如何将命令输出通过管道传输到多个程序

use*_*046 4 shell

我正在使用 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 的真实例子。

Ram*_*esh 6

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正在将两个流写入一个文件。无论是mpegtsflv进入标准输出这是|管。

因此,解决方案必须涉及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]链接的系统上运行。

  • 我做了一些编辑 - 起初只是因为 `\nl|pipe` 不起作用 - 你需要 `|pipe\nl`,但后来我想一些评论可能会有所帮助。很好的答案 - 我们*两次*都在考虑同样的事情。 (2认同)