Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android MediaRecorder crashed after set profile

I have a problem to save a video to sdcard using MediaRecorder on android.

My code works fie until I reach the line that set the profile to high quality.

This is my code:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_sample_testing);
        // Show the Up button in the action bar.
        //setupActionBar();
        overridePendingTransition(0, 0);

        SurfaceView cameraView = (SurfaceView)findViewById(R.id.videoView1);

        holder = cameraView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        intentTestResults = new Intent(this, TestResultsAct.class);

        TestPB = (ProgressBar) findViewById(R.id.ProgressBarTest);

        new Thread(new Runnable() {

            @Override
            public void run() {
                while(mProgressStatus < 100){
                    if(mProgressStatus == 1)
                        record();
                    if(mProgressStatus == 35)
                        record();
                    mProgressStatus += 1;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            TestPB.setProgress(mProgressStatus);
                        }
                    });
                }
            }
        }).start();
        //
    }

while

 private void initRecorder() {
        camera.unlock();

        recorder.setCamera(camera);
        recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
        CamcorderProfile cpHigh = CamcorderProfile
                .get(CamcorderProfile.QUALITY_HIGH);
        recorder.setProfile(cpHigh);
        recorder.setOutputFile(Environment.getExternalStorageDirectory() + "/DCIM/Frames/videocapture_example.mp4");
        recorder.setMaxDuration(50000); // 50 seconds
        recorder.setMaxFileSize(300000000); // Approximately 5 megabytes
    }
    private void prepareRecorder() {
        recorder.setPreviewDisplay(holder.getSurface());
        try {
            recorder.prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
            finish();
        } catch (IOException e) {
            e.printStackTrace();
            finish();
        }
    }

    void record()
    {
        if (recording) {
            recorder.stop();
            recording = false;
            camera.lock();
            parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(parameters);
            camera.unlock();
            recorder.release();
            //finish();
        } else {
            recording = true;
            initRecorder();
            prepareRecorder();
            recorder.start();
        }
    }

My problem came after this line : recorder.setProfile(cpHigh);

This is the logcat:

12-26 10:37:43.670: E/MediaRecorder(6046): try to set the audio encoder without setting the audio source first
    12-26 10:38:35.150: W/dalvikvm(6046): threadid=11: thread exiting with uncaught exception (group=0x40fee2a0)
    12-26 10:38:37.065: E/AndroidRuntime(6046): FATAL EXCEPTION: Thread-794
    12-26 10:38:37.065: E/AndroidRuntime(6046): java.lang.IllegalStateException
    12-26 10:38:37.065: E/AndroidRuntime(6046):     at android.media.MediaRecorder.setAudioEncoder(Native Method)
    12-26 10:38:37.065: E/AndroidRuntime(6046):     at android.media.MediaRecorder.setProfile(MediaRecorder.java:370)
    12-26 10:38:37.065: E/AndroidRuntime(6046):     at com.example.homedevice.SampleTestingAct.initRecorder(SampleTestingAct.java:124)
    12-26 10:38:37.065: E/AndroidRuntime(6046):     at com.example.homedevice.SampleTestingAct.record(SampleTestingAct.java:155)
    12-26 10:38:37.065: E/AndroidRuntime(6046):     at com.example.homedevice.SampleTestingAct$2.run(SampleTestingAct.java:90)
    12-26 10:38:37.065: E/AndroidRuntime(6046):     at java.lang.Thread.run(Thread.java:856)
    12-26 10:38:47.555: E/MediaRecorder(6046): stop called in an invalid state: 4

The exception that was written is : java.lang.IllegalStateException

What I'm doing wrong?

EDIT1(with sound permission):

private void initRecorder() {
    camera.unlock();

    recorder.setCamera(camera);
    recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    //recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
    //recorder.setVideoSize(1920, 1080);
    //recorder.setVideoFrameRate(30);
    CamcorderProfile cpHigh = CamcorderProfile
            .get(CamcorderProfile.QUALITY_HIGH);
    recorder.setProfile(cpHigh);
    recorder.setOutputFile(Environment.getExternalStorageDirectory() + "/DCIM/Frames/videocapture_example.mp4");
    recorder.setMaxDuration(50000); // 50 seconds
    recorder.setMaxFileSize(300000000); // Approximately 5 megabytes
}

Edit2(logcat) : This is the logcat

    12-26 11:32:43.170: E/AndroidRuntime(18552): FATAL EXCEPTION: Thread-1016
12-26 11:32:43.170: E/AndroidRuntime(18552): java.lang.IllegalStateException
12-26 11:32:43.170: E/AndroidRuntime(18552):    at android.media.MediaRecorder.setOutputFormat(Native Method)
12-26 11:32:43.170: E/AndroidRuntime(18552):    at android.media.MediaRecorder.setProfile(MediaRecorder.java:357)
12-26 11:32:43.170: E/AndroidRuntime(18552):    at com.example.homedevice.SampleTestingAct.initRecorder(SampleTestingAct.java:127)
12-26 11:32:43.170: E/AndroidRuntime(18552):    at com.example.homedevice.SampleTestingAct.record(SampleTestingAct.java:158)
12-26 11:32:43.170: E/AndroidRuntime(18552):    at com.example.homedevice.SampleTestingAct$2.run(SampleTestingAct.java:90)
12-26 11:32:43.170: E/AndroidRuntime(18552):    at java.lang.Thread.run(Thread.java:856)
setOutputFormat called in an invalid state: 4
threadid=11: thread exiting with uncaught exception (group=0x40fee2a0).
like image 305
user2235615 Avatar asked Nov 10 '22 15:11

user2235615


1 Answers

setProfile() function.

It always calls setAudioEncoder() so if you don't set the audio source it will crash.

try to include this in your code:

recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); 
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); 

recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); 

Explanation:

CamcorderProfile also sets audio properties (such as Codec, BitRate, SampleRate,...) so you need to set an Audio Source before calling it, that's why the app crashed. If you don't want to record audio try the next code:

recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoSize(WIDTH, HEIGHT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
recorder.setOutputFile(PATH);
recorder.setPreviewDisplay(SURFACE);

recorder.prepare();
recorder.start();
like image 149
gaurav5430 Avatar answered Nov 14 '22 23:11

gaurav5430