I have a capture process which writes raw video data and audio data to files. Something like this will capture 100 frames of data.
./capture -n 100 -f video_file -a audio_file
Giving me a 768000 bytes audio_file and a 414720000 bytes video_file. These seems to add up as expected:
Then when I encode that data like
ffmpeg -i audio_file -i video_file out.flv
I do get a playable video with sound (actually I have a lot more stuff in the command line, but those are the important parts for the purposes of this question)
Now, I actually want a live stream, not a file, and I can do this OK for just video with something like this:
./capture -f /dev/stdout | ffmpeg -i - udp://127.0.0.1:10000
I get a video stream with no audio broadcast on udp, and I was able to receive and play the stream ok. But when I want to add audio into the picture, I have some troubles.. I think I can not send them both on stdout, and I can't use stderr because the capture process chats on that already. So I have tried to do it with named pipes like this:
mkfifo audio_pipe
mkfifo video_pipe
ffmpeg -i audio_pipe -i video_pipe out.flv &
./capture -f video_pipe -a audio_pipe
But it is not working, it seems everything deadlocks. I have tested just running the ./capture -f video_file -a audio_file, and then opening two new shells and doing cat video_file > /dev/null and cat audio_file > /dev/null, once both cats are running this unblocks the capture process, so it seems it has no trouble writing to pipes. I had a peek at the source of the capture code, and the way it works is with a "frame arrived" callback from deeper the API which then goes and writes the video frame and audio data, in that order (it is blocking). I don't know what ffmpeg does, whether it reads the input video file or audio file sequentially, in either order, or reads them simultaneously in threads. I tried changing the order to ffmpeg -i video_pipe -i audio_pipe out.flv but unfortunately everything still locks. Using only one named pipes for video data works normally.
How can I solve my problem? I will script it with python subprocess module, once I understand how is the best way to avoid the blocking problem.
In Linux, the pipe buffer is limited to 65k, it's possible that you are ending up with a deadlock where capture won't write more audio until it can write more video, and ffmpeg won't read more video until it gets more audio.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With