我目前正在编写一个 UPnP 远程控制应用程序,用于将远程 MediaServer 连接到远程 MediaRenderer。由于实际的 MP3 文件不会发送到 Android 设备,我希望能够获得当前播放文件的专辑封面,而无需将整个 MP3 文件下载到我的手机上。
我读过这MediaMetadataRetriever
对这种事情很有用,但我无法让它发挥作用。我尝试的每一种方式,我都会IllegalArgumentException
通过调用 来得到一个MediaMetadataRetriever#setDataSource
,这表明我的文件句柄或 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 扩展名,但如果粘贴到 Web 浏览器中,文件将下载)。
第二次和第三次尝试使用 UPnP 元数据中的“res”值,它指向服务器上的实际文件。
我希望我只是错误地解析了 URI,但我没有想法。
有什么建议么?另外,从 UPnP 服务器拉取数据时,有没有更好的方法来完全做到这一点?FWIW,我正在使用 Cling UPnP 库。
== 解决方案 ==
我开始研究 william-seemann 的答案,这让我想到了这个:MediaMetadataRetriever.setDataSource(String path) 不再接受 URL
这篇文章的评论 #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);
}
}