Video Streaming using Netcat

Having messed about a bit with a WebCam a bit I decided to see if how easily I could stream a video on one machine to another, as simply as possible.

To do this I decided to use ‘netcat’ which is a really useful swiss army knife of a utility that can be abused in lots of different ways. When receiving data ‘netcat’ simply listens for an incoming connection, it does not attempt to do any sort of authentication, so you should be careful where you use it! To encode the video stream I decided to use ‘mencoder’ – installing ‘mencoder’ automatically installs ‘mplayer’ which we will use to play the video streams.

First I installed both ‘mencoder’ and ‘netcat’ on both machines.

$ su
Password:

OR

$ sudo -i
Password:

# apt-get install mencoder
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  esound-common libasyncns0 libaudiofile1 libavcodec53 libavformat53
  libavutil51 libdca0 libdirac-encoder0 libdirectfb-1.2-9 libdvdnav4
  libdvdread4 libenca0 libesd0 libfaad2 libfribidi0 libgif4 libgsm1
  libjson0 liblircclient0 liblzo2-2 libmp3lame0 libmpeg2-4
  libopenal-data libopenal1 libopenjpeg2 libpostproc52 libpulse0
  librtmp0 libschroedinger-1.0-0 libsdl1.2debian libsndfile1
  libsvga1 libswscale2 libts-0.0-0 libva1 libvdpau1 libvpx1
  libx264-123 libx86-1 libxvidcore4 mplayer tsconf
Suggested packages:
  libdvdcss2 pulseaudio-esound-compat lirc libportaudio2
  libroar-compat2 pulseaudio nvidia-vdpau-driver vdpau-driver bzip2
  mplayer-doc ttf-freefont netselect fping
The following NEW packages will be installed:
  esound-common libasyncns0 libaudiofile1 libavcodec53 libavformat53
  libavutil51 libdca0 libdirac-encoder0 libdirectfb-1.2-9 libdvdnav4
  libdvdread4 libenca0 libesd0 libfaad2 libfribidi0 libgif4 libgsm1
  libjson0 liblircclient0 liblzo2-2 libmp3lame0 libmpeg2-4
  libopenal-data libopenal1 libopenjpeg2 libpostproc52 libpulse0
  librtmp0 libschroedinger-1.0-0 libsdl1.2debian libsndfile1
  libsvga1 libswscale2 libts-0.0-0 libva1 libvdpau1 libvpx1
  libx264-123 libx86-1 libxvidcore4 mencoder mplayer tsconf
0 upgraded, 43 newly installed, 0 to remove and 0 not upgraded.
Need to get 14.7 MB of archives.
After this operation, 43.7 MB of additional disk space will be used.
Do you want to continue [Y/n]? 
  :
  :
  :
Setting up mplayer (2:1.0~rc4.dfsg1+svn34540-1+b2) ...
Setting up mencoder (2:1.0~rc4.dfsg1+svn34540-1+b2) ...

# apt-get install netcat
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  netcat
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 8,774 B of archives.
After this operation, 32.8 kB of additional disk space will be used.
  :
  :
  :
Setting up netcat (1.10-40) ...

If you have a firewall enabled you will also need to allow inbound UDP connections on the machine that is to receive the video stream.

Note - You will need to specify the IP address of the machine that will be sending the video stream instead of nnn.nnn.nnn.s in the following commands. I've also used port 8086, but you can use any unused port you want in the range 1024 - 65535.

# ufw allow proto udp from nnn.nnn.nnn.s/24 to any port 8086
Rule added

Then exit on both machines.

# exit

On the machine that is to receive the video stream you need to start 'netcat', have it listen to the incoming port and pass any incoming data to 'mplayer', in this case I've also selected UDP rather than TCP.

Note - You will need to cache the incoming stream for mplayer to work, initially this will result in a some lag but it doesn't take long for the playback to catch up.

$ nc -l -u -p 8086 nnn.nnn.nnn.s | mplayer - -cache 1024
MPlayer2 UNKNOWN (C) 2000-2012 MPlayer Team
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing -.
Reading from stdin...
Cache fill:  0.00% (0 bytes)

Once 'mplayer' has started and is waiting for the cache to fill up, we can use 'mencoder' on the source machine to capture the video from a webcam, encode it into an mpeg stream, and then pass the resulting video stream to 'netcat' which will send it over the network to the listening machine...

$ mencoder tv:// \
> -tv driver=v4l2:width=640:height=480:fps=20:device=/dev/video0 \
> -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=2000 -nosound \
> -of avi -o - |netcat -u 192.168.16.166 8086
v4l2: ioctl set format failed: Invalid argument
tv.c: norm_from_string(pal): Bogus norm parameter, setting default.
v4l2: ioctl enum norm failed: Invalid argument
Error: Cannot set norm!
Selected input hasn't got a tuner!
v4l2: ioctl set mute failed: Invalid argument
v4l2: ioctl query control failed: Invalid argument
Forcing audio preload to 0, max pts correction to 0.
7 duplicate frame(s)!
Skipping frame!
Skipping frame!

Provided we have got all the IP addresses and port numbers correct, 'mplayer' will start to receive the video stream and when the cache is full start to play it.

MPlayer svn r34540 (Debian), built with gcc-4.7 (C) 2000-2012 MPlayer Team
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing -.
Reading from stdin...
Cache fill: 18.09% (189679 bytes)   

