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、如果单独设置不管用,请参考代码部分的完整代码设置。 

  • 相关阅读:
    Failure [INSTALL_FAILED_ALREADY_EXISTS]
    在CentOS 7上构建RAID5、LVM和SAMBAserver(5)——架设SAMBAserver
    adb命令具体解释(二)——手机缺失sqlite3时操作数据库的多种解决方式
    【环境配置】Linux的经常使用命令
    windowsclient开发--使你的client执行时记住上次关闭的大小和位置
    【13】以对象管理资源
    C++ 初始化与赋值
    C++ 变量初始化规则
    C++ 构造和析构
    【20】宁以pass-by-reference-to-const替换pass-by-value
  • 原文地址:https://www.cnblogs.com/over140/p/3811084.html
Copyright © 2011-2022 走看看