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

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

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.

  • ¿La llave trasera del androide no hace nada?
  • Error: No se encontró ningún recurso que coincida con el nombre dado (en 'title' con el valor '@ string / menu_settings')
  • Obtener la altura de la pantalla en Android
  • Tipo de soporte no admitido: estado HTTP 415
  • Android hace que los números de teléfono puedan hacer clic, autodetect
  • Android - getTabHost () no está definido
  • Android: Google reproduce los servicios de juegos error de conexión (java.lang.IllegalStateException: GoogleApiClient debe estar conectado.)
  • Hacer solicitud de volley en diferentes hilos
  • Android MotionEvent Puntero Indice Confusión
  • JRE en Android
  • ¿Cómo hacer referencia a un estilo definido en un módulo de Android con IntelliJ?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.