SeemsIndie
SeemsIndie

Reputation: 520

MediaRecorder failed when i stop the recording

I have this error. Can somebody please help me, I think it's something about touch listener... The error is happening when I release my finger.

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)

And that is happening when I try to run this code:

from touch listener:

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

And these two methods:

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

Upvotes: 31

Views: 31724

Answers (4)

GauravDevMobile
GauravDevMobile

Reputation: 1322

I was facing same problem of stop failed while stopping the video after click on my stopScreenCapturing() method but only for the second time, first time it was just working fine. My this code fixed it for me finally. Hope it will help someone here.

To stop screen capturing write

     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
        }

and next time when you want to record again then call these lines in same sequence:

  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()
        }

    }

and after that start your recording. Always call prepare() before start() method as i did.

      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
        }

So, Basically why i was getting this error?

Because i was not setting up my virtual display(mVirutalDisplay) again after releasing it and making my projection null. If you are not using then you can bind your own surfaceview.

Upvotes: 0

Rahim .H
Rahim .H

Reputation: 98

In my case i was using Surface as the VideoSource and i just forget to set Input Surface. and then i got this -1007 error.

And i fixed by giving Input Surface and it worked fine.

Upvotes: 2

DigCamara
DigCamara

Reputation: 5568

Look at the documentation:

Note that a RuntimeException is intentionally thrown to the application, if no valid audio/video data has been received when stop() is called. This happens if stop() is called immediately after start(). The failure lets the application take action accordingly to clean up the output file (delete the output file, for instance), since the output file is not properly constructed when this happens.

In other words: Dalvik throws the exception on purpose. You have to handle it to clean up after your app. You'd have to handle it like this:

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

Upvotes: 69

soshial
soshial

Reputation: 6788

I had a similar error -1007 when I was recording audio with AMR_WB, but it turned out that the problem was that I forgot to set sampling rate.

mediaRecorder.setAudioSamplingRate(16000);

Upvotes: 7

Related Questions