Android显示MP3专辑封面

Android显示MP3专辑封面

Android实现选择本地音乐》实现了将音乐插入到神马笔记中,创建了音乐笔记。

接下来实现音乐笔记的界面,首先要实现的便是现实音乐专辑封面。

一、目标

二、实现方案

获取专辑封面有2种实现方式。

  1. 音乐文件如MP3中内嵌的专辑图片
  2. 额外关联的专辑图片

因为有些音乐文件没有内嵌专辑图片,尝试通过音乐信息(艺术家、标题、专辑等)从网易云音乐虾米音乐获取专辑封面,结果以失败告终。

云音乐平台并没有开放相关的API供开发者调用,只能以破解的方式来调用,这也意味着不稳定。

因此最终放弃从云音乐平台获取专辑封面的想法。

从文件中获取内嵌图片作为专辑封面,如果没有内嵌图片则显示为默认图片。

三、获取内嵌图片

1
2
3
4
5
6
7
8
9
byte[] data;
{
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(parent.getContext(), this.getUri());

data = retriever.getEmbeddedPicture();

retriever.release();
}

四、遇到的一些问题

获取内嵌图片的实现代码非常简单,但显示图片时遇到了一些问题。

1. 读取文件影响加载速度

每次显示图片都重新读取文件将影响加载速度。

余枫的《荣耀(荣耀手机中文主题曲)》内嵌的图片大小为309.996字节,300K大小。

尝试添加了10次这首歌,直接影响了打开速度。

2. Glide刷新时出现闪烁

Glide加载byte[]字节数组图片,即使设置了diskCacheStrategy(DiskCacheStrategy.RESOURCE)skipMemoryCache(false)以启用缓存。

最终在notifyItemChanged()时依然出现闪烁问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* Returns a request to load the given byte array.
*
* <p>Note - by default loads for bytes are not cached in either the memory or the disk cache.
*
* @param model the data to load.
* @see #load(Object)
*/
@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable byte[] model) {
RequestBuilder<TranscodeType> result = loadGeneric(model);
if (!result.requestOptions.isDiskCacheStrategySet()) {
result = result.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}
if (!result.requestOptions.isSkipMemoryCacheSet()) {
result = result.apply(skipMemoryCacheOf(true /*skipMemoryCache*/));
}
return result;
}

五、最终实现

考虑直接读取byte[]数组和加载byte[]图片,会影响加载速度和导致图片闪烁。

因此增加一个中间步骤,先将byte[]数组保存为文件,再通过Glide加载图片文件。

完美解决加载速度慢(第一次依然会慢)和图片闪烁问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public File getEmbeddedPicture() {
File file = entity.getEmbeddedPicture();

if (!isEmbedded()) {
return file;
}

if (file.exists()) {
return file;
}

byte[] data;
{
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(parent.getContext(), this.getUri());

data = retriever.getEmbeddedPicture();

retriever.release();
}

if (data != null && data.length > 0) {
try {
FileUtils.writeByteArrayToFile(file, data);
} catch (IOException e) {
e.printStackTrace();
}
}

return file;
}

六、开发过程回顾

尝试着从网易云音乐虾米音乐等云音乐平台获取专辑封面图片,考虑到云音乐平台并未开放相关API,即使使用破解方式暂时实现,也会为未来埋下隐患,最终放弃。

读取内嵌封面图片回导致加载速度慢和闪烁2个问题,增加保存为文件的中间过程,最终完美实现加载封面图片。

七、接下来

调用第三方播放音乐。

八、Finally

如来灭后。后五百岁。 有持戒修福者。 于此章句。能生信心。 以此为实。当知是人。 不于一佛二佛三四五佛而种善根。 已于无量千万佛所。种诸善根。