libavformat version 53.21.1 (external)
Mismatching header version 53.19.0
libavformat file format detected.
[m4v @ 0xb6bcd700]max_analyze_duration reached
[m4v @ 0xb6bcd700]Estimating duration from bitrate, this may be inaccurate
[lavf] stream 0: video (mpeg4), -vid 0
VIDEO:  [MP4V]  640x480  0bpp  25.000 fps    0.0 kbps ( 0.0 kbyte/s)
Load subtitles in ./
Cache not responding! [performance issue]
Cache not responding! [performance issue]
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
libavcodec version 53.35.0 (external)
Mismatching header version 53.32.2
Unsupported PixelFormat 61
Unsupported PixelFormat 53
Unsupported PixelFormat 81
Selected video codec: [ffodivx] vfm: ffmpeg (FFmpeg MPEG-4)
==========================================================================
Audio: no sound
Starting playback...

Streaming video from a Raspberry Pi

As before we will install 'mencoder' and 'netcat', although you can skip the installation of 'mencoder', as although the Raspberry Pi does support v4l2 I found that I could not use 'mencoder' to capture a video stream.

# su
Password: 
# apt-get install mencoder
Reading package lists... Done
Building dependency tree        
Reading state information... Done
The following extra packages will be installed:
  esound-common fontconfig-config libaa1 libasyncns0 libaudiofile1
  libbluray1 libcaca0 libcap2 libcdparanoia0 libdca0 libdirectfb-1.2-9
  libdrm2 libdvdnav4 libdvdread4 libenca0 libesd0 libfaad2 libflac8
  libfontconfig1 libfreetype6 libfribidi0 libgif4 libgl1-mesa-glx
  libglapi-mesa libice6 libjack-jackd2-0 libjson0 liblircclient0
  liblzo2-2 libmpeg2-4 libopenal-data libopenal1 libpng12-0
  libpostproc52 libpulse0 libsdl1.2debian libsm6 libsmbclient
  libsndfile1 libswscale2 libtalloc2 libtdb1 libts-0.0-0
  libwbclient0 libx11-6 libx11-data libx11-xcb1 libxau6 libxcb-glx0
  libxcb1 libxdamage1 libxdmcp6 libxext6 libxfixes3 libxi6
  libxinerama1 libxtst6 libxv1 libxvmc1 libxxf86dga1 libxxf86vm1
  mplayer tsconf ttf-dejavu-core x11-common
Suggested packages:
  libbluray-bdj libdvdcss2 pulseaudio-esound-compat jackd2 lirc
  libportaudio2 libroar-compat2 pulseaudio bzip2 fontconfig mplayer-doc
  ttf-freefont netselect fping
Recommended packages:
  libaacs0 libgl1-mesa-dri
The following NEW packages will be installed:
  esound-common fontconfig-config libaa1 libasyncns0 libaudiofile1
  libbluray1 libcaca0 libcap2 libcdparanoia0 libdca0 libdirectfb-1.2-9
  libdrm2 libdvdnav4 libdvdread4 libenca0 libesd0 libfaad2 libflac8
  libfontconfig1 libfreetype6 libfribidi0 libgif4 libgl1-mesa-glx
  libglapi-mesa libice6 libjack-jackd2-0 libjson0 liblircclient0
  liblzo2-2 libmpeg2-4 libopenal-data libopenal1 libpng12-0
  libpostproc52 libpulse0 libsdl1.2debian libsm6 libsmbclient
  libsndfile1 libswscale2 libtalloc2 libtdb1 libts-0.0-0
  libwbclient0 libx11-6 libx11-data libx11-xcb1 libxau6 libxcb-glx0
  libxcb1 libxdamage1 libxdmcp6 libxext6 libxfixes3 libxi6
  libxinerama1 libxtst6 libxv1 libxvmc1 libxxf86dga1 libxxf86vm1
  mencoder mplayer tsconf ttf-dejavu-core x11-common
0 upgraded, 66 newly installed, 0 to remove and 0 not upgraded.
Need to get 13.8 MB of archives.
After this operation, 33.2 MB of additional disk space will be used.
Do you want to continue [Y/n]? 
  :
  :
  :
Fetched 13.8 MB in 33s (416 kB/s)
Extracting templates from packages: 100%
Preconfiguring packages ...
  :
  :
  :
Setting up mplayer (2:1.0~rc4.dfsg1+svn34540-1) ...
Setting up mencoder (2:1.0~rc4.dfsg1+svn34540-1) ...

# apt-get install netcat --no-install-recommends
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  netcat
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 8,774 B of archives.
After this operation, 32.8 kB of additional disk space will be used.
  :
  :
  :
Fetched 8,774 B in 5s (1,578 B/s)
Selecting previously unselected package netcat.
(Reading database ... 19060 files and directories currently installed.)
Unpacking netcat (from .../netcat_1.10-40_all.deb) ...
Setting up netcat (1.10-40) ...

# exit

As before you need to start a process to listen for the incoming video stream using 'netcat' first...

$ nc -l -u -p 8086 192.168.16.181 | mplayer - -fps 20 -cache 1024

Note - Unless you specify the number of frames per second 'mplayer' will have difficulty playing an H264 video stream.

The current versions of Raspbain 'wheezy' do include v4l2 (Video for Linux) support, so in theory you could use 'mencoder' to capture mpg4 video as before - however I found that this didn't work on my Raspberry Pi model B. Unfortunately after repeated 'video buffer full - dropping frame' error messages from 'mencoder' it crashed and the whole machine had to be rebooted.

However, since 'mplayer' can play H264 video streams as well as mpg4 we can use the Raspberry Pi video utility 'raspivid' to stream a raw H264 video from the Raspberry Pi's camera module instead.

$ raspivid -n -w 854 -h 480 -fps 20 -t 9999999 -o - | \
> nc -u 192.168.16.166 8086

Raspberry Pi is a trademark of the Raspberry Pi Foundation

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s