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

通过FFmpeg管道流式传输Firebase视频时遇文件偏移与moov atom缺失错误

问题:Firebase云存储视频经FFmpeg流式传输至HTML播放器的分段请求异常

问题表现

  • 浏览器无法识别视频实际时长,时长显示持续变动
  • 服务器端流式传输中断,抛出以下错误:
[NULL @ 000001d8c239e140] Invalid NAL unit size (110356 > 45446).
[NULL @ 000001d8c239e140] missing picture in access unit with size 45450
pipe:0: corrupt input packet in stream 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 000001d8c238c7c0] stream 0, offset 0x103fcf: partial file

后续还会出现:

[mov,mp4,m4a,3gp,3g2,mj2 @ 000001dc9590c7c0] moov atom not found
pipe:0: Invalid data found when processing input

仅前10秒左右的请求正常,当播放器请求如第5分钟片段时触发上述错误。

环境与核心代码

  • 运行环境:Node.js,无服务器环境,FFmpeg 5.0.1
  • 核心处理代码(精简版):
const filePath = `sample.mp4` ||  req.query.path;

// Create a read stream from the video file
const videoFile = bucket.file(filePath);

const range = req.headers.range;

if(!range){
  return res.status(500).json({mes: 'Not Found'});
}

// Get the file size for the 'Content-Length' header
const [metadata] = await videoFile.getMetadata();
const videoSize = metadata.size;

const CHUNK_SIZE = 1000000; // 1MB

const start = Number(range.replace(/\D/g, ""));
const end = Math.min(start + CHUNK_SIZE, videoSize - 1);

// Create headers
const contentLength = end - start + 1;
const headers = {
  "Content-Range": `bytes ${start}-${end}/${videoSize}`,
  "Accept-Ranges": "bytes",
  "Content-Length": contentLength,
  "Content-Type": "video/mp4",
  // 'Transfer-Encoding': 'chunked'
};

// HTTP Status 206 for Partial Content
res.writeHead(206, headers);

// create video read stream for this particular chunk
const inputStream = videoFile.createReadStream({ start, end });

const ffmpeg = spawn(pathToFfmpeg, [
  // '-re', '-y',  
  '-f', 'mp4',  
  '-i', 'pipe:0', // read input from standard input (pipe)
  '-c:v', 'copy', // copy video codec
  '-c:a', 'copy', // copy audio codec
  '-map_metadata', '0',
  `-movflags`, `frag_keyframe+empty_moov+faststart+default_base_moof`,
  '-f', 'mp4', // output format
  'pipe:1',
 // write output to standard output (pipe)
], {
  stdio: ['pipe', 'pipe', 'inherit']
});

inputStream.pipe(ffmpeg.stdin);

ffmpeg.stdout.pipe(res);

注:实际代码包含完整日志与错误处理逻辑。

已尝试的解决方案

  • 调整FFmpeg参数尝试修复moov atom错误,问题依旧:
-map_metadata', '0',
`-movflags`, `frag_keyframe+empty_moov+faststart+default_base_moof`
  • 尝试先将Firebase流写入本地文件,再通过管道传给FFmpeg,仍出现相同错误。

需求背景

需要为每个请求动态添加视频滤镜与水印,因此必须通过FFmpeg流处理视频,无法直接传输原文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:13:32