是否可以从Android中的远程mp3文件中检索专辑封面?

时间:2013-07-31 16:38:02

标签: android upnp

我正在编写一个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元数据中提取的albumArtURI(没有* .mp3扩展名,但如果粘贴到网络浏览器中,该文件将会下载)。

第二次和第三次尝试使用UPnP元数据中的“res”值,该值指向服务器上的实际文件。

我希望我只是错误地解析URI,但我没有想法。

有什么建议吗?另外,从UPnP服务器提取时,是否有更好的方法可以完成此操作? FWIW,我正在使用Cling UPnP库。

== SOLUTION ==

我开始研究william-seemann的答案,它引导我:MediaMetadataRetriever.setDataSource(String path) no longer accepts URLs

此帖子上的评论#2提到使用仍然接受远程网址的setDataSource()的不同版本。

这就是我最终做的事情,而且效果很好:

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);
     }
  }

2 个答案:

答案 0 :(得分:1)

FFmpegMediaMetadataRetriever将从远程文件中提取元数据(Disclosure:我创建了它)。我的界面与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();

答案 1 :(得分:0)

查看MediaMetadataRetriever if (uri == null) { throw new IllegalArgumentException(); } (不是官方的Android回购,但它应该仍然相似,如果不相同的话)告诉我这个:

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();
}

而且:

Uri

您的例外来自其中一个区块。

从查看source code文档和源代码,我觉得该文件必须在设备上。您可以使用"file:///android_asset/mysound.mp3",但我认为它必须类似于MediaMetadataRetriever。我可能错了;您确定可以使用{{1}}通过网络解析文件吗?