2011-09-14 28 views
14

Stiamo usando MediaRecorder per registrare video in un file sul archiviazione esterna utilizzando setOutputFile() prima di fare la registrazione vera e propria.Come sapere quando MediaRecorder ha terminato la scrittura dei dati su file

Tutto funziona bene, ma il problema principale è che non appena la registrazione è fatto, vogliamo avviare la riproduzione del video registrato di nuovo in un VideoView.

Come sapere quando il file è pronto per essere letto e riprodotto?

risposta

18

La classe FileObserver si adatta alle vostre esigenze perfettamente. Here is the documentation. È facile da usare. Quando un file osservato viene chiuso dopo la scrittura, il callback onEvent viene chiamato con il parametro CLOSE_WRITE.

MyFileObserver fb = new MyFileObserver(mediaFile_path, FileObserver.CLOSE_WRITE); 
fb.startWatching(); 

class MyFileObserver extends FileObserver { 

    public MyFileObserver (String path, int mask) { 
     super(path, mask); 
    } 

    public void onEvent(int event, String path) { 
     // start playing 
    } 
} 

Non dimenticare di chiamare stopWatching() ..

+0

Io non sono in grado di testare questo proprio ora, ma fai a sapere se è garantito che il MediaRecorder non chiude il file tra le scritture? –

+0

Non ne sono al corrente. Ma anche se lo fosse, è possibile mantenere lo stato di registrazione in un membro e controllarlo in "onEvent". Se la registrazione è in pausa, ignora l'evento. – Ronnie

+0

Vero. Penso che questa sia la soluzione migliore, grazie! –

0

Apparentemente non è possibile rilevare quando la registrazione si è interrotta nel lettore multimediale, ma è presente un arresto() che è possibile ignorare se si crea una classe personalizzata che implementa MediaRecorder. qui vorrei fare qualcosa di simile:

public class MyRecorder implements MediaRecorder { 
    public boolean stopped; 

    .... implement all the methods that MediaRecorder has making 
     sure to call super for each method. 

    @Override 
    public void myStop() { 
     this.stopped = true; 
     super.stop(); 
    } 
} 

Quindi è possibile accedere al booleano per vedere se ha interrotto la registrazione.

+1

Ma quando la registrazione viene interrotta, maggiore quantità di dati deve ottenere per iscritto al deposito e non siamo in grado di avviare la riproduzione del video fino a quando la registrazione in realtà ha ottenuto scritta allo stoccaggio. –

+0

Cosa deve essere scritto? Se è personalizzato ciò che stai scrivendo, chiama la tua funzione personalizzata dall'interno del metodo di interruzione forzata, quindi imposta la variabile arrestata dopo la chiamata. – JPM

+2

Lo so quando abbiamo _stop_ la registrazione. Quando la registrazione viene interrotta, il registratore scrive i dati su disco e voglio sapere quando ha finito di scrivere i dati :) –

0

Un modo sporco sarebbe controllare il valore lastModified() del file e aprire la visualizzazione video se il file non è stato modificato per 2 secondi.

+0

Abbiamo già hack in atto, ma preferirei una soluzione adeguata se ce n'è uno. Se non ce n'è, beh, allora continueremo a usare il nostro trucco e aggiungere qualche errore di salvaguardia ad esso :) –

5

abbiamo risolto problema simile con la seguente algo:

while (file not complete) 
    sleep for 1 sec 
    read the fourth byte of the file 
    if it is not 0 (contains 'f' of the 'ftyp' header) then 
     file is complete, break 

Il punto chiave è che MediaRecorder scrive la casella ftyp all'ultimo momento. Se è presente, il file è completo.

+0

Questo è promettente! Ci proveremo, grazie. –

1

Non ho provato io stesso, ma questo potrebbe funzionare:

pubblico rilascio void() Dal: API livello 1

Rilascia le risorse associate a questo oggetto MediaRecorder. È una buona pratica chiamare questo metodo quando hai finito di utilizzare il MediaRecorder .

Se fa ciò che dice, allora suppongo che se si chiama questo e dopo questo metodo si ritorna si sa che il file è pronto.

+0

Davvero? Ho pensato che fosse solo per liberare risorse e lasciare che il GC si occupasse di loro, inoltre, registriamo molte clip, quindi ricostruire il MediaRecorder ogni volta probabilmente danneggerebbe le prestazioni per noi. Lo indagherò ulteriormente, grazie! –

1

Nel mio test, indipendentemente dalle dimensioni della mediaRecorder.stop registrazione() è un metodo di bloccaggio che restituisce solo dopo che il file è stato completamente scritto e chiuso da il registratore multimediale.

Quindi la risposta di JPM è effettivamente corretta.

Lo si può verificare chiamando file.length() subito dopo l'arresto(). Troverete che la lunghezza del file di output è la lunghezza finale del file a questo punto. In altre parole, il registratore multimediale non scrive nulla oltre al file dopo che è stato restituito stop().

0

Ho avuto lo stesso problema in Xamarin e provato tutte queste soluzioni (tranne la soluzione Ash).Quello che ho finalmente fatto per risolvere il problema è stato chiamare la funzione sottostante nella funzione releaseMediaRecorder() prima di Reset e prima che venga chiamato Release.

mediaRecorder.setOutputFile("some new file") 
Problemi correlati