If you need to stream your audio/video content over the internet, you'll usually need a streaming (broadcasting) server, one of which is ffserver. It is able to collect multiple input sources (usually ffmpeg applications) and transcode/remux/broadcast each of them using multiple output streams. The simple diagram is shown on the image below:
Various input sources (ffmpeg applications) can be used to "feed" the broadcasting server (ffserver) with multimedia content that will be distributed to multiple clients for viewing. The purpose of the above image is to visually show the ability to separate parts of your streaming system into pieces that can be deployed around the world, allowing you to broadcast various live events without the need to change the structure of your streaming media system.
Let's take a closer look of ffserver, to better describe its possibilities. Consider the following image:
There are several elements shown on the image. Let's name them all first:
These elements are not part of internal structure of ffserver tool, but rather represent external applications (usually ffmpeg), which can send audio/video streams to ffserver that will be distributed (broadcast) to all the viewers (media players). Since ffmpeg is mostly used as an input source, we'll describe it here in this document.
Input sources will connect to ffserver and bind themselves with one or more feeds if those feeds are not bound with some other input source at that moment. Binding one input source to multiple feeds is possible and makes sense only if the input source can produce different stream input for each feed it is bound to. It's useless for the input source to provide the same stream input to several feeds, since ffserver already has got a way of associating a single feed to multiple output streams.
Feed element is an internal part of ffserver which has a purpose to associate one input source with one or more output streams. The possibility to associate a feed with more output streams is useful when you want to stream one input source (for example, your webcam with audio) using several different output formats (for example, streaming a full HD video and a small-size preview video for mobile phones) at the same time. Shortly speaking, each feed element logically represents each of your input sources. It can be considered as an "input jack" of ffserver, to which you connect your audio/video sources.
A stream element is internal part of ffserver and represents a connection point for all your viewers who wish to get a specific stream. For example, if you want to stream one full HD video and a small-size preview video for mobile phones, you will create one feed element (to connect your input to) and associate it with two stream elements (which will define different frame size, encoding type and/or output format). Each stream element can handle multiple connecting clients, just like one web server can handle multiple web clients. It can be considered as an "output jack" of ffserver, to which your viewers (media players) can connect to view your audio/video stream. The obvious difference between a feed element and a stream element (between input/output jack) is that a single stream element can handle multiple connections with viewers, while a single feed element is always connected to only one input source.
Media player elements are not internal part of ffserver. They just represent your viewers from the "outside world" that are connecting to the various stream elements to view your multimedia content. Some of the popular media players are: ffplay, VLC, Winamp, Windows Media Player, etc.
To be able to successfully start ffserver, you'll need a valid configuration file first. Once you create a valid config file, you can start ffserver simply by running the following command:
ffserver -f /etc/ffserver.conf
Depending on your configuration file, your ffserver will start or not :) But more often it will not start until you debug all the issues that usually occur, including syntax errors, so you'll most probably want to run your ffserver in debug mode with "-d" option, until you sort out everything, like this:
ffserver -d -f /etc/ffserver.conf
You can always get a full list of options with:
ffserver --help
When you finally build a valid configuration file, you'll want to run your ffserver in the background (as a daemon), which can be accomplished using either a trailing ampersand character (&) in a shell command or more conveniently you can comment out "NoDaemon" directive inside your config file (works on Windows too).
Once your ffserver is up and running, it's time to connect input sources to it. Without input sources, your ffserver is not going to broadcast anything to the outside world and will be pretty much useless. So, let's see how we can connect input sources to ffserver. The simplest way is to use the ffmpeg tool and the general syntax for such command is:
ffmpeg <inputs> <feed URL>
Of course, if you want to use one input source (ffmpeg) and bind it to multiple feeds (if you like to have only one application started), you might use:
ffmpeg <inputs> <feed URL> <more inputs> <another feed URL> <even more inputs> <yet another feed URL>
but, keep in mind that, if that input source crashes, all its bound feeds will become unavailable. So it's a good practice to use one input source (ffmpeg) pear each feed (1-1).
The parameter "<feed URL>" has got the following form:
http://<ffserver_ip_address_or_host_name>:<ffserver_port>/<feed_name>
All these things are defined in your ffserver configuration file:
Let's assume that we want to stream our webcam video + audio to our friends. We will simply run an ffmpeg command line that will capture our webcam video and audio input and forward it to ffserver. The command line will look something like this:
ffmpeg \ -f v4l2 -s 320x240 -r 25 -i /dev/video0 \ -f alsa -ac 1 -i hw:0 \ http://localhost:8090/feed1.ffm
This is the same thing as this:
ffmpeg -f v4l2 -s 320x240 -r 25 -i /dev/video0 -f alsa -ac 1 -i hw:0 http://localhost:8090/feed1.ffm
but it looks better and makes it more clear to understand each part of the command line.
As soon as you type the command above, you should see ffmpeg displaying some statistics about your input streams and counting output frames, which is a pretty good sign that everything works (so far).
For this example, you would need at least the following things defined in your config file (three dots "..." represent the other data that is irrelevant for this topic):
Port 8090 BindAddress 0.0.0.0 ... <Feed feed1.ffm> ... </Feed> ...
If you've done all the steps so far without errors, you're now ready to view your streams. The simplest way to do so is to use ffplay to connect to ffserver and view a specific stream. The general syntax for such command is:
ffplay <stream URL>
The parameter "<stream URL>" has got the following form:
http://<ffserver_ip_address_or_host_name>:<ffserver_port>/<stream_name>
All these things are defined in your ffserver configuration file:
For example if you have appropriate stream element defined in your ffserver configuration file, you could type:
ffplay http://localhost:8090/test1.mpg
and your stream should appear (depending on the encoding used and caching enforced) relatively shortly in a matter of seconds. In this example we used the host name "localhost" which means that everything is running on our computer, but if you need to view streams from the live online ffserver, you'll need to change the "localhost" to the real host name or IP address of ffserver computer.
For this example, you would need at least the following things defined in your config file (three dots "..." represent the other data that is irrelevant for this topic):
Port 8090 BindAddress 0.0.0.0 ... <Stream test1.mpg> ... </Stream> ...
It would be very wise to start off reading the ffserver's sample configuration file. It is self-documented with a lot of comments and it is a good starting point for beginners, since it contains various examples too. It would be a waste of time and space to write about it again here. Also, ffserver's documentation page might help too. In general, the configuration file is consisted of global directives, list of feed elements, list of stream elements and a specification of a special status stream element, which is used to provide a way for you to view the status of all your running streams.
Port 8090 BindAddress 0.0.0.0 MaxHTTPConnections 2000 MaxClients 1000 MaxBandwidth 1000 CustomLog - #NoDaemon <Feed feed1.ffm> File /tmp/feed1.ffm FileMaxSize 200K ACL allow 127.0.0.1 </Feed> # if you want to use mpegts format instead of flv # then change "live.flv" to "live.ts" # and also change "Format flv" to "Format mpegts" <Stream live.flv> Format flv Feed feed1.ffm VideoCodec libx264 VideoFrameRate 30 VideoBitRate 512 VideoSize 320x240 AVOptionVideo crf 23 AVOptionVideo preset medium # for more info on crf/preset options, type: x264 --help AVOptionVideo flags +global_header AudioCodec aac Strict -2 AudioBitRate 128 AudioChannels 2 AudioSampleRate 44100 AVOptionAudio flags +global_header </Stream> ################################################################## # Special streams ################################################################## <Stream stat.html> Format status # Only allow local people to get the status ACL allow localhost ACL allow 192.168.0.0 192.168.255.255 </Stream> # Redirect index.html to the appropriate site <Redirect index.html> URL http://www.ffmpeg.org/ </Redirect> ##################################################################
Port 8090 BindAddress 0.0.0.0 MaxHTTPConnections 2000 MaxClients 1000 MaxBandwidth 1000 CustomLog - #NoDaemon <Feed feed1.ffm> File /tmp/feed1.ffm FileMaxSize 200K ACL allow 127.0.0.1 </Feed> <Stream live.ogg> Format ogg Feed feed1.ffm VideoCodec libtheora VideoFrameRate 24 VideoBitRate 512 VideoSize 320x240 VideoQMin 1 VideoQMax 31 VideoGopSize 12 Preroll 0 AVOptionVideo flags +global_header AudioCodec libvorbis AudioBitRate 64 AudioChannels 2 AudioSampleRate 44100 AVOptionAudio flags +global_header </Stream> ################################################################## # Special streams ################################################################## <Stream stat.html> Format status # Only allow local people to get the status ACL allow localhost ACL allow 192.168.0.0 192.168.255.255 </Stream> # Redirect index.html to the appropriate site <Redirect index.html> URL http://www.ffmpeg.org/ </Redirect> ##################################################################