zoukankan      html  css  js  c++  java
  • 【Android】用MediaRecorder录制视频太短崩的问题


    具体表现:

    调用MediaRecorder的start()与stop()间隔不能小于1秒(有时候大于1秒也崩),否则必崩。

    错误信息:

    java.lang.RuntimeException: stop failed.

     at android.media.MediaRecorder.stop(Native Method)


    解决办法:

    在stop以前调用setOnErrorListener(null);就行了!

    相关代码:

        /** 开始录制 */
        @Override
        public MediaPart startRecord() {
            if (mMediaObject != null && mSurfaceHolder != null && !mRecording) {
                MediaPart result = mMediaObject.buildMediaPart(mCameraId, ".mp4");

                try {
                    if (mMediaRecorder == null) {
                        mMediaRecorder = new MediaRecorder();
                        mMediaRecorder.setOnErrorListener(this);
                    } else {
                        mMediaRecorder.reset();
                    }

                    // Step 1: Unlock and set camera to MediaRecorder
                    camera.unlock();
                    mMediaRecorder.setCamera(camera);
                    mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

                    // Step 2: Set sources
                    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);//before setOutputFormat()
                    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//before setOutputFormat()

                    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

                    //设置视频输出的格式和编码
                    CamcorderProfile mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
                    //                mMediaRecorder.setProfile(mProfile);
                    mMediaRecorder.setVideoSize(640, 480);//after setVideoSource(),after setOutFormat()
                    mMediaRecorder.setAudioEncodingBitRate(44100);
                    if (mProfile.videoBitRate > 2 * 1024 * 1024)
                        mMediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);
                    else
                        mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate);
                    mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);//after setVideoSource(),after setOutFormat()

                    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//after setOutputFormat()
                    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//after setOutputFormat()

                    
    //mMediaRecorder.setVideoEncodingBitRate(800);

                    
    // Step 4: Set output file
                    mMediaRecorder.setOutputFile(result.mediaPath);

                    // Step 5: Set the preview output
                    
    //                mMediaRecorder.setOrientationHint(90);//加了HTC的手机会有问题

                    Log.e("Yixia", "OutputFile:" + result.mediaPath);

                    mMediaRecorder.prepare();
                    mMediaRecorder.start();
                    mRecording = true;
                    return result;
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                    Log.e("Yixia", "startRecord", e);
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e("Yixia", "startRecord", e);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e("Yixia", "startRecord", e);
                }
            }
            return null;
        }

        /** 停止录制 */
        @Override
        public void stopRecord() {
            long endTime = System.currentTimeMillis();
            if (mMediaRecorder != null) {
                //设置后不会崩
                mMediaRecorder.setOnErrorListener(null);
                mMediaRecorder.setPreviewDisplay(null);
                try {
                    mMediaRecorder.stop();
                } catch (IllegalStateException e) {
                    Log.w("Yixia", "stopRecord", e);
                } catch (RuntimeException e) {
                    Log.w("Yixia", "stopRecord", e);
                } catch (Exception e) {
                    Log.w("Yixia", "stopRecord", e);
                }
            }

            if (camera != null) {
                try {
                    camera.lock();
                } catch (RuntimeException e) {
                    Log.e("Yixia", "stopRecord", e);
                }
            }

            mRecording = false;
        }

        /** 释放资源 */
        @Override
        public void release() {
            super.release();
            if (mMediaRecorder != null) {
                mMediaRecorder.setOnErrorListener(null);
                try {
                    mMediaRecorder.release();
                } catch (IllegalStateException e) {
                    Log.w("Yixia", "stopRecord", e);
                } catch (Exception e) {
                    Log.w("Yixia", "stopRecord", e);
                }
            }
            mMediaRecorder = null;
        }

        @Override
        public void onError(MediaRecorder mr, int what, int extra) {
            try {
                if (mr != null)
                    mr.reset();
            } catch (IllegalStateException e) {
                Log.w("Yixia", "stopRecord", e);
            } catch (Exception e) {
                Log.w("Yixia", "stopRecord", e);
            }
            if (mOnErrorListener != null)
                mOnErrorListener.onVideoError(what, extra);
        }

    代码片段引自拍摄SDK Vitamio Recorder 2.0:http://www.cnblogs.com/over140/p/3704580.html

    结尾吐槽:

    1、这个bug太2了!!

    2、Instagram你是怎么发现的?! 

    后续补充:

    1、如果单独设置不管用,请参考代码部分的完整代码设置。 

  • 相关阅读:
    Android ANR异常解决方案
    数据结构之斐波那契查找
    数据结构之插值查找
    数据结构之折半查找
    Android Task 任务
    java中“==”号的运用
    php中向前台js中传送一个二维数组
    array_unique和array_flip 实现去重间的区别
    js new Date() 获取时间
    手机端html5触屏事件(touch事件)
  • 原文地址:https://www.cnblogs.com/over140/p/3811084.html
Copyright © 2011-2022 走看看