MediaRecorder保存视频问题

发布于 2024-11-27 20:57:53 字数 5126 浏览 3 评论 0原文

几天来,我一直在试图找出与保存视频相关的一个模糊问题。我已将问题范围缩小到 MediaRecorder 的问题。问题是当您连续录制许多(15-30)个视频时。发生的情况是,在某个点(>10),当您开始录制(即 MediaRecorder.start())时发出的蜂鸣声停止。在 LogCat 中,AudioFlinger 会出现错误“ERROR/AudioTrack: AudioFlinger 无法创建曲目,状态: -12”。一旦发生这种情况,您仍然可以毫无问题地录制任意数量的视频,但是如果您按手机音量键,​​手机就会崩溃。

我认为这与保存视频特别相关的原因是我可以注释掉 MediaRecorder 的所有视频相关设置,然后仅录制音频,没有任何问题,并且代码/程序没有任何不同,

我已包含在我的手机上产生相同问题的代码(运行 2.2 的 Samsung Captivate)。那是我的实际视频录制器代码有所不同,该代码只是为了分享并专注于 MediaRecorder 视频保存问题。

如果您遇到过类似问题,请回复,如果您在手机上测试此代码并且没有任何问题,请告诉我。我知道这是一个电话/固件问题,如果您有可以运行的代码,请分享,

谢谢,

[code]

    public class Camcorder extends Activity implements SurfaceHolder.Callback {
    MediaRecorder mRecorder;
    SurfaceHolder mHolder;
    SurfaceView mSurfaceView; 
    String mOutputFileRoot = "/sdcard/Avid_";
    String mOutputFile; 
    String mFileExt = ".3gp"; 
    Integer cnt = 0; 
     private boolean mRecording = false; 

     /** Called when the activity is first created. */ 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
          super.onCreate(savedInstanceState); 
          requestWindowFeature(Window.FEATURE_NO_TITLE);
          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
          setContentView(R.layout.camcorder_preview); 

          mSurfaceView =  ((SurfaceView)findViewById(R.id.camera_preview));
          mHolder = mSurfaceView.getHolder();
          mHolder.addCallback(this);
          mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

     } 

     @Override 
     public boolean onKeyDown(int keyCode, KeyEvent event) 
     { 
         if (keyCode == KeyEvent.KEYCODE_SEARCH) 
         { 
          if (mRecording) { 
                stopRecording();
                //finish(); 
             if(mRecorder == null){
                    initMediaRecorder();
                    prepareMediaRecorder();
                    }
                mRecording = false;
            } else { 
                mRecording = true; 

                startRecording(); 
            } 
             return true; 
         } 
         return super.onKeyDown(keyCode, event); 
     }   

     public void surfaceCreated(SurfaceHolder holder) {
         mHolder = holder;
         initMediaRecorder();
         prepareMediaRecorder();

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        if(mHolder != null) mHolder = null; 
        if(mSurfaceView != null) mSurfaceView = null; 
    }

    public void initMediaRecorder(){

        mRecorder = new MediaRecorder();

        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
        mRecorder.setPreviewDisplay(mHolder.getSurface());
        mOutputFile = mOutputFileRoot + cnt.toString() + mFileExt;
        cnt += 1;
        mRecorder.setOutputFile(mOutputFile);

    }

    private void prepareMediaRecorder(){
        if (mRecorder != null) {
            try {
                mRecorder.prepare();
            } catch (IllegalStateException e) {
                Log.e("IllegalStateException", e.toString());
            } catch (IOException e) {
                Log.e("IOException", e.toString());
            }
        }
    } 

     public void startRecording()
     {
        mRecorder.start();
     }

     public void stopRecording()
     {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;   
     }

     @Override
     public void onPause(){
         if(mRecorder != null){
             mRecorder.reset();
             mRecorder.release();
             mRecorder = null; 
         }
         super.onPause();
     }
    }

[/code]

清单 。

    <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.CAMERA"></uses-permission>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></user-permission>
   </manifest> 

XML布局

    <FrameLayout 

      android:layout_width="fill_parent"
      android:layout_height="fill_parent">

     <SurfaceView android:id="@+id/camera_preview" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent"
            android:clickable="true" />

   </FrameLayout>
   </LinearLayout>

For several days I have been trying to figure out an obscure problem related to saving video. I have narrowed it down to an issue with MediaRecorder. The problem is when you record many (15-30) videos in a row. What happens is that at some point (>10) the BEEP sound that occurs when you start recording (i.e. MediaRecorder.start()) stops. In LogCat there will be an error from AudioFlinger "ERROR/AudioTrack: AudioFlinger could not create track, status:
-12". Once this has happen you can still record as many videos as you want without problem, BUT if you press the phones volume keys the phone will CRASH.

