Cómo cambiar el archivo de salida de un mediarecorder sin detener el mediarecorder
Tengo un requisito en mi proyecto, donde el video se está grabando y subiendo al servidor, pero como las redes móviles no son confiables, al principio lo que decidí hacer fue cada 30 segundos
-
Detener la grabadora
- Androide. Cambiar el color de fondo de un FrameLayout de código
- Algo falta en mi proyecto de prueba de Android?
- ¿Por qué no se llama a UtteranceProgress Listener a Text to Speach?
- SSLHandshakeException Ancla de confianza para ruta de certificación no encontrada Android HTTPS
- Parsing JSON de los mapas google DistanceMatrix api en android
-
Restablecer el estado de la grabadora
-
Recuperar el archivo escrito por la grabadora y cargar (datos de formulario de varias partes) en un hilo diferente.
-
Cambie el archivo externo de la grabadora a un nuevo archivo basado en el hash de la marca de tiempo actual.
-
Repita el proceso cada 30 segundos
Hacer esto satisface mis necesidades perfectamente ya que cada uno de los 30sec tamaño de archivo de vídeo no son más de 1 MB y la subida sucede suavemente.
Pero el problema que enfrento es que cada vez que el grabador de medios se detiene y comienza de nuevo hay un retraso de unos 500ms, por lo que el video que recibo en el servidor tiene estos 500ms se rompe cada 30secs que es realmente malo para mi situación actual, por lo que Estaba pensando si sería posible cambiar el archivo que la grabadora está escribiendo sobre la marcha?
Código relevante:
GenericCallback onTickListener = new GenericCallback() { @Override public void execute(Object data) { int timeElapsedInSecs = (int) data; if (timeElapsedInSecs % pingIntervalInSecs == 0) { new API(getActivity().getApplicationContext()).pingServer(objInterviewQuestion.getCurrentAccessToken(), new NetworkCallback() { @Override public void execute(int response_code, Object result) { // TODO: HANDLE callback } }); } if (timeElapsedInSecs % uploadIntervalInSecs == 0 && timeElapsedInSecs < maxTimeInSeconds) { if (timeElapsedInSecs / uploadIntervalInSecs >= 1) { if(stopAndResetRecorder()) { openConnectionToUploadQueue(); uploadQueue.add( new InterviewAnswer(0, objInterviewQuestion.getQid(), objInterviewQuestion.getAvf(), objInterviewQuestion.getNext(), objInterviewQuestion.getCurrentAccessToken())); objInterviewQuestion.setAvf(MiscHelpers.getOutputMediaFilePath()); initializeAndStartRecording(); } } } } };
Aquí es initializeAndStartRecording()
:
private boolean initializeAndStartRecording() { Log.i("INFO", "initializeAndStartRecording"); if (mCamera != null) { try { mMediaRecorder = CameraHelpers.initializeRecorder(mCamera, mCameraPreview, desiredVideoWidth, desiredVideoHeight); mMediaRecorder.setOutputFile(objInterviewQuestion.getAvf()); mMediaRecorder.prepare(); mMediaRecorder.start(); img_recording.setVisibility(View.VISIBLE); is_recording = true; return true; } catch (Exception ex) { MiscHelpers.showMsg(getActivity(), getString(R.string.err_cannot_start_recorder), AppMsg.STYLE_ALERT); return false; } } else { MiscHelpers.showMsg(getActivity(), getString(R.string.err_camera_not_available), AppMsg.STYLE_ALERT); return false; } }
Aquí está stopAndResetRecorder
:
boolean stopAndResetRecorder() { boolean success = false; try { if (mMediaRecorder != null) { try { //stop recording mMediaRecorder.stop(); mMediaRecorder.reset(); mMediaRecorder.release(); mMediaRecorder = null; Log.d("MediaRecorder", "Recorder Stopped"); success = true; } catch (Exception ex) { if(ex != null && ex.getMessage()!=null && ex.getMessage().isEmpty()){ Crashlytics.log(Log.ERROR, "Failed to stop MediaRecorder", ex.getMessage()); Crashlytics.logException(ex); } success = false; } finally { mMediaRecorder = null; is_recording = false; is_recording = false; } } } catch (Exception ex) { success = false; } Log.d("MediaRecorder", "Success = " + String.valueOf(success)); return success; }
- Cómo transferir datos de una actividad a otra en android
- Comenzando con Android: Java o Python (SL4A)
- Cómo depurar un servicio de fondo de Android?
- MissingResourceException: No se puede encontrar el paquete para el nombre base sun.util.logging.resources.logging, locale en_US
- ¿Cuál es la diferencia entre View.postDelayed () y Handler.postDelayed () en el hilo principal?
- ¿Todos los dispositivos android tienen la carpeta "sdcard"?
- Borrar el botón de retroceso para actuar como botón de inicio
- No se puede ejecutar un AlertDialog en un método doInbackground ()
Puede acelerar ligeramente al no llamar al método release()
y todo el resto de la destrucción que realiza en stopAndResetRecorder()
(consulte la documentación de la máquina de estado MediaRecorder ). Tampoco es necesario llamar a stop()
y reset()
.
En cambio, podría tener una función resetRecorder()
intermedia que acaba de realizar reset()
luego llamar a initializeAndStartRecording()
. Cuando termine toda su grabación, podría llamar a stopRecorder()
que realizaría la destrucción de su mMediaRecorder
.
Como digo, esto te ahorrará tiempo, pero si la sobrecarga adicional que tienes actualmente de destruir y volver a inicializar el MediaRecorder
es una parte significativa de la demora que no sé. Déle un intento, y si no soluciona su problema, estaría interesado saber cuánto tiempo hizo / no ahorró.
Me parece que el setOutputFile llama a un método nativo con respecto a la fuente de MediaRecorder , así que no creo que haya una manera fácil de escribir en archivos separados al mismo tiempo.
¿Qué pasa con subirlo en un trozo al final, pero permitir al usuario hacer algo después de iniciar el proceso de carga? A continuación, el usuario no se dará cuenta de la cantidad de tiempo que tarda en cargarse, y puede notificarlo más tarde cuando la subida ha sido satisfactoria o ha fallado.
[Editar:] Intente transferir la carga al servidor, donde el servidor hace el mecanismo de fragmentación para separar los archivos. Aquí usted puede tener una breve explicación de cómo hacerlo.
Aparentemente MediaRecorder.setOutputFile()
también acepta un FileDescriptor
.
Por lo tanto, si estuviera programando a bajo nivel (JNI) podría haber representado el flujo de entrada de un proceso como un descriptor de archivo y, a su vez, habría escrito ese proceso en diferentes archivos cuando lo deseara. Pero eso implicaría gestionar ese proceso "router" nativo de java.
Por desgracia, en Java API lado, usted está fuera de suerte.
- ¿Cómo mostrar 2 vistas, con un gradiente de desvanecimiento efecto en Android?
- Android – Cómo tratar un cambio de diálogo en la orientación de pantalla