Piping video with netcat behind NAT

I found an excellent tutorial by Zachary Bears on how to stream video from a Raspberry Pi over the network to another computer. His method works as long as the receiver (the ‘listening’ machine) has an IP address you can reach: either on the local network or a public IP. However, when both the sender and the receiver are behind separate NATs and not publicly accessible, it is no longer so simple to stream between them. Instead, we can pipe the data through a public server that both machines can reach. Below is how you do that.

I will assume you have read and understood Zachary’s tutorial.

Setting up the server

The server serves as a common location both the sender and the receiver can pipe the data through. For this example, the public IP will be 123.45.678.90. The server should listen on two ports: one for the Raspberry Pi to stream the video to and one for the other computer to download the video from. This is really easy to do with netcat:

nc -l 5001 | nc -l 5002

This will simply pipe all incoming data on port 5001 to output on port 5002 (using TCP) and vice versa.

It is worth pointing out that this is not secure. Anyone can access these ports. However, security is not discussed here.

Stream video from the Pi

You need to create a named pipe for the Pi to stream the video to:

mkfifo fifo.video

Then start streaming the video into the pipe:

/opt/vc/bin/raspivid -o fifo.video -t 0 -b 10000000

And send the data to the server using netcat:

cat fifo.video | nc 123.45.678.90 5001

Connecting to the video stream

Because of the way we set up the server, the Pi’s video will be available on port 5002. From any other machine, we can connect to this port by running:

nc 123.45.678.90 5002 | mplayer -cache 2048 -cache-min 1/2 -

And that’s it! It might take some seconds for the video to buffer, but it should then stream with very low latency (depending on your bandwidth, of course). Have fun!