How to stream live video from a linux server?

I currently develop online streaming from 3 miniDV cameras connected via FireWire, which is quite similar to your needs.

Quick hint: vlc + flowplayer/jw player

First of all, there are two video formats, that you can use in online streaming: FLV and h264. FLV is easier to transcode, h264 has better size/quality ratio but transcoding is much more cpu consuming. Both can be displayed by flash players in web page.

Second of all, streaming infrastructure. Since your bandwith from laptop is limited (couple Mbps tops) you need to get stream to your server and there restream it to clients. So the stream will flow 1 time to server and then N times to clients from there. You haven't described your internet connection for your laptop, so the scenario is divided into two section:

  1. Laptop is connected with public IP address OR you can NAT port to laptop. This scenario is much easier, since you can connect from server to laptop nice and easy. Big disadvantage is, that you're bound to one location (one IP address).

  2. Laptop is not connected with public I address. This is little bit tricky, but will work from any network which will allow you to SSH to your server and have sufficiant upload (1 Mbps should do it).

Regardless on used scenario, the infrastructer will look like this

CAMERA - (usb) - LAPTOP - (network, limited upload) - SERVER - (network) - Client 0
                                                                         - Client 1
                                                                         - Client 2
                                                                         - Client N

Streaming from laptop

  1. Capture video from webcam. I've never captured stream from locally attached webcam, but there are many examples how to do it via V4L, e.g: Webcam Setup. The only part which you should be interested is:

    laptop$ vlc v4l:// :v4l-vdev="/dev/video0" :v4l-adev="/dev/audio2"

    Which is the first part of VLC command to connect to webcam. For more details follow the mentioned HOWTO. Especially look at "video group" part and correct device path to /dev/video and /dev/audio. Those can be different on your laptop.

  2. Transcode video to FLV. I personally use FLV, since it is less CPU demanding. Transcode string I use is this:

    --sout '#transcode{vcodec=FLV1,vb=512,acodec=mpga,ab=64,samplerate=44100}'

    Which will transcode video stream to FLV format with MPGA audio (MP3 is not available in my Ubuntu). Samplerate is somehow mandatory, it won't work without it. But you can choose smaller, like 22050. This will transcode video stream 'as is', so the scale is 1:1. You can append width and height parameters, or even scale parameter. Look into VLC documentation.

  3. Stream it from laptop. Now you have to make local stream, on which will server connect:

    :std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8081/stream.flv}

    This will bind VLC stream to 0.0.0.0:8081/stream.flv. The whole command will look like this:

    laptop$ vlc v4l:// :v4l-vdev="/dev/video0" :v4l-adev="/dev/audio2" --sout '#transcode{vcodec=FLV1,vb=512,acodec=mpga,ab=64,samplerate=44100}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8081/stream.flv}'

Restreaming on server

  1. Capture stream on server and restream it. Again, we use VLC to capture and stream. Usage is based on infrastructure scenario from early of this post. As I showed, VLC on laptop streams video on some port. This port has to be accesible from server. If you have public IP address of laptop, or NATed port, you can test it with telnet:

    server$ telnet public_ip_address 8081

    Anything except "connection timeout" will reveal, that you can connect to your laptop's stream. If you don't have public IP address, or you can't NAT port, you have to do it the other way around. You can SSH from laptop to server and remote forward your laptop port to server. The correct SSH command would be:

    laptop$ ssh your_user@server_ip_address -R 8081:127.0.0.1:8081

    This magic command will 'bind' your laptop port 8081, to server port 8081. That means when you connect on server to 8081, you will silently connect to your laptop port 8081 via SSH tunnel. Cool, huh?:) So all we have to do is simple VLC connect and stream:

    server$ vlc http://localhost:8081/stream.flv --sout '#std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8082/stream.flv}'

    Or in case with public IP adress or NATed port:

    server$ vlc http://public_ip_address:8081/stream.flv --sout '#std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8082/stream.flv}'

    As in the laptop part, your VLC on server is bind to port 8082. Why 8082 and not 8081? 8081 is already taken by the SSH remote forward. Why we don't use transcode part as in first example? The video is already in the right format, so all we have to do is just stream it as-is.

  2. Testing. In both examples, you can test functionality by viewing streams via VLC. You can test your local stream:

    laptop$ vlc http://localhost:8081/stream.flv

    And you can test your server's stream:

    laptop$ vlc http://server_ip_address:8082/stream.flv

    In both cases, you should see your webcam input.

Display stream on web

Displaying the stream on web, which will work in most cases, is via flash player. I tried two products, which are free for non-commercial usage: JW Player and Flowplayer. I stayed with Flowplayer, but I don't remember the reason, maybe because of plugins (which I don't use:) ) or because of better documentation.

How to display FLV stream from VLC in web page is covered here: Stream VLC to Website with asf and Flash

Troubleshooting

Be aware of many problems that WILL arise. First thing, as in everything, read. VLC is very chatty program, so it will tell you where the problem is. Could be problem with permissions to access the video/audio device, missing codecs, misspelled --sout parameters,... Learn to use iftop to see if the data really flows thru network, etc.


My tool of choice here would be vlc. It is not just a multi-purpose multi-format video player, it is also capable of streaming in a magnitude of file formats and streaming protocols. As a bonus, it works cross-platform among Windows and Linux hosts.

We've set up something similar a couple of years ago where a customer using a narrow-bandwidth DSL line (128 K upstream) needed to have his network-connected webcams streamed to a broad audience. A VLC installation as a "reflector" host did cam signal rotation, took the main bandwidth load from the streaming clients and presented the stream in different streaming protocols and formats.


Not really my area of expertise, but perhaps I can point you in a potential direction.

The commercial implementation is to use Adobe's Flash Media Server. Of course, that can be a rather costly approach. There are however, open source alternatives - such as Red5. You will need to install the server (it has Java dependencies).

Once you have the server running, you can pick your front-end (I believe Red5 comes with some samples, but you can also use JW Player with type=camera).

The front end will receive the streaming video from the media server, and you will upload your stream to the media server.

Further information: Red5 Help & Info and Red5 Reference