2013-07-31 11 views
6

Attualmente sto scrivendo un'app di controllo remoto UPnP che viene utilizzata per connettere un MediaServer remoto a un MediaRenderer remoto. Poiché i file MP3 non vengono inviati al dispositivo Android, mi piacerebbe poter ottenere la copertina dell'album del file attualmente in riproduzione senza dover scaricare l'intero file MP3 sul mio telefono.È possibile recuperare la copertina dell'album dal file mp3 remoto in Android?

Ho letto che MediaMetadataRetriever è utile per questo genere di cose, ma non sono riuscito a farlo funzionare. Ogni modo in cui lo provo, continuo a ricevere IllegalArgumentException tramite la chiamata a MediaMetadataRetriever#setDataSource, che indica che il mio file handle o URI non è valido.

MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever(); 

Le seguenti opere dal momento che è un percorso di file direttamente sul dispositivo stesso:

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

Tuttavia, una delle seguenti falliscono con lo stesso errore:

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

Il primo è l'albumArtURI estratto dai metadati UPnP (nessuna estensione * .mp3, ma il file verrà scaricato se incollato in un browser Web).

Il secondo e il terzo tentativo utilizzano il valore "res" dai metadati UPnP, che indicano il file effettivo sul server.

Spero di analizzare l'URI in modo non corretto, ma sono fuori dalle idee.

Qualche suggerimento? Inoltre, c'è un modo migliore per farlo interamente quando si estrae da un server UPnP? FWIW, sto usando la libreria UPnP di Cling.

== == SOLUZIONE

ho iniziato a guardare in risposta di William-Seemann e mi ha portato a questo: MediaMetadataRetriever.setDataSource(String path) no longer accepts URLs

commento # 2 su questo post menzioni utilizzando una versione diversa di setDataSource() che accetta ancora lontana URL.

Ecco quello che ho finito per fare e che sta funzionando grande:

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

Si scopre devi passare la HashMap per gli URL remoti, i miei tag restituito nulla ma almeno è fermato schiantarsi con IllegalStateException ora. – kabuto178

risposta

0

Guardando il source code per MediaMetadataRetriever (non dal repo ufficiale di Android, ma dovrebbe comunque essere simili, se non equivalente) ha mostrato me questo :

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

E questo:

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

L'eccezione proviene da uno di questi blocchi.

Dall'esame della documentazione MediaMetadataRetriever e del codice sorgente, mi sembra che il file debba trovarsi sul dispositivo. È possibile utilizzare un Uri, ma penso che deve essere qualcosa come "file:///android_asset/mysound.mp3". Potrei sbagliarmi però; sei sicuro che MediaMetadataRetriever possa essere usato per risolvere file su una rete?

+0

No, non sono sicuro che possa essere usato sulla rete. Speravo che fosse possibile, soprattutto dal momento che un URI può essere usato, ma forse era pensato solo per i file locali. Se MediaMetadataRetreiever non può essere utilizzato per i file remoti, c'è un altro modo per ottenere la copertina dell'album senza scaricare l'intero file? – agelter

+0

È possibile scaricare la copertina dell'album da un sito Web esterno (album "server"), ma è necessario disporre di informazioni di base sul titolo, artista, ecc. – crocboy

1

FFmpegMediaMetadataRetriever estrae i metadati da un file remoto (Disclosure: l'ho creato). Ho la stessa interfaccia di MediaMetadataRetriever ma usa FFmpeg come backend.Ecco un esempio:

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

Grazie per avermi segnalato! Ho finito per utilizzare _MediaMetadataRetriever_ con una versione diversa di _setDataSource() _. Vedi la mia soluzione sopra. – agelter

+0

Sopra la classe non funziona con l'URL di Amazon, fornendo sempre Exception of IllegalstateException. –