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).
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With