使用 FFmpeg 试图做个人用的转码点播服务端, 但 mpegts 多个切片间音频偶尔不连续?
3 January 2025 at 00:16
lslqtz:
最近试着写了一份简单的个人用途的转码点播服务端, 完成了之前的想法, 它能把当前工作目录下的视频转为 m3u 切片用于点播. 主要是由于部分 BDMV 视频码率过高, 很难远程点播 NAS 上的内容. Jellyfin 等媒体库方案不在考虑范围.
为了实现浏览器 seek 的效果, 选择由服务端通过 PTS 时间点和 timeBase 来根据关键帧提前生成切片范围, 在请求对应切片后实时转码到 mpegts (并通过浏览器预缓冲避免播放卡顿).
但无论如何调节, 似乎偶尔都会出现音频不连续的问题, 转储后发现目标切片似乎时间和请求长度不完全一致, 调节多次参数仍未解决此问题 (为使切片有足够起始长度只测试到 muxdelay 方法可用, -ss/-t 放于输入之后似乎也无果, 包括 -start_at_zero 等的替代也都尝试过, 使用 hls 或 segment 的话较难控制自由点播进度).
由于 nodejs 服务端较难调用 FFmpeg API, 是用的 命令+管道 的方式. 在这种情况下, 有方法可以解决或规避此问题吗?
服务端的完整代码, 其中相关的代码如下:
let args = [
'-ss', startTimeStr,
'-t', durationTimeStr,
'-accurate_seek',
'-i', videoPath,
'-map', '0:v:0',
'-c:v', encoder,
'-b:v', String(bitrate),
'-bsf:v', 'h264_mp4toannexb',
'-avoid_negative_ts', 'make_zero',
'-start_at_zero',
'-muxdelay', delayTimeStr,
'-muxpreload', delayTimeStr,
'-f', 'mpegts',
'pipe:1'
];
请求方法:
m3u: http://127.0.0.1:8082/video/rttPlaylist?videoPath=1.mkv
segment: http://127.0.0.1:8002/video/rttSegment?videoPath=1.mkv&start=0.0000&duration=4.0000
(BTW: 其实大部分是 Gemini 写的.)