我正在使用一个程序,该程序在运行时连续将 MPEG-TS 视频数据写入文件。我预计它会连续运行很多天。
我想使用 ffmpeg 实时转码该视频数据。因此 .mts 文件不会持续增长,直到我用完硬盘空间,我试图让第一个程序写入命名管道并ffmpeg
从该管道读取。
我尝试这样做ffmpeg -i /tmp/test.mts -c:v libx264 test.mp4
,但似乎 ffmpeg 一旦到达管道末端就会退出,而不是等待新数据。例如,如果我启动程序,等待 30 秒,然后运行 ffmpeg,我只会输出大约 50 秒的视频。 (30秒+ffmpeg赶上的时间)
我已经设法让它工作了,ffmpeg -i pipe:0 -c:v libx264 test.mp4 < /tmp/test.mts
但这对我来说感觉有点老套,使用标准输入来做到这一点。有没有一种方法可以直接提供命名管道作为 ffmpeg 的输入,并让它在到达当前数据末尾后等待新数据?
谢谢!
答案1
只需从另一个地方打开该 fifo 进行写入(并保持打开状态)即可。例子:
在窗口中:
mkfifo /tmp/test.mts
exec 7<>/tmp/test.mts
ffmpeg -i /tmp/test.mts out.mp4
在另一个窗口中:
cat ... >/tmp/test.mts
cat ... >/tmp/test.mts
这个想法是,在所有打开管道进行写入的进程都将其关闭之前,读取器不会从管道接收到 EOF:
$ mkfifo /tmp/fifo
$ cat /tmp/fifo &
[1] 26437
$ exec 7>/tmp/fifo
$ echo yes >/tmp/fifo
yes
$ echo yes >/tmp/fifo
yes
$ echo yes >/tmp/fifo
yes
$ exec 7>&-
$
[1]+ Done cat /tmp/fifo
如果没有exec 7>/tmp/fifo
保持 的写入结束的打开句柄/tmp/fifo
,则cat
将会在第一个 后终止echo
。