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

Node.js中使用FFmpeg Spawn将MP4转HLS时,如何实现TS分段输出流与stdio流的管道传输?

Node.js中使用FFmpeg Spawn将MP4转HLS时,如何实现TS分段输出流与stdio流的管道传输?

我最近在Node.js里搭建一个自动化媒体处理流水线,流程是先压缩MP4文件,拿到压缩后的文件Buffer,再传给另一个FFmpeg命令,把它转成HLS格式的.m3u8文件。

但现在遇到了一个棘手的问题:没法把生成的TS分段文件的数据流直接通过管道传输到云存储——毕竟这是云函数环境,根本不能把文件存到磁盘上。

目前的困境是:

  • 要么只能在内存目录里生成TS分段文件,再基于它们生成播放清单;
  • 要么就得到一个把TS二进制数据和.m3u8清单数据混在一起的大Buffer。
    本地环境里存磁盘的话一切正常,但云函数完全走不通。

我现在用的FFmpeg转换命令是这样的:

const ffmpeg = spawn(
  "ffmpeg",
  [
    "-i",
    `pipe:0`,
    "-codec",
    "copy",
    "-start_number",
    "0",
    "-hls_time",
    "10",
    "-hls_list_size",
    "0",
    "-f",
    "hls",
    "-hls_flags",
    "delete_segments",
    "pipe:1",
  ],
  { stdio: ["pipe", "pipe", "pipe", "pipe"] }
);

我是把输入Buffer写到FFmpeg的stdin里的。试了各种方法后发现,只有加上delete_segments这个flag,才能避免生成物理TS文件,同时还不会触发EPIPE错误(之前直接把分段输出到stdout时一直报这个错)。之后我监听stdout的流,得到的是一个包含所有TS二进制数据和.m3u8清单数据的大Buffer——清单是UTF-8编码的,我能把它解析出来。

哪怕我手动把TS的Buffer解析出来上传成Blob,再把云存储的下载URL替换到清单里对应TS文件的位置,整个HLS流还是没法正常工作。

如果有需要,我可以补充更多细节~


更新:找到可行解决方案

后来我找到了一个靠谱的解决办法,和之前收到的一条评论思路一致,分享给大家:

  • 合并FFmpeg命令:不再启动多个FFmpeg子进程,而是把压缩参数和HLS转换参数合并到一个命令里,这样就不用手动把Buffer存在内存再传给下一个FFmpeg进程了。
  • 手动配置编码参数:我手动设置了视频的比特率、最大缓冲区大小,同时重新编码了音频。之前试过自适应比特率流,不过我的场景暂时用不上,以后需要的话再加也没问题。
  • 实时监听并处理TS文件:在FFmpeg运行的时候,我用Chokidar做了文件监听——每生成一个TS文件,就立刻上传到云存储,然后删除本地文件,这样能最大限度减少云环境里的内存占用。
  • 替换清单中的文件路径:我把每个TS文件对应的云存储下载URL存在一个Map里,key就是分段文件名。等清单文件生成后,再把里面的分段文件名逐个替换成对应的下载URL。

如果有人想看具体的代码或者完整的FFmpeg命令,可以告诉我~

备注:内容来源于stack exchange,提问作者Jacob L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:39:53