Ошибка Android Media Recorder Нет правильного выходного файла
Я пытаюсь записать видео с помощью Media Recorder. Но я получаю IOException при вызове prepare() медиа-рекордера, который говорит
setOutputFormat called in an invalid state: 4
java.io.IOException: No valid output file
Я следовал за всеми шагами как упомянуто в документах.
Вот мой способ начать запись:
private void initRecorder(Surface surface) throws RuntimeException,
IOException, IllegalArgumentException {
// Step 1: Get camera instance and initialise MediaRecorder
try {
mCamera = getCameraInstance();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Camera is in use by other application", Toast.LENGTH_LONG)
.show();
}
mMediaRecorder = new MediaRecorder();
// Step 2: Unlock and set camera to media recorder
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
try {
// Step 3: Set AV Sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 4: Set Camcorder profile
mMediaRecorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH));
} catch (IllegalStateException ise) {
Toast.makeText(getApplicationContext(),
"Cannot set Audio/Video Source", Toast.LENGTH_LONG).show();
}
File file = new File(sos_vid_dir, "test.mp4");
// Step 5: Set output format and file path
try {
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(file.getAbsolutePath());
} catch (IllegalStateException ise) {
Toast.makeText(getApplicationContext(),
"Cannot set output file format", Toast.LENGTH_LONG).show();
}
// Step 6: Set Output preview
mMediaRecorder.setPreviewDisplay(surface);
mCamera.startPreview();
// No limit. Check the space on disk!
mMediaRecorder.setMaxDuration(-1);
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
shutdown();
} catch (IOException ioe) {
ioe.printStackTrace();
shutdown();
}
mInitSuccesful = true;
}
И это мой logcat:
12-16 12:34:45.747: E/MediaRecorder(15634): setOutputFormat called in an invalid state: 4
12-16 12:34:45.998: W/System.err(15634): java.io.IOException: No valid output file
12-16 12:34:45.999: W/System.err(15634): at android.media.MediaRecorder.prepare(MediaRecorder.java:683)
12-16 12:34:45.999: W/System.err(15634): at com.dzo.timelapsevideo.MainActivity.initRecorder(MainActivity.java:169)
12-16 12:34:45.999: W/System.err(15634): at com.dzo.timelapsevideo.MainActivity.surfaceCreated(MainActivity.java:97)
12-16 12:34:45.999: W/System.err(15634): at android.view.SurfaceView.updateWindow(SurfaceView.java:582)
12-16 12:34:46.004: W/System.err(15634): at android.view.SurfaceView.access$000(SurfaceView.java:83)
12-16 12:34:46.004: W/System.err(15634): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:179)
12-16 12:34:46.005: W/System.err(15634): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:726)
12-16 12:34:46.006: W/System.err(15634): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2105)
12-16 12:34:46.006: W/System.err(15634): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1140)
12-16 12:34:46.007: W/System.err(15634): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4726)
12-16 12:34:46.008: W/System.err(15634): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:747)
12-16 12:34:46.008: W/System.err(15634): at android.view.Choreographer.doCallbacks(Choreographer.java:567)
12-16 12:34:46.008: W/System.err(15634): at android.view.Choreographer.doFrame(Choreographer.java:536)
12-16 12:34:46.009: W/System.err(15634): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:733)
12-16 12:34:46.010: W/System.err(15634): at android.os.Handler.handleCallback(Handler.java:615)
12-16 12:34:46.010: W/System.err(15634): at android.os.Handler.dispatchMessage(Handler.java:92)
12-16 12:34:46.011: W/System.err(15634): at android.os.Looper.loop(Looper.java:153)
12-16 12:34:46.011: W/System.err(15634): at android.app.ActivityThread.main(ActivityThread.java:5000)
12-16 12:34:46.012: W/System.err(15634): at java.lang.reflect.Method.invokeNative(Native Method)
12-16 12:34:46.013: W/System.err(15634): at java.lang.reflect.Method.invoke(Method.java:511)
12-16 12:34:46.013: W/System.err(15634): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
12-16 12:34:46.014: W/System.err(15634): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
12-16 12:34:46.014: W/System.err(15634): at dalvik.system.NativeStart.main(Native Method)
Линия № 169 это:
mMediaRecorder.prepare();
И строки нет. 97 это:
initRecorder(holder.getSurface());
2 ответа
Вы устанавливаете OutputFormat дважды. когда вы вызываете метод:
mMediaRecorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH));
и это делает OutputFormat и через несколько строк вы вызываете метод:
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
и это попытаться установить формат снова и выбросить исключение
Не уверен что sos_vid_dir
но у вас нет необходимости создавать файл перед настройкой, вам просто нужно передать путь к функции и позволить медиа создать сам файл. Вместо этого просто создайте строку для хранения пути.
private void initRecorder(Surface surface) throws RuntimeException,
IOException, IllegalArgumentException {
try {
//build filename
String mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/test.mp4";
// Step 1: Get camera instance and initialise MediaRecorder
mCamera = getCameraInstance();
//Unlock if nessecarry
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH){
mCamera.unlock();
}
// Step 2:et camera to media recorder
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
// Step 3: Set AV Sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 4: Set Camcorder profile
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 5: Set output format and file path
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(mFileName);
// Step 6: Set Output preview
mMediaRecorder.setPreviewDisplay(surface);
mCamera.startPreview();
// No limit. Check the space on disk!
mMediaRecorder.setMaxDuration(-1);
mMediaRecorder.prepare();
// if we get here then it's all successful
mInitSuccesful = true;
} catch (IllegalStateException ise) {
// print to stack
e.printStackTrace();
// show error in toast
Toast.makeText(getApplicationContext(),
"initRecorder(Surface surface)"
+ e.printStackTrace().ToString() , Toast.LENGTH_LONG).show();
//Or log it to Log cat
Log.d("mylog", "IllegalStateException" + e.printStackTrace().ToString());
shutdown();
} catch (IOException ioe) {
ioe.printStackTrace();
shutdown();
}
catch (Exception e) {
e.printStackTrace().ToString()
Toast.makeText(getApplicationContext(),
"Exception : " + e.printStackTrace().ToString(),
Toast.LENGTH_LONG).show();
}
}