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

使用MediaSourceExtension(MSE)加载音频播放时长归零且无法播放求助

问题分析与解决方案

核心原因:MP4格式不兼容MSE要求

你当前用FFmpeg生成的是标准MP4,这类文件的moov原子(包含媒体元数据)在文件末尾,而MSE需要可流化的Fragmented MP4(fMP4)——即moov原子前置,且媒体数据被分割为可逐个加载的片段。这就是音频元素能识别时长,但无法播放的关键原因。

步骤1:修正FFmpeg命令生成兼容的fMP4

替换原FFmpeg命令为:

ffmpeg -i m.wav -c:a aac -b:a 32k -f mp4 -movflags frag_keyframe+empty_moov output.mp4

参数说明:

  • frag_keyframe:让每个关键帧对应一个媒体片段,适配流式加载逻辑
  • empty_moov:生成空的moov原子放在文件开头,确保MSE能提前解析元数据

步骤2:修正代码中的MIME类型

MSE要求明确指定编码格式,不能仅用audio/mp4,需补充codecs参数:

const sourceBuffer = mse.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"');

mp4a.40.2对应AAC-LC编码,和你用FFmpeg指定的aac编码完全匹配。

步骤3:确保加载完整的媒体数据

你代码中Uint8Array([0x00, 0x00, 0x00, 0x1C, 0x66, ...])如果只是截取的部分数据,会导致MSE无法解析完整媒体流。测试时建议直接加载完整的fMP4文件:

function msOpen(e) {
  URL.revokeObjectURL(ae.src);
  var mse = e.target;
  const sourceBuffer = mse.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"');
  
  // 加载完整的fragmented mp4文件
  fetch('output.mp4')
    .then(res => res.arrayBuffer())
    .then(buffer => {
      sourceBuffer.appendBuffer(buffer);
    });
  
  sourceBuffer.addEventListener('updateend', function() {
    if (!sourceBuffer.updating && mse.readyState === 'open') {
      mse.endOfStream();
      console.log('Audio is ready to play!');
    }
  });
}

额外说明

你遇到的播放中止错误,是因为调用endOfStream()后媒体资源被标记为已结束,再次播放时浏览器会认为资源已终止。在后续WebSocket直播场景中,你不需要调用endOfStream(),直到直播结束时再执行即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:25:18