【问题标题】:Getting individual image of mp3 file is too slow获取 mp3 文件的单个图像太慢
【发布时间】:2019-03-18 15:57:41
【问题描述】:

我正在尝试在手机上获取 mp3 文件的图像。我已经挣扎了几天,现在我知道了;

  • 首先,我使用带有此代码的内容提供程序

        `       Uri allSongsUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
                String[] projection = {
                        MediaStore.Audio.Media.TITLE,
                        MediaStore.Audio.Media.ARTIST,
                        MediaStore.Audio.Media.DATA,
                        MediaStore.Audio.Media.DISPLAY_NAME,
                        MediaStore.Audio.Media.DURATION,
                        MediaStore.Audio.Media.ALBUM,
                        MediaStore.Audio.Media.ALBUM_ID,
                        MediaStore.Audio.Media.ALBUM_KEY,
                        MediaStore.Audio.Media.DATE_MODIFIED
                };
                String sortOrder = MediaStore.Video.Media.DATE_MODIFIED + " DESC";
    

    我像这样创建我的光标;

    Cursor cursor = ctx.getContentResolver().query(allSongsUri, projection, null, null, sortOrder);

那里有我所有的 mp3 文件。没关系。现在我想得到他们的封面图片。

  • 如果我像这样使用 MediaMetadataRetriver 的 getEmbeddedPicture 方法

    mediaMetadataRetriever.setDataSource(localeMusic.getPath()); 
    localeMusic.setImage(mediaMetadataRetriever.getEmbeddedPicture());
    

    将近 40-50 个文件大约需要 6-7 秒。因为 getEmbeddedPicture() 太慢了!

  • 还尝试获取专辑 ID 并查询另一个光标到 MediaStore.Audio.Albums,我看到所有专辑 ID 都是相同的,因为它们都是同一个文件夹。我不想显示他们的专辑图片。我想显示文件的封面图片。 我像here 一样尝试过,但是在那里,我们正在获取文件的专辑图像。那不是我问的。

在哪里可以找到文件的图像路径? MetadataRetriever 类在哪里可以使用 getEmbeddedPicture 获取它?嵌入的图片在哪里?

谢谢。最好的问候

【问题讨论】:

  • 我的问题是什么问题,为什么要减分?

标签: android performance file android-contentresolver mediametadataretriever


【解决方案1】:

mediaMetadataRetriever.getEmbeddedPicture() 是一个本地方法,每个本地方法调用都有代价,因为 JNI 调用需要时间。所以,如果你重复这样的调用,你可能会浪费很多时间。您可以尝试按需异步调用此方法并缓存结果。尝试结合glide 这将同时解决您的两个问题,glide 调用自然是 asnyc,因此您不需要实现 AsyncTask 类,它也会缓存您的图像。

这是滑翔的基本用法:

Glide.with(context).load(mediaMetadataRetriever.getEmbeddedPicture());

我鼓励您阅读 glide documents。它还有很多其他功能。

希望这会有所帮助。

【讨论】:

  • 感谢思南的帮助。我尝试了你的建议,但现在我有相同的图像。我认为我们必须使用第一个光标的某个字段并使用第二个专辑艺术光标。因为第二个光标不知道要获得哪些歌曲专辑?我尝试使用专辑 ID,但没有奏效,因为位于同一文件夹的歌曲具有相同的图像
  • 亲爱的思南,我认为您正在迭代专辑光标。但我不想要专辑。我需要获取文件的个人封面。
  • @TayfunCesur 我明白了。你使用 AsyncTask 吗?
  • 是的。但是 AsyncTask 在这种情况下没有帮助。因为这个过程需要太多时间。
  • mediaMetadataRetriever.getEmbeddedPicture() 是本机方法,每个本机方法调用都有代价,因为 JNI 调用需要时间。你可以尝试将你的异步进程与 glide 结合起来。 github.com/bumptech/glide
【解决方案2】:

你可以得到这里提到的专辑封面

https://stackoverflow.com/a/17574629/3825975

基本上,

Cursor cursor = getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, 
                new String[] {MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART}, 
                MediaStore.Audio.Albums._ID+ "=?", 
                new String[] {String.valueOf(albumId)}, 
                null);

if (cursor.moveToFirst()) {
    String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
    // do whatever you need to do
}

但要获得个人歌曲艺术,这就是我记得的做法。希望对您有所帮助。

float ht_px = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
        float wt_px = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());

        Bitmap artwork, bitmap2 = null;

        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        byte[] rawArt;
        BitmapFactory.Options bfo = new BitmapFactory.Options();

        try {
            mmr.setDataSource(songUri);  //songUri is the uri of the song. You need to extract this from the song id
            rawArt = mmr.getEmbeddedPicture();
            if (rawArt != null)
                bitmap2 = BitmapFactory.decodeByteArray(rawArt, 0, rawArt.length, bfo);
            if (bitmap2 == null)
                bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.def_icon);
            artwork = Bitmap.createScaledBitmap(bitmap2, (int) ht_px, (int) wt_px, true);   //This is the bitmap you need
        } catch (Exception e) {
            //Exception handling
        }
    }

【讨论】:

  • 感谢您的建议。我需要获得个人歌曲艺术,并且我已经尝试过 MediaMetadataRetriever。我在上面的问题中说过。这太慢了
  • 真的吗?您可能一直在获取更大的图像。请参阅我已限制高度和宽度。我创建了一个音乐播放器,效果很好。我相信这应该适用于您的情况。
  • 事情是 mmr.getEmbeddedPicture() 并解码这个 byre 数组。在此之后,缩放没有问题
  • @TayfunCesur 好的,我明白了。如果我没记错的话,这个过程可能就像你说的那样漫长。您需要第一次在后台服务中加载图像,然后将它们缓存起来,这样您就不需要再次加载它们。所以你只需要这样做一次。之后,您可以重复使用它们。第一次你可以在启动画面中进行,或者向用户展示一些加载器等。
  • 听起来不错。我不明白android os怎么做得太快了。现在我认为他们是这样做的 :D 谢谢。我试试这个
猜你喜欢
  • 1970-01-01
  • 2021-11-10
  • 2013-11-02
  • 2021-03-21
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多