2011-09-14 35 views
14

Estamos utilizando MediaRecorder para grabar video en un archivo en el almacenamiento externo usando setOutputFile() antes de realizar la grabación real.Cómo saber cuándo MediaRecorder ha terminado de escribir datos en el archivo

Todo funciona bien, pero el problema principal es que tan pronto como finalice la grabación, queremos comenzar a reproducir el video grabado en una VideoView.

¿Cómo saber cuándo el archivo está listo para leerse y reproducirse?

Respuesta

18

La clase FileObserver se adapta perfectamente a sus necesidades. Here is the documentation. Es fácil de usar Cuando un archivo observado se cierra después de la escritura, se llama a la devolución de llamada onEvent con CLOSE_WRITE como parámetro.

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

No se olvide de llamar stopWatching() ..

+0

No puedo probar esto ahora, pero ¿sabes si se garantiza que MediaRecorder no cierre el archivo entre escrituras? –

+0

No estoy enterado de eso. Pero incluso si lo hace, puede mantener el estado de grabación en un miembro y verificarlo en 'onEvent'. Si la grabación está en pausa, simplemente ignore el evento. – Ronnie

+0

Es cierto. Creo que esta parece ser la mejor solución, ¡gracias! –

0

Aparentemente no hay manera de detectar cuando la grabación se detuvo en el Reproductor multimedia, pero hay una parada() que puede anular si crea una clase personalizada que implemente MediaRecorder. aquí me gustaría hacer algo como esto:

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

Entonces, podrá acceder al booleano para ver si se ha detenido la grabación.

+1

Pero cuando la grabación se detiene, se tienen que escribir más datos en el almacenamiento y no podemos comenzar a reproducir el video hasta que la grabación realmente haya sido escrita en el almacenamiento. –

+0

¿Qué tiene que escribir? Si está personalizado lo que está escribiendo, llame a su función personalizada desde el método de parada anulada y luego configure la variable detenida después de su llamada. – JPM

+2

Sé cuando detenemos la grabación. Cuando la grabación se detiene, la grabadora escribe datos en el disco y quiero saber cuándo ha terminado de escribir los datos :) –

0

Una manera sucia sería comprobar el valor lastModified() del archivo y abrir el VideoView si el archivo no se modificó durante 2 segundos.

+0

Ya tenemos implementados los hacks, pero preferiría una solución adecuada si la hay. Si no hay ninguno, bueno, entonces seguiremos usando nuestro truco y añadiremos algún error para protegerlo :) –

5

Hemos resuelto un problema similar con el siguiente 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 

El punto clave es que MediaRecorder escribe el cuadro ftyp en el último momento. Si está en su lugar, entonces el archivo está completo.

+0

¡Esto es prometedor! Intentaremos esto, gracias. –

1

No he probado esto por mí mismo, pero esto podría funcionar:

liberación public void() desde: API de nivel 1

lanzamientos recursos asociados con este objeto MediaRecorder. Es una buena práctica llamar a este método cuando haya terminado de utilizar la MediaRecorder .

Si hace lo que dice, entonces supongo que si llama a esto y después de que este método regrese, sabrá que el archivo está listo.

+0

¿De verdad? Pensé que era solo para liberar recursos y dejar que el GC los tratara, también, grabamos muchos clips, por lo que reconstruir el MediaRecorder cada vez probablemente perjudicaría el rendimiento para nosotros. Lo investigaré más a fondo, ¡gracias! –

1

En mis pruebas con independencia del tamaño de la mediaRecorder.stop grabación() es un método de bloqueo que sólo devuelve después de que el archivo ha sido completamente escrita y cerrada por el grabador de medios.

Así que la respuesta de JPM es en realidad correcta.

Puede verificar esto llamando a File.length() inmediatamente después de detener(). Descubrirá que la longitud del archivo de salida es la longitud final del archivo en este punto. En otras palabras, el grabador de medios no escribe nada más en el archivo después de que tope() haya regresado.

0

Tuve el mismo problema en xamarin y probé todas estas soluciones (excepto la solución de cenizas).Lo que finalmente hice para resolver el problema fue llamar a la función siguiente en la función releaseMediaRecorder() antes de reiniciar y antes de llamar a Release.

Cuestiones relacionadas