I'm writing a camera app and am having an issue with the S3. Whenever I start recording, the display goes to garbage (see screenshots below). Then, when I stop recording I get an exception:
10-02 13:36:31.647: E/MediaRecorder(24283): stop failed: -1007
10-02 13:36:31.647: D/AndroidRuntime(24283): Shutting down VM
10-02 13:36:31.647: W/dalvikvm(24283): threadid=1: thread exiting with uncaught exception (group=0x40c49a68)
10-02 13:36:31.647: E/AndroidRuntime(24283): FATAL EXCEPTION: main
10-02 13:36:31.647: E/AndroidRuntime(24283): java.lang.RuntimeException: stop failed.
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.media.MediaRecorder.native_stop(Native Method)
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.media.MediaRecorder.stop(MediaRecorder.java:742)
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.myapp.android.ui.camera.NewCameraActivity.stopRecording(NewCameraActivity.java:178)
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.myapp.android.ui.camera.NewCameraActivity.toggleRecording(NewCameraActivity.java:189)
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.myapp.android.ui.camera.NewCameraActivity.onClick(NewCameraActivity.java:97)
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.view.View.performClick(View.java:3565)
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.view.View$PerformClick.run(View.java:14165)
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.os.Handler.handleCallback(Handler.java:605)
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.os.Handler.dispatchMessage(Handler.java:92)
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.os.Looper.loop(Looper.java:137)
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.app.ActivityThread.main(ActivityThread.java:4514)
10-02 13:36:31.647: E/AndroidRuntime(24283): at java.lang.reflect.Method.invokeNative(Native Method)
10-02 13:36:31.647: E/AndroidRuntime(24283): at java.lang.reflect.Method.invoke(Method.java:511)
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
10-02 13:36:31.647: E/AndroidRuntime(24283): at dalvik.system.NativeStart.main(Native Method)
I've tested my app on the Galaxy Nexus (4.1), Galaxy S2, Nexus S, and Galaxy Tab 10.1. All of them work fine. I've followed development guidelines for video recording. I don't understand why this device is so different from the others. Here's what I'm seeing on the device. First picture is before I start recording. Second picture is what happens once I start recording.
Here's my code for preparing and starting the MediaRecorder
object:
@Override
public void onClick( View v ) {
switch (v.getId()) {
case R.id.camera_action_ImageView:
int mode = getMode();
if ( mode == MODE_PHOTO ) {
focusThenTakePicture();
}
else if ( mode == MODE_VIDEO ) {
toggleRecording();
}
break;
}
}
private void startRecording() {
if ( prepareRecorder() ) {
getRecorder().start();
setRecording( true );
}
}
@TargetApi( 9 )
private boolean prepareRecorder() {
Camera camera = getCamera();
camera.unlock();
MediaRecorder recorder = new MediaRecorder();
setRecorder( recorder );
recorder.setCamera( camera );
recorder.setAudioSource( MediaRecorder.AudioSource.CAMCORDER );
recorder.setVideoSource( MediaRecorder.VideoSource.CAMERA );
CamcorderProfile profile;
if ( Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD ) {
profile = CamcorderProfile.get( CamcorderProfile.QUALITY_HIGH );
}
else {
profile = CamcorderProfile.get( getCameraId(), CamcorderProfile.QUALITY_HIGH );
}
recorder.setProfile( profile );
File outputFile = LocalMediaUtil.getOutputMediaFile( LocalMediaUtil.MEDIA_TYPE_VIDEO );
setRecorderOutputFile( outputFile );
recorder.setOutputFile( outputFile.toString() );
recorder.setPreviewDisplay( getPreview().getHolder().getSurface() );
try {
recorder.prepare();
}
catch (Exception e) {
camera.lock();
setRecorder( null );
return false;
}
return true;
}
private void stopRecording() {
MediaRecorder recorder = getRecorder();
recorder.stop();
releaseRecorder();
setRecording( false );
LocalMediaUtil.scanMedia( this, getRecorderOutputFile().toString(), 90 );
setRecorderOutputFile( null );
}
private void toggleRecording() {
if ( isRecording() ) {
stopRecording();
}
else {
startRecording();
}
}
private void releaseRecorder() {
MediaRecorder recorder = getRecorder();
if ( recorder != null ) {
recorder.reset();
recorder.release();
setRecorder( null );
getCamera().lock();
}
}
Edit: So this has something to do with the CamcorderProfile
being set. I change it to CamcorderProfile.QUALITY_LOW
and it worked fine. So how can I have high resolution video without garbled output?
Edit2: So with CamcorderProfile.QUALITY_LOW
set, I get no errors using the video recorder. However, the output video looks very similar the garbled screenshot posted above. So what gives?