2012-07-27 7 views
6

Sto riproducendo un file audio utilizzando il BasicPlayer(basato su Javasound). Il file è in una condivisione Samba e sto usando Jcifs per accedervi. Mi dà un InputStream.Modo efficiente per cercare uno streaming audio su rete con InputStream

NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(...); 

SmbFile f = new SmbFile(...); 
SmbFileInputStream audioIn = new SmbFileInputStream(f); 

int bufSize = 8096;//should I use f.length() here? 
audioBIS = new BufferedInputStream(audioIn, bufSize); 

audioBIS.mark(f.length()); 

    //call BasicPlayer 
play(audioBIS); 

ho bisogno di essere in grado di posizionare il puntatore ovunque nel file, proprio come qualsiasi giocatore comune. L'unica soluzione che potevo pensare era usare uno BufferedInputStream e una combinazione di mark/reset/skip ogni volta che ho bisogno di riposizionare il puntatore. Non appena apro il file e ottengo il flusso, chiamo il metodo mark(), in modo che un successivo reset() mi riposizionerà all'inizio. Quindi con skip() posso andare dove voglio.

audioBIS.reset(); 
audioBIS.skip(newBytePosition); 

Il mio problema è che la chiamata salto() funziona solo se lo desideri se a specificare un buffer abbastanza grande da contenere l'intero file.

Esiste un modo più efficiente per farlo?

risposta

2

Sono stato giù per il percorso identico come ora. Il caso era che avevamo un server (e una condivisione SMB) contenente migliaia di file audio. Questi file dovevano essere riproducibili in un'applicazione.

Ho iniziato con jCifs e ho modificato la sorgente di BasicPlayer per gestire SmbFile nello stesso modo in cui avrebbe trattato File. Ha funzionato bene, ma quando si tratta di cercare/saltare non ti fa davvero saltare in aria. Finché hai una buona connessione con il server, dovresti stare bene.

Alla fine ho abbandonato la soluzione, e invece ho installato tomcat6 sul server e distribuito un servlet piccolo e semplice che consentiva di effettuare richieste per un file in una determinata posizione. La macchina client prenderà quindi la risposta come InputStream e la passerà a BasicPlayer. Funziona molto meglio e la riproduzione è istantanea. Il codice è un po 'più di ciò che è ragionevole incolla qui, ma sarei disposto a condividerlo con te se sei interessato.

+0

La tua soluzione sembra molto interessante, ma non ho abbastanza spazio sul lato server per installare tomcat. Ad ogni modo, potrei pensare a un wrapper di BasicPlayer che fa più o meno la stessa cosa, avendo cura delle funzioni seek e getTime. Solo una domanda. Come si genera un Inputstream in base a un determinato offset? La risposta fornita [qui] (http://stackoverflow.com/questions/5923817/how-to-clone-an-inputstream) è stimolante e implica anche il caching, ma sono preoccupato per l'overhead che vorrei introdurre facendo copie di enormi matrici. – Giuseppe

+0

Quando si dice InputStream basato su un dato offset, si sta ancora parlando di jCifs (SmbFile) e offset in byte? – sbrattla

+0

Mi riferivo alla parte in cui dici "La macchina client prenderà la risposta come InputStream".Non intendi dire che il server risponde con un inputstream che inizia nella posizione desiderata? – Giuseppe

0

In alternativa. Puoi sempre chiudere lo stream e ricrearlo. Sembra andare veloce e sei tornato alla posizione 0 se necessario.

Quindi tieni traccia di dove sei. Finché vai avanti, mantieni il flusso e salta con skip(). Una volta che hai bisogno di tornare indietro, chiudi quel flusso e crea un nuovo e salta() nella posizione desiderata.

A meno che l'applicazione non sia pesante sul backskipping tutto il tempo dovrebbe essere ok.

Avvolgetelo in un nuovo flusso personalizzato e avete un flusso che supporta andare avanti e indietro.

Problemi correlati