【问题标题】:MediaMetadataRetriever returns null but fine with MediaStoreMediaMetadataRetriever 返回 null 但对 MediaStore 很好
【发布时间】:2014-02-11 15:21:35
【问题描述】:

我是开发安卓应用的新手。
我正在开发一个音乐播放器,想从音频文件的元数据中获取歌曲名称、艺术家、专辑名称、专辑封面。
我使用了MediaMetadataRetriever,但是当有 800 多首歌曲时速度很慢,并且对于某些文件返回 null,而其他音乐播放器可以检索这些信息。

然后我使用MediaStore.Audio.Media.EXTERNAL_CONTENT_URI 获取歌曲名称、艺术家、专辑名称和MediaStore.Audio.Albums.EXTERNAL_CONTENT_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";
    }

非常感谢!!!

【问题讨论】:

  • 感谢您的回复:) 我在使用 MediaStore 之前使用过 MediaMetadataRetriever,但它对某些文件返回 null,而其他音乐播放器可以正确检索这些信息。使用 MediaMetadataRetriever 的实现代码和你的一样。任何的想法?非常感谢!

标签: android metadata


【解决方案1】:

你知道吗 - 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 中的其他可用选项感兴趣。

【讨论】:

    【解决方案2】:

    原来 MediaMetadataRetriever 只处理 UTF-16 格式的 MP3 文件中的所有数据

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

    使用 MP3Tag。我确保选择了选项 ID3v2.3 UTF-16。

    Verify Saving as UTF-16

    然后选择我拥有的所有 ISO-8859-1 的 MP3 文件并保存(或重新保存)它们

    如果您不确定自己是否遇到此问题。您可以在 MP3 中创建一个 Column 标签来显示编码

    Create MP3 Tag Column

    See Files with wrong Encoding

    在将我所有具有 ISO-8859-1 的 MP3 重新保存为 UTF-16 之后,现在 MediaMetadataRetriever 永远不会返回 Null 并且总是返回正确的数据。

    BobVal

    【讨论】:

      猜你喜欢
      • 2015-06-11
      • 2013-07-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 2012-11-21
      相关资源
      最近更新 更多