加载MP3歌手图片出现Call to getEmbeddedPicture failed错误
问题现象
Android开发场景下,读取MP3歌曲文件内嵌的歌手封面图并加载显示时,部分MP3文件可正常加载图片,部分文件加载失败,Logcat抛出Call to getEmbeddedPicture failed错误。
原有实现代码如下:
public void metaData(Uri uri){ MediaMetadataRetriever retriever = new MediaMetadataRetriever(); retriever.setDataSource(uri.toString()); int durationTotal = Integer.parseInt(songsList.get(position).getDuration()) / 1000; tv_end.setText(formattime(durationTotal)); byte[] art = retriever.getEmbeddedPicture(); Bitmap bitmap = null; if(art != null){ Glide.with(this).asBitmap().load(art)..into(img_minSongImage); }else{ Glide.with(this).asBitmap().load(R.drawable.profile).into(img_minSongImage); } }
故障原因
setDataSource调用方式错误:直接传入uri.toString()仅支持本地文件绝对路径类型的Uri,对于Android分区存储下的Content Uri、媒体库Uri,这种调用方式不会自动授予文件访问权限,会导致MediaMetadataRetriever无法正常读取文件内容,调用读取内嵌图方法时直接报错。- 缺少异常捕获逻辑:部分MP3文件的ID3标签不标准、内嵌封面数据损坏、封面格式不被系统原生MediaMetadataRetriever支持(比如非常规编码的图片、存放在非标准ID3帧的封面),调用
getEmbeddedPicture()时会直接抛出异常,没有兜底逻辑就会加载失败。 - 代码存在语法错误:
Glide.with(this).asBitmap().load(art)..into(img_minSongImage);行存在连续两个点的书写错误,会触发编译或运行异常。 - 未释放MediaMetadataRetriever资源:长时间运行会引发资源泄漏,也可能导致偶发的读取失败问题。
修复方案
- 修正
setDataSource调用方式,针对Uri类型的数据源,使用带Context参数的重载方法,适配分区存储的权限要求。 - 给MediaMetadataRetriever的全流程操作增加try-catch-finally块,捕获所有解析异常,在finally中主动释放retriever资源避免泄漏。
- 修复Glide加载的语法书写错误。
- 所有解析失败、无内嵌图的场景统一兜底加载默认封面。
修正后的代码参考:
public void metaData(Uri uri){ MediaMetadataRetriever retriever = new MediaMetadataRetriever(); byte[] art = null; try { // 修正setDataSource调用,适配Content Uri场景 retriever.setDataSource(this, uri); int durationTotal = Integer.parseInt(songsList.get(position).getDuration()) / 1000; tv_end.setText(formattime(durationTotal)); // 读取内嵌封面 art = retriever.getEmbeddedPicture(); } catch (Exception e) { // 捕获所有解析异常,避免崩溃 e.printStackTrace(); } finally { // 必须释放native资源 retriever.release(); } // 加载图片,修复多余点的语法错误 if(art != null){ Glide.with(this).asBitmap().load(art).into(img_minSongImage); }else{ Glide.with(this).asBitmap().load(R.drawable.profile).into(img_minSongImage); } }
如果经过上述修改后仍有少量MP3无法读取内嵌图,是因为这部分文件的ID3标签格式不符合系统原生解析的标准,可以引入专门的音频标签解析库做二次兜底解析即可。
内容的提问来源于stack exchange,提问作者Techno World
相关产品推荐
相关产品推荐

