当前位置: 首页 > 知识库问答 >
问题:

MediaMetadataRetriever返回null,但对MediaStore没有影响

姬温文
2023-03-14

我是开发android应用程序的新手
我正在开发一款音乐播放器,希望从音频文件的元数据中获取歌曲名称、艺术家、专辑名称、专辑艺术
我使用了MediaMetadataRetriever,但当有800首歌曲时,速度会很慢,有些文件返回null,而其他音乐播放器可以检索这些信息。

然后我使用MediaStore。音频媒体外部内容URI获取歌曲名称、艺术家、专辑名称和媒体商店。音频专辑。外部内容_URI获取专辑艺术。

是否有任何uri可同时获取(歌曲名称、艺术家、专辑名称、专辑艺术)
因为我需要在程序中创建歌曲对象。

下面是我的代码,但它非常慢,因为它要求为每首歌提供专辑艺术。

    public ArrayList<Songs> getPlayList(Context c) {

    String[] TRACK_PROJ = {
            MediaStore.Audio.AudioColumns.ARTIST,
            MediaStore.MediaColumns.TITLE,
            MediaStore.Audio.AudioColumns.ALBUM,
            MediaStore.Audio.AudioColumns.YEAR,
            MediaStore.MediaColumns.DATA
    };
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor cursor = c.getContentResolver().query(uri, TRACK_PROJ, null, null, null);

    int count;

    if (cursor != null) {
        count = cursor.getCount();
        if (count > 0) {
            cursor.moveToFirst();
            do {
                Songs song;
                String artist = cursor.getString(cursor.getColumnIndex(TRACK_PROJ[0]));
                String title = cursor.getString(cursor.getColumnIndex(TRACK_PROJ[1]));
                String album = cursor.getString(cursor.getColumnIndex(TRACK_PROJ[2]));
                String year = cursor.getString(cursor.getColumnIndex(TRACK_PROJ[3]));
                String path = cursor.getString(cursor.getColumnIndex(TRACK_PROJ[4]));
                if (path.toLowerCase().contains(MEDIA_PATH.toLowerCase())) {
                    song = new Songs(artist, title, album, year, path);
                    songsList.add(song);
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
    }

    for (Songs aSongsList : songsList) {

        String[] ALBUM_PROJ = {MediaStore.Audio.Albums.ALBUM_ART};
        String selection = MediaStore.Audio.Albums.ALBUM + "=?";
        String[] values = new String[]{aSongsList.getAlbum()};
        Cursor cur = c.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, ALBUM_PROJ, selection, values, null);
        int cnt;
        if (cur != null) {
            cnt = cur.getCount();
            if (cnt > 0) {
                cur.moveToFirst();
                do {
                    String art = cur.getString(cur.getColumnIndex(ALBUM_PROJ[0]));
                    if (art != null)
                        aSongsList.setAlbumArt(art);
                } while (cur.moveToNext());
                cur.close();
            }
        }
    }

    return songsList;
}

编辑:(使用MediaMetadataRetriever的代码)

    private Songs getMetadata (File file){
    String artist, title, album, path;
    MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
    metaRetriever.setDataSource(file.getPath());

    try {

        artist = metaRetriever
                .extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);

        album = metaRetriever
                .extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);

        path = file.getPath();

        title = metaRetriever
                .extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);

    } catch (Exception e) {
        artist = "Unknown";
        title = "Unknown";
        album = "Unknown";
        path = "Unknown";
    }

谢谢!!!

共有2个答案

阎知
2023-03-14

事实证明,MediaMetadataRetriever只处理一个MP3文件(UTF-16)中的所有数据

我的一些MP3(真的很多)很旧,出于某种原因制造出来的时候是ISO-8859-1

使用MP3Tag。我确定了ID3v2选项。选择了3个UTF-16。

验证保存为UTF-16

然后选择所有的MP3文件,我有是ISO-8859-1和保存(或重新保存)他们

如果你不确定自己是否有这个问题。您可以在MP3中创建列标记以显示编码

创建MP3标签

查看错误编码的文件

在将所有ISO-8859-1作为UTF-16重新保存后,现在MediaMetadataRetriever从不返回空值,而是始终返回正确的数据。

博瓦尔

索令
2023-03-14

你知道这个http://developer.android.com/reference/android/media/MediaMetadataRetriever.html

MediaMetadataRetriever metaRetriver;
metaRetriver = new MediaMetadataRetriever();
metaRetriver.setDataSource("/sdcard/audio.mp3");

try {
        byte [] art = metaRetriver.getEmbeddedPicture();
        Bitmap songImage = BitmapFactory
            .decodeByteArray(art, 0, art.length);
        metaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
        String artist = metaRetriver
                .extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
        String genre = metaRetriver
                .extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE));
    } catch (Exception e) {
         // TO-DO Exception
    }

您可能对上述API中的其他可用选项感兴趣。

 类似资料:
  • 加载样式表,并在用户单击按钮时将其应用于场景 调用getScene()返回null。 函数所在的类是场景的控制器和根节点,我使用SceneBuilder 2.0,并将类设置为加载fxml的控制器,它是一个。 问题代码是类中的一个成员函数,标记是这样的,我可以通过设置按钮来调用它。 完整的代码可以在https://github.com/SebastianTroy/FactorioManufactur

  • 问题内容: 以下代码似乎不起作用,即使该文件看起来很好也是如此。 在此先感谢您的帮助。 编辑:结果是我试图去Graphics.drawImage(images [0]);,它给了我一个空指针异常。这段代码可以很好地完成。 编辑:更改按建议移动if(!file.exists()),并将文件包装在输入流中。 问题答案: ImageIO.read(file); 如果找不到注册的 ImageReader,

  • 正在尝试检索mp3信息(唱片名,…)使用MediaMetadataRetriever。在模拟器中,它运行良好。在我的设备上,大多数方法都返回null。 MediaMetadataRetriever mmr=新的MediaMetadataRetriever();嗯。setDataSource(songPath); 字符串albumName=mmr。extractMetadata(MediaMetad

  • 我花了几个小时来查找为什么我的代码没有从这个结构X:/中检索到文件“firstname”的原因 当我在debug中时,我可以看到Firebase检索与“firstname”相同级别的所有其他字段,但最后一个字段始终为null,即使它中有有效数据。 这是我创建FireStoreRecyclerOptions的行: 这是我的QueryFireStore: 而X类是一个POJO,包含以下数据结构:

  • 我有两个活动和两个布局。当我在第一个活动中显示列表时,一切都正常,并在单击时给出列表中项目的编号,但当我尝试在第二个活动中重复相同的内容时,它会告诉我RecycleServiceClickListener侦听器为空。 适配器: 第一项活动: 第二项活动: 错误: 我不明白为什么在第一种情况下,它正常处理单击,而在第二种情况下,它说RecyclerViewClickListener为null

  • 我有下面的代码,当我打印树形图时,我可以清楚地看到键和值对。每个键都有一个值(输出中没有空值)。当我得到第一个键时,它会给我一个键,但当我试图基于该键获取值时,它会返回null。 以下是输出的一部分: 所以我应该得到article04_C9,article08_C12firstKey()(我这样做),但是当我检索与该键关联的值时,它返回null。 下面是我用来填充树映射的代码 这是我用来按值排序的