I'm using FFmpeg and I have made a custom application which is a TCP server. I 'm using duplicate output in ffmpeg.
What I want is, for each output I want to start my program to listen on a specific port. For example what I can do now:
ffmpeg -i "stream_link" -codec copy -f mpegts - \
| myprogram -h 127.0.0.1 -p 12345 -f -
My program takes the data from ffmpeg and stores them inside the server. Now, I CAN'T DO the following
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 -
I think you got me. I'm trying to output 2 different containers mpegts, flv and open again 2 instances of my program. So how I am able to do it?
This question is only pipe related. I just gave a real example using FFmpeg.
1 Answer 1
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 -
So If I understand correctly, you are tryithisng to combine these 2 commands into one.
mpegts format
ffmpeg -i "stream_link" -codec copy -f mpegts - |
myprogram -h 127.0.0.1 -p 12345 -f -
flv format
ffmpeg -i "stream_link" -codec copy -f flv - |
myprogram -h 127.0.0.1 -p 12345 -f -
So, if my above understanding is correct, I believe you can accomplish it using tee
command. You could get more details from this question here.
So, you could rephrase your command as,
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 -)
However, as user mikeserv points out in his comments,
ffmpeg
is writing two streams to one file. Both the mpegts
and the flv
go to stdout which is the |
pipe.
So, the solution would have to involve ffmpeg
writing to two distinct files.
something like, ffmpeg flv processing -o flvfile, mpegts processing -o mpegtsfile
and the two processes reading from the two outputs.
Either that or the process receiving the input would have to parse ffmpeg
's output to know at which offset to begin reading their intended streams.
So the problem with the tee
approach is that tee
could duplicate the ffmpeg
's input and two ffmpeg
could be used.
So a better solution to this problem would be to use the approach as,
{ { 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
When we use the above approach ffmpeg
explicitly splits its output. It does depend on being run on a system that understands the /dev/fd/[num]
links.
-
does this not send both containers to both
(myprogram...)
instances?mikeserv– mikeserv2014年10月18日 17:13:23 +00:00Commented Oct 18, 2014 at 17:13 -
@mikeserv, yeah. But isn't what the question is about? I believe the OP wanted to send the ffmpeg output to 2 processes. Or am I misinformed?Ramesh– Ramesh2014年10月18日 17:16:10 +00:00Commented Oct 18, 2014 at 17:16
-
1the wording there isn't exactly correct -
tee
doesn't split anything - it doubles it. So you can doecho "one output" | tee >(whole output here) >(whole output here) >whole_output_here
mikeserv– mikeserv2014年10月18日 17:40:00 +00:00Commented Oct 18, 2014 at 17:40 -
1Thanks @mikeserv. I have incorporated your comments. Let me know if it is fine and feel free to edit if you feel I have missed something.Ramesh– Ramesh2014年10月18日 18:29:34 +00:00Commented Oct 18, 2014 at 18:29
-
2I did a little edit - at first only because
\nl|pipe
doesn't work - you need|pipe\nl
, but then I figured some comments might help. Good answer - we were thinking the same thing both times.mikeserv– mikeserv2014年10月18日 18:53:52 +00:00Commented Oct 18, 2014 at 18:53
ptee
/pipexec
answer particularly.