如何在不停止mediarecorder的情况下更改mediarecorder的输出文件

Bha*_*gav 10 c++ java android native-code

我的项目中有一个要求,即录制视频并将其上传到服务器,但由于移动网络不可靠,开始时我决定每隔30秒做一次

  • 停止录音机

  • 重置录像机状态

  • 检索由记录器写入的文件,并将其(多部分表单数据)上载到不同的线程中.

  • 根据当前时间戳的哈希值将记录器的outfile更改为新文件.

  • 每30秒重复一次

这样做完全符合我的需要,因为每个30秒的视频文件大小不超过1MB,上传顺利进行.

但我面临的问题是,每次媒体录音机停止再次启动时都会有大约500ms的延迟,所以我在服务器上收到的视频每隔30秒会有500ms的时间,这对我目前的情况非常不利,所以我在想是否有可能只是改变录音机正在写入的文件?

相关代码:

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();
                    }
                }
            }
        }
    };
Run Code Online (Sandbox Code Playgroud)

这是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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是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;
    }
Run Code Online (Sandbox Code Playgroud)

abb*_*ath 0

在我看来, setOutputFile 调用有关MediaRecorder 源的本机方法,因此我认为没有一种简单的方法可以同时写入单独的文件。

最后将其分成一大块上传,但允许用户在开始上传过程后执行任何操作怎么样?这样用户就不会注意到上传需要多长时间,并且您可以稍后在上传成功/失败时通知他。

[编辑:]尝试将流式上传到服务器,服务器在其中使用分块机制来分隔文件。在这里您可以得到如何操作的简要说明。