我的项目中有一个要求,视频被记录并上传到服务器,但由于移动网络不可靠,一开始我决定做的是每隔30秒
>停止录音机
>重设录像机状态
>检索由记录器写入的文件,并以不同的线程上传(多部分表单数据).
>根据当前时间戳的散列将录像机的文件更改为新文件.
>每30秒重复一次
这样做适合我的需要,因为每个30秒的视频文件大小不超过1MB,上传顺利进行.
但是我所面临的问题是,每当媒体记录器停止并再次启动时,延迟时间约为500ms,所以在服务器上收到的视频每隔30秒就会发生,这对我目前的情况来说是非常糟糕的,所以我正在考虑是否可以在飞行中更改录音机正在写的文件?
相关代码:
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(); } } } } };
这里是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; } }
这里是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; }
解决方法
您可以通过不调用release()方法和在stopAndResetRecorder()中执行的所有其他破坏来加速它(请参阅
documentation for the MediaRecorder state machine).
你也不需要调用stop()和reset().
你也不需要调用stop()和reset().
你可以使用一个中间的resetRecorder()函数,它刚刚执行了reset(),然后调用initializeAndStartRecording().完成所有录音后,您可以调用stopRecorder()来执行破坏您的mMediaRecorder.
正如我所说,这将节省你一些时间,但是您目前是否破坏和重新初始化MediaRecorder的额外开销是我不知道的延迟的很大一部分.尝试一下,如果它不能解决你的问题,我有兴趣知道它做了多少时间/没有保存.