MediaRecorder的几个常见坑

一、问题代码

private void initRecord() throws IOException {
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.reset();
        if (mCamera != null)
            mMediaRecorder.setCamera(mCamera);
        mMediaRecorder.setOnErrorListener(this);
        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
        mMediaRecorder.setVideoSource(VideoSource.CAMERA);// 视频源
        mMediaRecorder.setAudioSource(AudioSource.MIC);// 音频源
        mMediaRecorder.setVideoSize(mWidth, mHeight);// 设置分辨率:
        mMediaRecorder.setVideoFrameRate(16);// 这个我把它去掉了,感觉没什么用
        mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024 * 100);// 设置帧频率
        mMediaRecorder.setOrientationHint(90);// 输出旋转90度,保持竖屏录制

        mMediaRecorder.setOutputFormat(OutputFormat.MPEG_4);// 视频输出格式
        mMediaRecorder.setAudioEncoder(AudioEncoder.AMR_NB);// 音频格式
        mMediaRecorder.setVideoEncoder(VideoEncoder.MPEG_4_SP);// 视频录制格式

        // mediaRecorder.setMaxDuration(Constant.MAXVEDIOTIME * 1000);
        mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());

        mMediaRecorder.prepare();
        try {
            mMediaRecorder.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

二、问题解析及解决方案

1、start failed: -19

原因:设置的宽高数值必须要和摄像头支持的数值相匹配,否则报错
解决方法:
①把setVideoSize和setVideoFrameRate放到设置编码和格式的代码后面(亲测可行)
②不行就把setVideoSize和setVideoFrameRate注释掉

2、start failed: -38

原因:开始录像的时候,已经了开启录音,抢用麦克风了。
解决方法:把setAudioSource(AudioSource.MIC);换成setAudioSource(AudioSource.DEFAULT)

3、at android.media.MediaRecorder.setVideoSize(Native Method)

原因:setVideoSize是设置视频分辨率,跟设备硬件有关,若手机不支持则会报该错误。
解决方法:
①把setVideoSize和setVideoFrameRate放到设置编码和格式的代码后面(亲测可行)
②不行就把setVideoSize和setVideoFrameRate注释掉

4、at android.media.MediaRecorder.setOutputFormat(Native Method)

原因:
解决方法:
①如果代码中设置了setProfile,就把setProfile设置去掉
(
    // CamcorderProfile cProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);//可以提高视频质量
    // mMediaRecorder.setProfile(cProfile);
)
②更换视频格式(mp4报错就换3gp)

三、正常代码

贴一份可以在Android6.0上跑的代码(被注释的代码可以无视):

private void initRecord() throws IOException {
    mMediaRecorder = new MediaRecorder();
    try {
        mMediaRecorder.reset();
        if (mCamera != null)
            mMediaRecorder.setCamera(mCamera);
        mMediaRecorder.setOnErrorListener(this);
        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
        mMediaRecorder.setVideoSource(VideoSource.CAMERA);// 视频源
        mMediaRecorder.setAudioSource(AudioSource.DEFAULT);// 音频源率,然后就清晰了
        mMediaRecorder.setVideoEncodingBitRate(5*1024*1024);
        mMediaRecorder.setOrientationHint(90);// 输出旋转90度,保持竖屏录制
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 视频输出格式
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 音频格式
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);// 视频录制格式
        // 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
        mMediaRecorder.setVideoSize(320, 240);
        // 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错
        mMediaRecorder.setVideoFrameRate(20);

        // mediaRecorder.setMaxDuration(Constant.MAXVEDIOTIME * 1000);
        mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());

        mMediaRecorder.prepare();
    } catch (Exception e) {
        e.printStackTrace();
        releaseRecord();
    }
    try {
        mMediaRecorder.start();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (RuntimeException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

四、常见设置

1、编码格式设置
1) mp4
mMediaRecorder.setOutputFormat(OutputFormat.MPEG_4);// 视频输出格式
mMediaRecorder.setAudioEncoder(AudioEncoder.AMR_NB);// 音频格式
mMediaRecorder.setVideoEncoder(VideoEncoder.MPEG_4_SP);// 视频录制格式
2) 3gp
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// 视频输出格式
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);// 音频格式
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);// 视频录制格式
2、视频清晰度设置:
// 所说越大清晰度最高(但是我自己测试5*1024*1024是最清晰的)
mMediaRecorder.setVideoEncodingBitRate(5*1024*1024);
// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
mMediaRecorder.setVideoSize(240,320);
// 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错
mMediaRecorder.setVideoFrameRate(20);

五、开源控件

https://github.com/GitLqr/LQRViedoRecordView

### MediaRecorder 使用指南 #### 创建和初始化 `MediaRecorder` 实例 为了使用 `MediaRecorder` 进行音频或视频录制,首先需要创建一个 `MediaRecorder` 的实例并对其进行配置: ```java MediaRecorder mediaRecorder = new MediaRecorder(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); mediaRecorder.setOutputFile("/path/to/output/file.mp4"); mediaRecorder.prepare(); ``` 上述代码设置了音频源为麦克风输入、视频源为摄像头,并指定了输出格式为 MPEG-4 文件。编码器选择了 AMR-NB 编码用于音频流,而视频则采用 MPEG-4 SP 编码[^1]。 #### 处理录制完成事件 当达到预设的最大持续时间或文件大小限制时,可以通过重写 `onInfo()` 方法来捕获这些状态变化的信息: ```java @Override public void onInfo(MediaRecorder mr, int what, int extra) { switch(what){ case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED: // 到达最大时长后的逻辑处理 break; case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED: // 到达最大尺寸后的逻辑处理 break; } } ``` 此方法允许开发者定义特定条件下应采取的动作,比如停止录制或者提示用户保存当前进度等操作[^2]。 #### 关于为何选择 `MediaRecorder` 相较于其他技术方案如 ScriptProcessor 或者 AudioWorklet,在某些情况下选用 `MediaRecorder` 可以为用户提供更高质量的声音体验。特别是对于 Web 应用程序来说,它能够有效地捕捉来自用户的语音数据,并将其存储成常用的媒体格式(例如 WebM 和 PCM),从而便于后续分析或分享给他人[^3]。 #### Multimedia 团队的工作范围 Android 平台下的多媒体服务由专门团队负责开发和支持,该团队致力于优化整个流程中的各个环节——从声音收集到最后播放效果呈现。这不仅涉及到硬件层面的支持,还包括软件算法上的改进以确保最终产品可以稳定运行且具备良好的用户体验[^4]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值