The reason that I think it is related specifically to saving video is that I can comment out all of the video related setup for the MediaRecorder and then record only audio without any problem and nothing else about the code/program is different.

I have included code that creates the same issue on my phone (Samsung Captivate running 2.2). Note that my actually video recorder code is different and that this code is simply to share and focus on the MediaRecorder video save issue.

If you have experienced a similar issue please respond, if you test this code on your phone and you don't have any problems please let me know as I have started to think it is a phone/firmware issue. If you have code that works and can share please do.

Thanks,

[code]

    public class Camcorder extends Activity implements SurfaceHolder.Callback {
    MediaRecorder mRecorder;
    SurfaceHolder mHolder;
    SurfaceView mSurfaceView; 
    String mOutputFileRoot = "/sdcard/Avid_";
    String mOutputFile; 
    String mFileExt = ".3gp"; 
    Integer cnt = 0; 
     private boolean mRecording = false; 

     /** Called when the activity is first created. */ 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
          super.onCreate(savedInstanceState); 
          requestWindowFeature(Window.FEATURE_NO_TITLE);
          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
          setContentView(R.layout.camcorder_preview); 

          mSurfaceView =  ((SurfaceView)findViewById(R.id.camera_preview));
          mHolder = mSurfaceView.getHolder();
          mHolder.addCallback(this);
          mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

     } 

     @Override 
     public boolean onKeyDown(int keyCode, KeyEvent event) 
     { 
         if (keyCode == KeyEvent.KEYCODE_SEARCH) 
         { 
          if (mRecording) { 
                stopRecording();
                //finish(); 
             if(mRecorder == null){
                    initMediaRecorder();
                    prepareMediaRecorder();
                    }
                mRecording = false;
            } else { 
                mRecording = true; 

                startRecording(); 
            } 
             return true; 
         } 
         return super.onKeyDown(keyCode, event); 
     }   

     public void surfaceCreated(SurfaceHolder holder) {
         mHolder = holder;
         initMediaRecorder();
         prepareMediaRecorder();

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        if(mHolder != null) mHolder = null; 
        if(mSurfaceView != null) mSurfaceView = null; 
    }

    public void initMediaRecorder(){

        mRecorder = new MediaRecorder();

        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
        mRecorder.setPreviewDisplay(mHolder.getSurface());
        mOutputFile = mOutputFileRoot + cnt.toString() + mFileExt;
        cnt += 1;
        mRecorder.setOutputFile(mOutputFile);

    }

    private void prepareMediaRecorder(){
        if (mRecorder != null) {
            try {
                mRecorder.prepare();
            } catch (IllegalStateException e) {
                Log.e("IllegalStateException", e.toString());
            } catch (IOException e) {
                Log.e("IOException", e.toString());
            }
        }
    } 

     public void startRecording()
     {
        mRecorder.start();
     }

     public void stopRecording()
     {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;   
     }

     @Override
     public void onPause(){
         if(mRecorder != null){
             mRecorder.reset();
             mRecorder.release();
             mRecorder = null; 
         }
         super.onPause();
     }
    }

[/code]

manifest

    <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.CAMERA"></uses-permission>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></user-permission>
   </manifest> 

xml layout

    <FrameLayout 

      android:layout_width="fill_parent"
      android:layout_height="fill_parent">

     <SurfaceView android:id="@+id/camera_preview" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent"
            android:clickable="true" />

   </FrameLayout>
   </LinearLayout>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沦落红尘 2024-12-04 20:57:53

似乎是手机或操作系统特有的问题。我现在已经在两部不同的手机上测试了上述代码和更复杂的录像机代码,但没有遇到上述问题。不幸的是我不知道这是电话还是操作系统。

经过更多测试,这似乎是 Android 2.2 的问题。在运行 2.2 的两部不同手机(Samsung Vibrant 和 Captivate)上会出现此问题。我已经在运行 2.1 和 2.1-update1 的单独手机(Samsung Vibrant)以及运行 2.3.1 的 HTC 上进行了测试,没有出现任何问题。

Appears to be a problem specific to the phone or operating system. I have now tested the above code and my more complex video recorder code on two different phone and I did not get the above issue. Unfortunately I do not know if it was phone or os.

After more testing it seems to be a problem with Android 2.2. On two different phones (Samsung Vibrant and Captivate) running 2.2 the problem occurs. I have tested it on a separate phone (Samsung Vibrant) running 2.1 and 2.1-update1 and an HTC running 2.3.1 and there was no problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文