我正在使用 FFmpeg 并且我制作了一个自定义应用程序,它是一个 TCP 服务器。我在 ffmpeg 中使用重复输出。
我想要的是,对于每个输出,我想启动我的程序以侦听特定端口。例如我现在可以做什么:
ffmpeg -i "stream_link" -codec copy -f mpegts - \
| myprogram -h 127.0.0.1 -p 12345 -f -
Run Code Online (Sandbox Code Playgroud)
我的程序从 ffmpeg 获取数据并将它们存储在服务器中。现在,我不能做以下事情
ffmpeg -i "stream_link" -codec copy -f mpegts - -codec copy -f flv - \
| myprogram -h 127.0.0.1 -p 12345 -f - \
| myprogram -h 127.0.0.1 -p 12345 -f -
Run Code Online (Sandbox Code Playgroud)
我想你得到了我。我正在尝试输出 2 个不同的容器 mpegts、flv 并再次打开我的程序的 2 个实例。那么我如何才能做到呢?
这个问题只与管道有关。我只是举了一个使用 FFmpeg 的真实例子。
ffmpeg -i "stream_link" -codec copy -f mpegts - -codec copy -f flv - |
myprogram -h 127.0.0.1 -p 12345 -f - |
myprogram -h 127.0.0.1 -p 12345 -f -
Run Code Online (Sandbox Code Playgroud)
因此,如果我理解正确,您正在尝试将这 2 个命令合二为一。
mpegts格式
ffmpeg -i "stream_link" -codec copy -f mpegts - |
myprogram -h 127.0.0.1 -p 12345 -f -
Run Code Online (Sandbox Code Playgroud)
flv格式
ffmpeg -i "stream_link" -codec copy -f flv - |
myprogram -h 127.0.0.1 -p 12345 -f -
Run Code Online (Sandbox Code Playgroud)
所以,如果我上面的理解是正确的,我相信你可以使用tee命令来完成它。您可以从这里的这个问题中获得更多详细信息。
所以,你可以将你的命令改写为,
ffmpeg -i "stream_link" -codec copy -f mpegts - -codec copy -f flv - |
tee >(myprogram -h 127.0.0.1 -p 12345 -f -)
>(myprogram -h 127.0.0.1 -p 12346 -f -)
Run Code Online (Sandbox Code Playgroud)
然而,正如用户mikeserv在他的评论中指出的那样,
ffmpeg正在将两个流写入一个文件。无论是mpegts和flv进入标准输出这是|管。
因此,解决方案必须涉及ffmpeg写入两个不同的文件。类似的东西,ffmpeg flv processing -o flvfile, mpegts processing -o mpegtsfile以及从两个输出读取的两个进程。
无论是那个还是接收输入的进程都必须解析ffmpeg的输出才能知道从哪个偏移量开始读取它们的预期流。
因此,该tee方法的问题在于tee可能会复制ffmpeg的输入并且ffmpeg可以使用两个。
因此,解决此问题的更好方法是使用该方法,
{ { ffmpeg -i "stream_link" #one input stream
-codec copy -f flv /dev/fd/3 #duped and processed, out >&3
-codec copy -f mpegts - | #duped and processed, out >&1
myprogram1 >&4 #receives >&1 on <&0, out >&4
} 3>&1 | myprogram2 #receives >&3 on <&0, out >&1
} 4>&1 #ensures both myprograms write to >&1
Run Code Online (Sandbox Code Playgroud)
当我们使用上述方法时,ffmpeg明确地拆分其输出。它确实取决于在理解/dev/fd/[num]链接的系统上运行。