Aus dem Quellcode here können wir sehen, die endgültige Implementierung des Scanners hat zwei Schritte zum Scannen einer Audiodatei. Wenn einer dieser beiden Schritte fehlschlägt, wird die Audiodatei nicht in den Medienanbieter eingefügt.
Schritt 1 Überprüfung der Dateierweiterung
static bool FileHasAcceptableExtension(const char *extension) {
static const char *kValidExtensions[] = {
".mp3", ".mp4", ".m4a", ".3gp", ".3gpp", ".3g2", ".3gpp2",
".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
".avi", ".mpeg", ".mpg"
};
static const size_t kNumValidExtensions =
sizeof(kValidExtensions)/sizeof(kValidExtensions[0]);
for (size_t i = 0; i < kNumValidExtensions; ++i) {
if (!strcasecmp(extension, kValidExtensions[i])) {
return true;
}
}
return false;
}
Weitere Erweiterungen sind seit Android 5.0 hinzugefügt. Der gemeinsame Container für Opus Codec ist ogg
, diese Erweiterung existiert vor Android 5.0. Angenommen, Ihre Audiodateierweiterung ist ogg
, der Scanvorgang ist in diesem Schritt in Ordnung.
schritt2 Metadaten
Nach dem ersten Schritt abgerufen werden weitergegeben, müssen die Scanner Medien Metadaten für eine spätere Datenbank Einfügen abzurufen. Ich denke, dass der Scanner die Codec-Stufe bei diesem Schritt überprüft.
sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever);
int fd = open(path, O_RDONLY | O_LARGEFILE);
status_t status;
if (fd < 0) {
// couldn't open it locally, maybe the media server can?
status = mRetriever->setDataSource(path);
} else {
status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL);
close(fd);
}
if (status) {
return MEDIA_SCAN_RESULT_ERROR;
}
Für Android-Version vor 5.0 ist der Scanner möglicherweise bei diesem Schritt fehlgeschlagen. Aufgrund der fehlenden integrierten Opus-Codec-Unterstützung wird setDataSource
schließlich fehlgeschlagen. Die Mediendatei wird nicht endgültig zum Medienanbieter hinzugefügt.
vorgeschlagene Lösung
Weil wir die Audiodatei wissen
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
zu
hinzugefügt werden wir manuell Datenbank Betrieb tun können. Wenn Sie möchten, dass Ihre Audiodatei mit anderen Audiodateien in der Datenbank konsistent bleibt, müssen Sie alle Metadaten selbst abrufen. Da Sie die Opus-Datei abspielen können, ist es einfach, die Metadaten abzurufen.
// retrieve more metadata, duration etc.
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Audio.AudioColumns.DATA, "/mnt/sdcard/Music/example.opus");
contentValues.put(MediaStore.Audio.AudioColumns.TITLE, "Example track");
contentValues.put(MediaStore.Audio.AudioColumns.DISPLAY_NAME, "example");
// more columns should be filled from here
Uri uri = getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentValues);
Log.d(TAG, uri.toString());
Danach können Sie die Audiodatei finden.
getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI...
Danke. Das hat mir geholfen, herauszufinden, warum in der Welt alle meine Audiodateien, die ich in Opus transcodierte, nicht in der Musik-App erschienen sind ... – aross