I am trying to accomplish the following objectives:
- Write video from my Raspberry Pi Camera to disk without any interference from streaming
- Stream the same video through the network optimizing latency
It is important streaming does not interfere with the video being written to disk, since network connection may be unstable, such as WiFi router may be out of range, etc.
To accomplish that, the first thing I have tried is the following:
#Receiver side
FPS="30"
netcat -l -p 5000 | mplayer -vf scale -zoom -xy 1280 -fps $FPS -cache-min 50 -cache 1024 - &
#RPi side
FPS="30"
mkfifo netcat_fifo
raspivid -t 0 -md 5 -fps $FPS -o - | tee --output-error=warn netcat_fifo > $video_out &
cat netcat_fifo | netcat -v 192.168.0.101 5000 &> $netcat_log &
And the streaming works very well. However, when I switch off the router, simulating a problem with the network, my $video_out is cut. I think this is due to the back-pressure from the netcat_fifo.
I found a solution here at stackexchange concerning a non-blocking FIFO, by replacing tee by ftee:
Linux non-blocking fifo (on demand logging)
It now prevents my $video_out from being affected by the streaming, but the streaming itself is very unstable. The best results were using the following script:
#RPi side
FPS="30"
MULTIPIPE="ftee"
mkfifo netcat_fifo
raspivid -t 0 -md 5 -fps $FPS -o - | ./${MULTIPIPE} netcat_fifo > $video_out &
cat netcat_fifo | mbuffer --direct -t -s 2k 2> $mbuffer_log | netcat -v 192.168.0.101 5000 &> $netcat_log &
When I check the mbuffer log, I diagnose a FIFO that remains most of the time empty, but has peaks of 99-100% utilization. During these peaks, my mplayer receiver-side has many errors decoding the video and takes about 5 seconds to recover itself. After this interval, the mbuffer log shows again an empty FIFO. The empty->full->empty goes on and on.
I have two questions:
- Am I using the correct approach to solve my problem?
- If so, how could I render my streaming more robust while keeping the $video_out file intact?