| 3 | | If you need to [http://en.wikipedia.org/wiki/Streaming_media stream your audio/video content over the internet], you'll usually need [http://en.wikipedia.org/wiki/List_of_streaming_media_systems#Servers a streaming (broadcasting) server], one of which is '''[http://ffmpeg.org/ffserver.html ffserver]'''. It is able to collect multiple input sources ('''feeds''') and transcode/remux/broadcast each of them using multiple outputs ('''streams'''). To better describe its possibilities, consider the following image: |
| | 3 | If you need to [http://en.wikipedia.org/wiki/Streaming_media stream your audio/video content over the internet], you'll usually need [http://en.wikipedia.org/wiki/List_of_streaming_media_systems#Servers a streaming (broadcasting) server], one of which is '''[http://ffmpeg.org/ffserver.html 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: |
| | 4 | |
| | 5 | [[Image(ffserver_map.png)]] |
| | 6 | |
| | 7 | 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. |
| | 8 | |
| | 9 | Let's take a closer look of ffserver, to better describe its possibilities. Consider the following image: |
| 25 | | 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 two stream elements with different frame size and possibly different encoding 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 can connect to view your audio/video stream. The obvious difference between a feed element and a stream element 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. |
| | 31 | 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. |
| 52 | | 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 perfectly useless. So, let's see how we can connect a couple of input sources to ffserver. |
| 53 | | |
| 54 | | The simplest way is to use ffmpeg tool. Let's assume that we want to stream our webcam video together with 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 will look something like this: |
| | 58 | 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: |
| | 59 | {{{ |
| | 60 | ffmpeg <inputs> <feed URL> |
| | 61 | }}} |
| | 62 | |
| | 63 | 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: |
| | 64 | {{{ |
| | 65 | ffmpeg <inputs> <feed URL> <more inputs> <another feed URL> <even more inputs> <yet another feed URL> |
| | 66 | }}} |
| | 67 | 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). |
| | 68 | |
| | 69 | The parameter "{{{<feed URL>}}}" has got the following form: |
| | 70 | {{{ |
| | 71 | http://<ffserver_ip_address_or_host_name>:<ffserver_port>/<feed_name> |
| | 72 | }}} |
| | 73 | |
| | 74 | All these things are defined in your ffserver configuration file: |
| | 75 | - '''{{{<ffserver_ip_address_or_host_name>}}}''' - using the "{{{BindAddress}}}" directive |
| | 76 | - '''{{{<ffserver_port>}}}''' - using the "{{{Port}}}" directive |
| | 77 | - '''{{{<feed_name>}}}''' - using the "{{{<Feed>}}}" block |
| | 78 | |
| | 79 | 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: |
| 67 | | The first part "'''{{{-f v4l2 -s 320x240 -r 25 -i /dev/video0}}}'''" captures our webcam input. For more info, you can read more about [[How to capture a webcam input]]. |
| 68 | | The second part "'''{{{-f alsa -ac 1 -i hw:0}}}'''" captures our audio input, depending on our audio configuration. For more info, you can read more about [[Capturing audio with FFmpeg and ALSA]]. |
| 69 | | The last, but not the least important, part is "'''{{{http://localhost:8090/feed1.ffm}}}'''", which tells ffmpeg to connect to the ffserver and send the audio+video streams to be broadcast. Make sure that your feed ends with ".ffm" and if it's not the case, then prepend "-f ffm" before your url, to manually specify the output format (because ffmpeg won't be able to figure it out automatically any more), like this "'''{{{-f ffm http://localhost:8090/blah.bleh}}}'''". |
| 70 | | |
| 71 | | As soon as you type that command, 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). |
| | 92 | * The first part "'''{{{-f v4l2 -s 320x240 -r 25 -i /dev/video0}}}'''" represents the first input for ffmpeg and captures our webcam video. For more info, you can read more about [[How to capture a webcam input]]. |
| | 93 | * The second part "'''{{{-f alsa -ac 1 -i hw:0}}}'''" represents the second input for ffmpeg and captures our audio, depending on our system audio configuration. For more info, you can read more about [[Capturing audio with FFmpeg and ALSA]]. |
| | 94 | * The last, but not the least important, part "'''{{{http://localhost:8090/feed1.ffm}}}'''" represents the feed URL, which tells ffmpeg to connect to ffserver and send it the audio + video streams for broadcast. Make sure that your feed ends with "{{{.ffm}}}" and if it's not the case, then add "{{{-f ffm}}}" before your feed URL, to manually specify the output format (because ffmpeg won't be able to figure it out automatically any more), like this "'''{{{-f ffm http://localhost:8090/blah.bleh}}}'''". |
| | 95 | |
| | 96 | 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). |
| | 97 | |
| | 98 | 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): |
| | 99 | {{{ |
| | 100 | Port 8090 |
| | 101 | BindAddress 0.0.0.0 |
| | 102 | |
| | 103 | ... |
| | 104 | |
| | 105 | <Feed feed1.ffm> |
| | 106 | |
| | 107 | ... |
| | 108 | |
| | 109 | </Feed> |
| | 110 | |
| | 111 | ... |
| | 112 | |
| | 113 | }}} |
| 75 | | 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, for example, like this: |
| | 117 | 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: |
| | 118 | {{{ |
| | 119 | ffplay <stream URL> |
| | 120 | }}} |
| | 121 | |
| | 122 | The parameter "{{{<stream URL>}}}" has got the following form: |
| | 123 | {{{ |
| | 124 | http://<ffserver_ip_address_or_host_name>:<ffserver_port>/<stream_name> |
| | 125 | }}} |
| | 126 | |
| | 127 | All these things are defined in your ffserver configuration file: |
| | 128 | - '''{{{<ffserver_ip_address_or_host_name>}}}''' - using the "{{{BindAddress}}}" directive |
| | 129 | - '''{{{<ffserver_port>}}}''' - using the "{{{Port}}}" directive |
| | 130 | - '''{{{<stream_name>}}}''' - using the "{{{<Stream>}}}" block |
| | 131 | |
| | 132 | For example if you have appropriate stream element defined in your ffserver configuration file, you could type: |