You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MediaRecorder设置setMaxFileSize后MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING未触发问题

MediaRecorder自动分割文件时MAX_FILESIZE_APPROACHING未触发的问题解决

按照官方文档步骤配置MediaRecorder分割等大小文件时,常会遇到MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING回调从未触发,直接跳到MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED且后续停止输出的问题,以下是针对性的排查和解决方法:

可能原因及解决方案

1. 系统阈值逻辑偏差

MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING默认在文件大小达到设置值的90%时触发,但部分设备或Android版本存在阈值计算不准的情况。可以通过主动检查文件大小来兜底:

private static final long MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
private String currentOutputPath;
private MediaRecorder recorder;

// 初始化MediaRecorder时配置
recorder.setMaxFileSize(MAX_FILE_SIZE);
recorder.setOnInfoListener((mediaRecorder, what, extra) -> {
    if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
        // 兜底切换,避免录制中断
        switchToNextFile();
    } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING) {
        switchToNextFile();
    }
});

// 开启定时任务主动检查文件大小
new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        File currentFile = new File(currentOutputPath);
        if (currentFile.exists() && currentFile.length() >= MAX_FILE_SIZE * 0.85) {
            switchToNextFile();
            this.cancel(); // 切换后取消当前定时任务,新文件重新开启
        }
    }
}, 0, 1000); // 每秒检查一次

private void switchToNextFile() {
    try {
        currentOutputPath = getNextOutputFilePath(); // 自定义生成新文件路径
        recorder.setNextOutputFile(new File(currentOutputPath).getFD());
        // 为新文件开启定时检查
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                File newFile = new File(currentOutputPath);
                if (newFile.exists() && newFile.length() >= MAX_FILE_SIZE * 0.85) {
                    switchToNextFile();
                    this.cancel();
                }
            }
        }, 0, 1000);
    } catch (IOException e) {
        e.printStackTrace();
        // 异常时需处理录制中断逻辑
    }
}

2. Android版本兼容性问题

API 26以下的Android版本对setNextOutputFile()和文件大小回调的支持存在Bug,此时可以:

  • 放弃依赖系统回调,完全采用定时检查文件大小的方式触发切换
  • 升级项目的目标SDK版本至API 26+,使用更稳定的MediaRecorder实现

3. 编码/容器格式限制

部分视频编码(如H.264)或容器格式(如MP4)有帧对齐要求,导致文件大小无法精确触发接近阈值的回调:

  • 调整setMaxFileSize()的数值,避开帧大小的整数倍(比如设置为95MB而非100MB)
  • 更换为TS容器格式,它支持更灵活的文件分割,无需严格对齐帧边界

核心注意点

  • 调用setNextOutputFile()时必须确保新文件的文件描述符有效且未被其他进程占用
  • 切换文件后,旧文件会自动完成写入并关闭,无需手动调用stop()或reset()
  • 多次切换文件时需确保存储权限持续有效,避免因权限丢失导致录制中断

内容的提问来源于stack exchange,提问作者Juan Diana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:02:44