Android Media Recorder错误没有有效的输出文件

时间:2013-12-16 07:09:43

标签: android video-capture android-mediarecorder

我正在使用Media Recorder尝试录制视频。但是当我调用prepare()媒体录音机时,我收到 IOException

setOutputFormat called in an invalid state: 4
java.io.IOException: No valid output file

我按照docs中提到的所有步骤进行了操作。

这是我开始录制的方法:

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());
<{3>} surfaceCreated()中的

2 个答案:

答案 0 :(得分:0)

不确定sos_vid_dir是什么,但在设置之前没有创建文件,只需要将路径传递给函数,让媒体自己创建文件 而只是创建一个String来保存路径。

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

答案 1 :(得分:0)

您将OutputFormat设置两次。 当你打电话给方法时:

mMediaRecorder.setProfile(CamcorderProfile
                .get(CamcorderProfile.QUALITY_HIGH));

然后它会输出OutputFormat,稍后你会调用方法:

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) 

并尝试再次设置格式并抛出异常