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

iOS Safari MediaRecorder录制无时长音频的时长添加方案咨询

iOS下MediaRecorder录制音频缺失时长元数据的解决方案

问题根源

iOS上MediaRecorder仅支持MP4容器(仅录音频时实际为M4A格式),但录制生成的文件会把包含时长信息的moov原子放在音频数据mdat原子之后,大部分播放器和系统无法读取这个位置的元数据,导致显示时长为0或未知。

解决方案一:用mp4box.js修复MP4结构

mp4box.js是专门处理MP4/M4A文件结构的工具库,可轻松调整原子位置并补全缺失的元数据。

修改后的代码示例

先引入mp4box.js(可下载本地文件引入,避免外链依赖),再调整录制完成后的处理逻辑:

let recorder;
let chunks;

document.querySelector("#stop").addEventListener("click", () => {
    recorder.stop();
});

document.querySelector("#start").addEventListener("click", async () => {
    const stream = await navigator.mediaDevices.getUserMedia({
        audio: true,
        video: false,
    });

    recorder = new MediaRecorder(stream);
    chunks = [];
  
    recorder.ondataavailable = function(e) { chunks.push(e.data); };
    recorder.onstop = async function() {
        const blob = new Blob(chunks, { type: recorder.mimeType });
        // 用mp4box处理录制的Blob
        const fileReader = new FileReader();
        fileReader.onload = function() {
            const arrayBuffer = this.result;
            const mp4File = MP4Box.createFile();
            mp4File.onError = (e) => console.error(e);
            mp4File.onReady = function(info) {
                // 调整moov原子到文件开头
                mp4File.setSegmentation();
                const segments = mp4File.initializeSegmentation();
                const newChunks = [];
                segments.forEach(seg => {
                    const buffer = mp4File.getSegmentData(seg);
                    newChunks.push(new Blob([buffer], { type: recorder.mimeType }));
                });
                // 生成修复后的音频Blob
                const fixedBlob = new Blob(newChunks, { type: recorder.mimeType });
                const url = window.URL.createObjectURL(fixedBlob);
                
                const a = document.createElement("a");
                a.href = url;
                a.download = "recording.m4a"; // 明确后缀为m4a更规范
                a.click();
                
                window.URL.revokeObjectURL(url);
            };
            mp4File.appendBuffer(new Uint8Array(arrayBuffer));
            mp4File.flush();
        };
        fileReader.readAsArrayBuffer(blob);
        
        for (const t of stream.getTracks()) {
            t.stop();
        }
    };
  
    recorder.start();
});

方案二:手动调整MP4原子结构(不推荐,仅作原理说明)

若不想依赖第三方库,需手动解析MP4容器结构:

  • 遍历文件定位moov和mdat原子的位置
  • 将moov原子移至文件开头
  • 更新stts(时间到样本映射)原子中的总时长信息
  • 修正所有原子的偏移量

该方法需对MP4格式有深入了解,代码复杂度高且易出错,优先推荐使用mp4box.js。

注意事项

  • iOS 14及以上版本才支持MediaRecorder的音频录制功能,需确保目标设备系统版本达标
  • 修复后的文件建议命名为.m4a后缀,避免部分系统识别异常

内容的提问来源于stack exchange,提问作者Luke Vo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:22:39