【问题标题】:setOutputFormat called in an invalid state: 4 (where and why)setOutputFormat 在无效状态下调用:4(在哪里以及为什么)
【发布时间】:2014-02-07 16:21:00
【问题描述】:

我有以下代码:

Log.i("xx","A");
                 media_recorder = new MediaRecorder();
Log.i("xx","B");
                 media_recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
Log.i("xx","C");
                 media_recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
Log.i("xx","D");
                 media_recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
Log.i("xx","E");
                 media_recorder.setVideoSize(320, 240);
Log.i("xx","F");
                 media_recorder.setVideoFrameRate(15);
Log.i("xx","G");
                 CamcorderProfile profile = CamcorderProfile.get(CameraInfo.CAMERA_FACING_FRONT,CamcorderProfile.QUALITY_LOW);
Log.i("xx","H");
                 media_recorder.setProfile(profile);
Log.i("xx","I");
                 media_recorder.setOutputFile(fname);

执行代码时,我在日志中看到以下内容;

02-07 16:12:47.628: I/xx(15436): A
02-07 16:12:47.628: I/xx(15436): B
02-07 16:12:47.638: I/xx(15436): C
02-07 16:12:47.638: I/xx(15436): D
02-07 16:12:47.638: I/xx(15436): E
02-07 16:12:47.638: I/xx(15436): F
02-07 16:12:47.638: I/xx(15436): G
02-07 16:12:47.638: I/xx(15436): H
02-07 16:12:47.638: E/MediaRecorder(15436): setOutputFormat called in an invalid state: 4

这让我感到困惑,因为对 setOutputFormat 的调用是在“C”和“D”之间进行的,但错误报告似乎是在 H 之后立即报告的(从未到达“I”)。所以现在我不知道是什么导致了错误,而且我对错误发生在哪里感到困惑。

编辑:我刚刚在调试器中逐步完成了代码 - 果然在调用 setProfile(profile) 期间发生了错误......所以看起来对 setOutputFormat 的调用(在“C”和“D”之间)必须正常工作,但是 setProfile 必须自己再次调用 setOutputFormat ,然后失败......这是怎么回事?

编辑:无效状态 4 究竟是什么意思?是否有一些列表可以告诉您每个可能的无效状态编号 1、2、3、4...等的含义?

【问题讨论】:

    标签: android video-capture


    【解决方案1】:

    在您的上述代码中,media_recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) 被调用了两次。您在代码中在Log.i("xx","C");Log.i("xx","D"); 之间调用的第一次出现,以及在MediaRecorder 中通过您的media_recorder.setProfile(profile); 方法内部调用的第二次出现,即在Log.i("xx","H");Log.i("xx","I"); 之间。

    因为 MediaRecorder 对象应该遵循如下的生命周期:

    请参考 MediaRecoder 类 click here 中的 setProfile() 方法并再次比较您的代码。

    【讨论】:

      【解决方案2】:

      这里是setProfile方法的源代码:

      public void setProfile(CamcorderProfile profile) {
        setOutputFormat(profile.fileFormat);
        setVideoFrameRate(profile.videoFrameRate);
        setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
        setVideoEncodingBitRate(profile.videoBitRate);
        setVideoEncoder(profile.videoCodec);
        if (profile.quality >= CamcorderProfile.QUALITY_TIME_LAPSE_LOW &&
            profile.quality <= CamcorderProfile.QUALITY_TIME_LAPSE_QVGA) {
         // Nothing needs to be done. Call to setCaptureRate() enables
         // time lapse video recording.
        } else {
          setAudioEncodingBitRate(profile.audioBitRate);
          setAudioChannels(profile.audioChannels);
          setAudioSamplingRate(profile.audioSampleRate);
          setAudioEncoder(profile.audioCodec);
        }
      }
      

      例如它将 outputFormat、videoSize、encoder 和 frameRate 设置为配置文件中的值。所以你的代码:

      Log.i("xx","C");
      media_recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
      Log.i("xx","D");
      media_recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
      Log.i("xx","E");
      media_recorder.setVideoSize(320, 240);
      Log.i("xx","F");
      media_recorder.setVideoFrameRate(15);
      

      至少是无用的,也许在这些调用期间它会改变状态。尝试不使用它。

      【讨论】:

        【解决方案3】:

        发生这种情况是因为您无法在不调用 reset() 的情况下更改 MediaRecorder 中的值,因此您必须在 MediaRecorder 本身上设置所有内容(实际上您必须在 API 级别 8、Android 2.2 之前执行此操作)。

        或者,您可以基于例如创建自定义 CamcorderProfile。你想要什么,在那里进行更改并在 MediaRecorder 上设置该配置文件,如下所示:

            // establish the media recorder
            MediaRecorder media_recorder = new MediaRecorder();
            media_recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            media_recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        
            // Customise your profile based on a pre-existing profile
            CamcorderProfile profile = CamcorderProfile.get(CameraInfo.CAMERA_FACING_FRONT,CamcorderProfile.QUALITY_LOW);
            profile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
            profile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;
            profile.videoFrameHeight = 240;
            profile.videoFrameWidth = 320;
            profile.videoBitRate = 15;
        
            // Apply to MediaRecorder
            media_recorder.setProfile(profile);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-10
          • 1970-01-01
          • 1970-01-01
          • 2011-07-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多