2013-07-31 7 views
6

Ich schreibe gerade eine UPnP-Fernsteuerungs-App, mit der ein entfernter MediaServer mit einem entfernten MediaRenderer verbunden wird. Da die eigentlichen MP3-Dateien nicht an das Android-Gerät gesendet werden, möchte ich das Albumcover der aktuell abgespielten Datei abrufen können, ohne die gesamte MP3-Datei auf mein Telefon herunterladen zu müssen.Ist es möglich, Albumcover von einer Remote-MP3-Datei in Android abzurufen?

Ich habe gelesen, dass MediaMetadataRetriever ist nützlich für diese Art von Sache, aber ich habe es nicht geschafft zu arbeiten. Bei jeder Art, wie ich es versuche, erhalte ich durch den Aufruf an MediaMetadataRetriever#setDataSource eine IllegalArgumentException, die angibt, dass meine Dateikennung oder URI ungültig ist.

MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever(); 

folgende Arbeiten, da es auf dem Gerät ein direkter Dateipfad ist selbst:

metaRetriever.setDataSource("/sdcard/Music/Daft_Punk/Homework/01 - Daftendirekt.mp3"); 

jedoch eine des folgenden Aktionen mit dem gleichen Fehler fehlschlagen:

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

Die erste ist das AlbumArtURI aus den UPnP-Metadaten (keine * .mp3-Erweiterung, aber die Datei wird heruntergeladen, wenn in einen Webbrowser eingefügt).

Der zweite und dritte Versuch verwenden den Wert "res" aus den UPnP-Metadaten, der auf die tatsächliche Datei auf dem Server verweist.

Ich hoffe, dass ich nur die URI falsch analysieren, aber ich habe keine Ideen mehr.

Irgendwelche Vorschläge? Gibt es auch einen besseren Weg, dies vollständig zu tun, wenn Sie von einem UPnP-Server ziehen? FWIW, ich benutze die Cling UPnP-Bibliothek.

== Lösung ==

Ich begann Antwort William-seemann sucht in und führte mich dazu: MediaMetadataRetriever.setDataSource(String path) no longer accepts URLs

Kommentar # 2 zu diesem Beitrag erwähnt eine andere Version von setDataSource() verwenden, die noch in weiter Ferne akzeptiert URLs.

Hier ist, was ich tun endete und es funktioniert super:

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

Es stellt sich heraus Sie die HashMap für Remote-URLS passieren müssen, meine Tags zurückgegeben null, aber zumindest hörte es mit Illegal Absturz jetzt. – kabuto178

Antwort

0

am source code die Suche nach MediaMetadataRetriever (nicht aus der offiziellen Android-Repo, aber es sollte noch ähnlich, wenn nicht gleichwertig) zeigte mir diese :

if (uri == null) { 
    throw new IllegalArgumentException(); 
} 

Und:

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

Ihre Ausnahme kommt von einem dieser Blöcke.

Aus dem Blick auf die MediaMetadataRetriever Dokumentation und den Quellcode scheint es mir, dass die Datei auf dem Gerät sein muss. Sie können eine Uri verwenden, aber ich denke, es muss etwas wie "file:///android_asset/mysound.mp3" sein. Ich könnte mich allerdings irren. Sind Sie sicher, dass MediaMetadataRetriever zum Auflösen von Dateien über ein Netzwerk verwendet werden kann?

+0

Nein, ich bin mir nicht sicher, ob es über das Netzwerk verwendet werden kann. Ich hatte gehofft, dass es möglich ist, besonders da ein URI verwendet werden kann, aber vielleicht war es nur für lokale Dateien gedacht. Wenn MediaMetadataRetriever nicht für Remote-Dateien verwendet werden kann, gibt es eine andere Möglichkeit, das Albumcover zu erhalten, ohne die gesamte Datei herunterzuladen? – agelter

+0

Sie könnten das Album Art von einer externen Website (Album Art "Server") herunterladen, aber Sie würden grundlegende Informationen über das Lied wie Titel, Künstler usw. benötigen. – crocboy

1

FFmpegMediaMetadataRetriever werden Metadaten aus einer Remote-Datei extrahieren (Disclosure: Ich habe es erstellt). Ich habe die gleiche Schnittstelle wie MediaMetadataRetriever, aber es verwendet FFmpeg als Backend.Hier ein Beispiel:

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(); 
+0

Vielen Dank für mich darauf hingewiesen! Am Ende habe ich _MediaMetadataRetriever_ mit einer anderen Version von _setDataSource() _ verwendet. Siehe meine obige Lösung. – agelter

+0

Die obige Klasse funktioniert nicht mit der Amazon-Bucket-URL, die immer Exception of IllegalstateException enthält. –

Verwandte Themen