手动将歌曲添加到Mediastore作为音乐曲目

10

我希望创建一个音乐播放器,可以在线下载歌曲并将其添加到MediaStore。我正在使用下载管理器,并允许MediaScanner在下载完成时扫描此文件。

DownloadManager.Request request ....
request.allowScanningByMediaScanner();
...
downloadManager.enqueue(request);

在安卓5.0及以上版本中运行良好。
但是,歌曲是使用不支持Lollipop以下版本安卓系统的编解码器(opus)下载的,因此MediaScanner没有将该文件添加到MediaStore中。

这就是我的问题,我的应用程序可以播放opus编解码器,但是下载后,这首歌曲在MediaStore中不存在,因此我的应用程序找不到这首歌曲。

如何强制MediaScanner将下载的文件作为音乐轨道添加到MediaStore.Audio中。如果无法实现,则如何在下载完成后手动将此歌曲添加到MediaStore.Audio中:

public class BroadcastDownloadComplete extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.DOWNLOAD_COMPLETE")) {

            //addSongToMediaStore(intent);
        }
    }
}
2个回答

6

这里的源代码中,我们可以看到扫描程序的最终实现有两个步骤来扫描音频文件。如果其中任何一个步骤失败,则该音频文件将不会插入媒体提供程序。

步骤1 检查文件扩展名

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;
}

自 Android 5.0 以来,已经添加了更多的扩展。opus 编解码的通用容器是 ogg,在 Android 5.0 之前就已经存在了。假设您的音频文件扩展名是 ogg,则扫描过程在此步骤中正常。 第二步 检索元数据
在第一步通过后,扫描器需要检索媒体的元数据以备后续的数据库插入。我认为在此步骤中,扫描器进行编解码级别的检查。
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;
}

对于 Android 5.0 版本之前的设备,在此步骤可能会出现扫描器失败的问题。因为缺少内置的 Opus 编解码器支持,setDataSource 最终可能会失败。媒体文件最终不会被添加到媒体提供程序中。

建议解决方案

因为我们知道音频文件将被添加到

MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

我们可以手动进行数据库操作。如果您希望您的音频文件与数据库中的其他音频文件保持一致,您需要自己检索所有元数据。由于您可以播放opus文件,我认为检索元数据很容易。

// 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());

之后,您的应用程序可以找到音频文件。
getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI...

谢谢。这帮助我找出为什么我转码为opus的所有音频文件都没有出现在音乐应用程序中... - aross

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接