是否可以从 Android 中的远程 mp3 文件中检索专辑封面?
Posted
技术标签:
【中文标题】是否可以从 Android 中的远程 mp3 文件中检索专辑封面?【英文标题】:Is it possible to retrieve album art from remote mp3 file in Android? 【发布时间】:2013-08-01 07:32:45 【问题描述】:我目前正在编写一个 UPnP 远程控制应用程序,用于将远程 MediaServer 连接到远程 MediaRenderer。由于实际的 MP3 文件不会发送到 android 设备,我希望能够获得当前播放文件的专辑封面,而无需将整个 MP3 文件下载到我的手机。
我读到MediaMetadataRetriever
对这种事情很有用,但我无法让它发挥作用。每次尝试,我都会通过调用MediaMetadataRetriever#setDataSource
不断收到IllegalArgumentException
,这表明我的文件句柄或URI 无效。
MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
以下内容有效,因为它是设备本身的直接文件路径:
metaRetriever.setDataSource("/sdcard/Music/Daft_Punk/Homework/01 - Daftendirekt.mp3");
但是,以下任何操作都会失败并出现相同的错误:
metaRetriever.setDataSource(appCtx, Uri.parse("http://192.168.1.144:49153/content/media/object_id/94785/res_id/1/rct/aa"));
metaRetriever.setDataSource(appCtx, Uri.parse("http://192.168.1.144:49153/content/media/object_id/94785/res_id/0/ext/file.mp3"));
metaRetriever.setDataSource("http://192.168.1.144:49153/content/media/object_id/94785/res_id/0/ext/file.mp3");
第一个是从 UPnP 元数据中提取的专辑ArtURI(没有 *.mp3 扩展名,但如果粘贴到网络浏览器中,文件将会下载)。
第二次和第三次尝试使用 UPnP 元数据中的“res”值,它指向服务器上的实际文件。
我希望我只是错误地解析了 URI,但我没有想法。
有什么建议吗?另外,从 UPnP 服务器拉取数据时,有没有更好的方法来完全做到这一点? FWIW,我正在使用 Cling UPnP 库。
== 解决方案 ==
我开始研究 william-seemann 的答案,结果发现:MediaMetadataRetriever.setDataSource(String path) no longer accepts URLs
这篇文章的评论 #2 提到使用了不同版本的 setDataSource()
,它仍然接受远程 URL。
这是我最终做的,效果很好:
private Bitmap downloadBitmap(final String url)
final MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
metaRetriever.setDataSource(url, new HashMap<String, String>());
try
final byte[] art = metaRetriever.getEmbeddedPicture();
return BitmapFactory.decodeByteArray(art, 0, art.length);
catch (Exception e)
Logger.e(LOGTAG, "Couldn't create album art: " + e.getMessage());
return BitmapFactory.decodeResource(getResources(), R.drawable.album_art_missing);
【问题讨论】:
事实证明你必须为远程 URLS 传递 HashMap,我的标签返回 null 但至少它现在停止崩溃与非法状态异常。 【参考方案1】:FFmpegMediaMetadataRetriever 将从远程文件中提取元数据(披露:我创建了它)。我的界面与MediaMetadataRetriever 相同,但它使用FFmpeg 作为后端。这是一个例子:
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(mUri);
String album = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
String artist = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
byte [] artwork = mmr.getEmbeddedPicture();
mmr.release();
【讨论】:
感谢您指点我!我最终将 MediaMetadataRetriever 与不同版本的 setDataSource() 一起使用。请参阅上面的解决方案。 以上类不适用于亚马逊存储桶 url,总是给出 IllegalstateException 异常。【参考方案2】:查看MediaMetadataRetriever
的source code(不是来自官方Android 存储库,但它应该仍然相似,如果不是等效的话)向我展示了这一点:
if (uri == null)
throw new IllegalArgumentException();
还有这个:
ContentResolver resolver = context.getContentResolver();
try
fd = resolver.openAssetFileDescriptor(uri, "r");
catch(FileNotFoundException e)
throw new IllegalArgumentException();
if (fd == null)
throw new IllegalArgumentException();
FileDescriptor descriptor = fd.getFileDescriptor();
if (!descriptor.valid())
throw new IllegalArgumentException();
您的异常来自这些块之一。
通过查看MediaMetadataRetriever
文档和源代码,在我看来该文件必须在设备上。您可以使用Uri
,但我认为它必须类似于"file:///android_asset/mysound.mp3"
。不过我可能是错的;您确定MediaMetadataRetriever
可用于通过网络解析文件吗?
【讨论】:
不,我不确定它是否可以通过网络使用。我希望这是可能的,特别是因为可以使用 URI,但它可能仅适用于本地文件。如果 MediaMetadataRetreiever 不能用于远程文件,是否有另一种方法可以在不下载整个文件的情况下获取专辑封面? 您可以从外部网站(专辑封面“服务器”)下载专辑封面,但您需要有关歌曲的基本信息,例如标题、艺术家等。以上是关于是否可以从 Android 中的远程 mp3 文件中检索专辑封面?的主要内容,如果未能解决你的问题,请参考以下文章
使用 android.media.Rating 从 android 中的歌曲列表 (MP3) 中获取评分元数据
从 Android WebView 中的链接播放 MP4 或 MP3
ios - 从远程 URL 加载 MP3 并播放,冻结 UI