录音停止时,MediaRecorder 失败。

31

我遇到了这个错误,请有经验的人帮忙看看,我觉得是与触摸监听器有关... 当我松开手指时出现了这个错误。

04-25 20:07:00.263: D/FB Sessions(18429): false
04-25 20:07:04.533: I/MediaRecorderJNI(18429): prepare: surface=0x189250 (identity=1813)
04-25 20:07:10.493: E/MediaRecorder(18429): stop failed: -1007
04-25 20:07:10.493: D/AndroidRuntime(18429): Shutting down VM
04-25 20:07:10.493: W/dalvikvm(18429): threadid=1: thread exiting with uncaught exception (group=0x40018608)
04-25 20:07:10.503: E/AndroidRuntime(18429): FATAL EXCEPTION: main
04-25 20:07:10.503: E/AndroidRuntime(18429): java.lang.RuntimeException: stop failed.
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.media.MediaRecorder.stop(Native Method)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.crewbase.rec.RecordActivity.stopRecording(RecordActivity.java:151)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.crewbase.rec.RecordActivity.access$2(RecordActivity.java:150)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.crewbase.rec.RecordActivity$1.onTouch(RecordActivity.java:79)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.view.View.dispatchTouchEvent(View.java:3897)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1737)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1153)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1721)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2200)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1884)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.os.Looper.loop(Looper.java:130)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at android.app.ActivityThread.main(ActivityThread.java:3835)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at java.lang.reflect.Method.invokeNative(Native Method)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at java.lang.reflect.Method.invoke(Method.java:507)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
04-25 20:07:10.503: E/AndroidRuntime(18429):    at dalvik.system.NativeStart.main(Native Method)

当我尝试运行这段代码时,发生了这样的情况:

从触摸监听器中:

/// Preview is SurfaceView in my view
preview.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                prepareRecording();
                break;
            case MotionEvent.ACTION_MOVE:
            //Log.d(TAG, String.format("ACTION_MOVE | x:%s y:%s", 
                break;
            case MotionEvent.ACTION_UP:
                stopRecording();
                break;
            }
            return true;
        }
    });

以及这两种方法:

private void prepareRecording() {
    try {
        camera.unlock();

        recorder = new MediaRecorder();
        recorder.setCamera(camera);
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        File tempFile = new File(Environment.getExternalStorageDirectory(), "/rec/temp/video_" + String.valueOf(videoCount) + ".mp4");

        recorder.setOutputFile(tempFile.getPath());
        recorder.setVideoFrameRate(25);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        recorder.setPreviewDisplay(holder.getSurface());

        recorder.prepare();
        recorder.start();
    }  catch (IllegalStateException e) {
        Log.e("REDORDING :: ",e.getMessage());
        e.printStackTrace();
    } catch (IOException e) {
        Log.e("REDORDING :: ",e.getMessage());
        e.printStackTrace();
    }
}

private void stopRecording() {
    recorder.stop();
    camera.lock();
}
4个回答

69

查看文档

请注意,如果在调用start()后立即调用stop()且未收到有效的音频/视频数据,则应用程序会故意抛出RuntimeException异常。如果发生这种情况,则失败会让应用程序采取相应的操作来清理输出文件(例如删除输出文件),因为在此情况下输出文件没有正确构建。

换句话说:Dalvik是有意抛出异常的。您必须处理它以清理您的应用程序。您可以像这样处理它:

private void stopRecording() {
    try {
        recorder.stop();
    } catch(RuntimeException stopException) {
        // handle cleanup here
    }
    camera.lock();
}

1
有没有其他的方法来做这件事? - bhavesh kaila
1
在我的情况下,它不是立即启动/停止,或者使用MediaRecorder的MediaProjection根本无法工作。我无法理解为什么停止屏幕录制时会出现这个问题。 - user25
谢谢您的反馈。Android 应该提供像 onRecordStarted 和 onRecordStopped 这样的监听器。这让人更加讨厌 Android 了。 - Bugs Happen

6

在使用 AMR_WB 录制音频时,我遇到了类似的错误代码 -1007,但后来发现问题是我忘记设置采样率了。

mediaRecorder.setAudioSamplingRate(16000);

2

在我的情况下,我使用Surface作为视频源,但我忘记设置输入Surface,然后我遇到了-1007错误。

我通过设置输入Surface来解决问题,并且它正常工作了。


0

我在使用stopScreenCapturing()方法停止视频时,遇到了“停止失败”的问题,但只有第二次出现,第一次正常工作。

我的代码最终解决了这个问题。希望能对大家有所帮助。

要停止屏幕捕获,请编写:

     private fun stopScreenCapturing() {
            
            if (mMediaRecorder == null) {
                return
            }
            mMediaRecorder?.stop()
            mMediaRecorder?.reset()

//mVirtualDisplay is used to mirror the projection and bind it to mediarecorder's surfaceview
            if(mVirtualDisplay==null)
            {
                return
            }
            mVirtualDisplay.release()

//MediaProjection API
            if (projection != null) {
                projection?.unregisterCallback(cbk)
                projection?.stop()
                projection = null
            }

//a flag is maintained to check if recording is started or not
                videoRecordingStarted = false
        }

下次当您想要再次录制时,请以相同的顺序调用这些行:

  private fun initRecorder() {

            mMediaRecorder = MediaRecorder()
            mMediaRecorder!!.setAudioSource(MediaRecorder.AudioSource.MIC)
            mMediaRecorder!!.setVideoSource(MediaRecorder.VideoSource.SURFACE)
            mMediaRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
            mMediaRecorder!!.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
            mMediaRecorder!!.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
            mMediaRecorder!!.setVideoEncodingBitRate(512 * 1000)
            mMediaRecorder!!.setVideoFrameRate(30)
            mMediaRecorder!!.setVideoSize(
                mContext.resources.displayMetrics.widthPixels,
                mContext.resources.displayMetrics.heightPixels
            )
        mMediaRecorder!!.setOutputFile(getFilePath())
           try {
            mMediaRecorder!!.prepare()
        } catch (e: IllegalStateException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }

    }

然后开始录制。像我一样,在调用start()方法之前始终调用prepare()方法。

      private fun startVideoCapture() {
    
//i need to use this resultdata multiple times after getting permission, so i stored it in global variable
            if (projection == null) {
                projection = mediaprojectionManager.getMediaProjection(resultCode, resultData!!)
              
            }
    
                mVirtualDisplay = projection?.createVirtualDisplay(
                    "ScreenCapture",
                    480, 640,
                    resources.displayMetrics.densityDpi,
                    VIRT_DISPLAY_FLAGS, mMediaRecorder?.surface, null, null
                )!!
    
            mMediaRecorder?.start()
    
            videoRecordingStarted = true
        }

所以,基本上我为什么会得到这个错误?

因为我在释放mVirutalDisplay并将我的投影设置为空之后没有再次设置我的虚拟显示屏(mVirutalDisplay)。如果您不使用它,则可以绑定自己的surfaceview。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接