手动将歌曲作为音乐曲目添加到Mediastore [英] Manual add song to Mediastore as a music track

查看:539
本文介绍了手动将歌曲作为音乐曲目添加到Mediastore的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create a Music player which can download a song online and add it to MediaStore. I'm using Download Manager and allow MediaScanner scan this file when download completed.

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

在android 5.0及更高版本中工作正常。

但是歌曲已下载使用编解码器( opus ),此版本在棒棒糖版本以下的android中不受支持,因此MediaScanner不会将此文件添加到MediaStore。

It's work fine in android 5.0 and above.
But the song was downloaded using codec (opus) which not supported in android below lollipop version, so MediaScanner doesn't add this file to MediaStore.

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

That's my problem, my app can play opus codec but the song didn't exist in MediaStore after it has downloaded, so my app can't find this song.

如何强制MediaScanner将下载的文件作为音乐曲目添加到MediaStore.Audio。如果不能,如何在下载完成后手动将这首歌曲添加到MediaStore.Audio:

How to force MediaScanner add downloaded file to MediaStore.Audio as a Music track. If can not, how can I manual add this song to MediaStore.Audio after download completed:

public class BroadcastDownloadComplete extends BroadcastReceiver {

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

            //addSongToMediaStore(intent);
        }
    }
}


推荐答案

从源代码此处,我们可以看到扫描仪的最终实现有两个步骤来扫描音频文件。如果这两个步骤中的任何一个失败,则音频文件都不会插入媒体提供商。

From the source code here, we can see the final implementation of the scanner has two steps to scan an audio file. If either of these two step fail, the audio file will not insert into media provider.

步骤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 ,则此步骤的扫描过程很好。

More extensions have been added since Android 5.0. The common container for opus codec is ogg, this extension exists before Android 5.0. Assume your audio file extension is ogg, the scanning process is fine at this step.

step2 检索元数据

通过第一步后,扫描程序需要检索媒体的元数据,以便以后插入数据库。我认为扫描仪会在这一步进行编解码器级别检查。

After the first step passed, the scanner need to retrieve media's metadata for later database insertion. I think the scanner do the codec level checking at this step.

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

对于5.0之前的Android版本,扫描程序可能会在此步骤失败。由于缺少内置的opus编解码器支持, setDataSource 最终将失败。媒体文件最终将不会添加到媒体提供商。

For Android version before 5.0, the scanner might be failed at this step. Because of lacking of built-in opus codec support, setDataSource will get failed at last. The media file won't be added to media provider finally.

建议的解决方案

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

Because we know the audio file will be added to

MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

我们可以手动执行数据库操作。如果要使音频文件与数据库中的其他音频文件保持一致,则必须自己检索所有元数据。由于您可以播放作品文件,因此我认为检索元数据很容易。

we can do database operation manually. If you want your audio file keeps consistent with other audio files in the database, you have to retrieve all the metadata by yourself. Since you can play the opus file, I think it's easy to retrieve the metadata.

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

之后,您的应用程序可以找到音频文件。

After that, you app can find the audio file.

getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI...

这篇关于手动将歌曲作为音乐曲目添加到Mediastore的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