FFmpeg Wasm转码MP4在Android播放出现ERR_REQUEST_RANGE_NOT_SATISFIABLE错误
解决Android Chrome播放转码视频出现ERR_REQUEST_RANGE_NOT_SATISFIABLE的思路
核心原因
该错误本质是视频文件的元数据索引(MP4格式的moov atom)位置不符合Android Chrome的播放要求,或者浏览器无法对当前视频资源发起范围请求。默认转码生成的MP4会把moov块放在文件末尾,Android Chrome需要开头就能读取到元数据,因此触发范围请求失败。
1. 强制FFmpeg将moov atom前置
修改FFmpeg转码命令,添加-movflags faststart参数,该参数会把MP4的元数据移至文件开头,让浏览器能快速获取播放所需的索引:
await ffmpeg.run('-i', name, '-codec', 'copy', '-movflags', 'faststart', '-preset', 'superfast', '-crf', '27', 'output.mp4');
如果之前用-codec copy直接复制流,这个方案无需重新编码,耗时极低,是最直接的修复手段。
2. 重新编码为Android兼容的标准格式
若源WebM的编码(如VP9)在Android上兼容性较差,即使复制流也可能导致播放异常,此时需明确指定编码器,输出Android原生支持的H.264视频+AAC音频:
await ffmpeg.run('-i', name, '-c:v', 'libx264', '-c:a', 'aac', '-movflags', 'faststart', '-preset', 'superfast', '-crf', '27', 'output.mp4');
替换-codec copy为明确的编码器配置,确保输出MP4完全符合Android播放标准。
3. 用MediaSource替代Blob URL加载视频
部分移动浏览器对Blob URL的范围请求支持有限,改用MediaSource API加载视频流,可灵活处理播放需求:
const transcode = async (webcamData) => { const name = 'record.webm'; ffmpeg.FS('writeFile', name, await fetchFile(webcamData)); await ffmpeg.run('-i', name, '-c:v', 'libx264', '-c:a', 'aac', '-movflags', 'faststart', '-preset', 'superfast', '-crf', '27', 'output.mp4'); const data = ffmpeg.FS('readFile', 'output.mp4'); const video = document.getElementById('vidpreview'); const mediaSource = new MediaSource(); video.src = URL.createObjectURL(mediaSource); mediaSource.addEventListener('sourceopen', () => { // 对应H.264/AAC的codecs参数 const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'); sourceBuffer.appendBuffer(data.buffer); }); document.getElementById('viddiv').classList.add("show"); vidpreview.onloadeddata = function () { playBtn.addEventListener('click', playVidAgain); } }
MediaSource会处理视频数据的分段加载,规避Blob URL的范围请求限制。
4. 更新FFmpeg Wasm版本
旧版本的FFmpeg Wasm可能存在转码兼容性bug,检查并升级到最新稳定版,可解决部分底层编码格式问题。
内容的提问来源于stack exchange,提问作者heroicsatsuma
相关产品推荐
相关产品推荐

