Oct 07

FFserver Guide

Category: Linux,multimedia  tengo @ 9:10 am

This post is meant as a FAQ, an introductory guide and a general reference manual for  streaming video with ffmpeg‘s FFserver. It’s is mainly the stuff I found out while setting up ffserver myself, and fills in some bits the official docs leave out. It is in no way complete and a “work in progress”.

Of course, this here also refers to avserver, the forked version of ffmpeg now sailing under the avconv banner.

Be sure to use a very up-to-date version (and proper combination) of ffmpeg and ffserver. Refer to Compiling a recent ffmpeg for that. For Win32 / Win64 users: Yes, you can compile ffserver on Windows (using mingw) and No, I’ve got no precompiled binaries for you.

One note before you dive into it: I think FFserver is not really usable yet. Although spending hours getting it to work, my streams broke, stuttered or didn’t work at all. Until the developers get it right, look into vlc, which is similarly hard to get right but at least can produce usable streams. Comment on this post if your experience with or opinion towards FFserver differs.

Understanding the basic FFserver concept

The idea behind ffserver is that it acts as a deflector/repeater for stream data that it gets fed by an instance of ffmpeg. The feeder (ffmpeg) and the deflector/server (ffserver) can run on the same machine, or on two connected machines, based on your setup.

ffmpeg[ reads input video file -> transcodes -> sends to IP:Port ] —-> ffserver[ running on IP:Port -> receives data -> serves clients with received data]

ffmpeg, although seldomly used in classic transcoding scenarios, is able to transcode to multiple formats at once. This way, ffserver gets enabled to stream one source – transcoded into multiple formats by ffmpeg -as these multiple formats to clients.

ffmpeg and ffserver communicate via a “pseudo” file, in most cases named feed1.ffm, the default in the example config file. On connect, ffmpeg reads the parameters ffserver requests from ffserver’s feed1.ffm file, starts transcoding, and then relays resulting data to ffserver.

The FFserver’s status page, being mostly idle here, offering streams.

Configuring and starting ffserver itself

If you are on Debian and/or Ubuntu, and have the ffmpeg or avconv package installed, simply doing  $ avserver or $ ffserver should bring up a running instance of ffserver. Quickest way to check out what’s going on is to visit http://localhost:8090/stat.html then. The default config file has the web-interface configured and you can see that there’s also an index.html, for example. But it simply redirects to www.libav.org.
The actual config file is in /etc/avserver.conf or /etc/ffserver.conf respectively.

Ffserver is a bit like a broker, one that doesn’t do anything itself except receiving stuff and handing it out again. As such, ffserver expects a feed to come in. This feed then is locally buffered in a sort of socket, a .ffm file. The default config has such a socket file configured to be at /tmp/feed1.ffm, which is mentioned on the stat.html page. Go ahead and open the default config in an editor – it has lots of useful config templates which are commented out at the moment.

Common questions (and their answers)

Q: How does it work?
A: The official documentation can be found here: ffserver Documentation.

Q: Where can I get a sample ffserver config file ffserver.conf?
A: At the ffmpeg.org official website: here. But as it seems, not all Streams sections really work. See mytests below.

Q: I get an okay stream by connecting with mplayer. A few seconds or minutes into the stream, it breaks and stops.
A: Check if your ffserver logs an “invalid stream index” error. I think this means that the input video is corrupt at this point. ffserver passes it througzh and makes mplayer hickup and drop the stream. A curing hack would be to try a different video input file and checking if it runs through.

Q: I get “Unknown AudioCodec: mp3″ error when starting ffserver.
A: You’ve got an mp3 stream configured in your ffservcer.conf but your ffmpeg/ffserver version has changed names for mp3. Try setting AudioCodec to “libmp3lame”.

Q: What is Stream 0 or Stream 1?
A: Streams are counted up beginning at 0 in your config file, mostly Stream 0 is the Audio stream part embedded in a Stream and Stream 1 the video portion.

Q: I get “Codecs do not match for stream 0″. Or stream 1, etc.
A: This means ahh.. somehow ffserver dislikes your chosen bitrate. See it in the source. And: ffserver seems to be a bit inconsistent in parsing options from ffserver.conf, also try a ffserver restart or rearranging the order of Audio and Video declarations in your <Stream> section.

Q: I get “Codec bitrates do not match for stream 0″. Or stream 1, etc.
A: This means ahh.. somehow ffserver dislikes your chosen bitrate. See it in the source. And: ffserver seems to be a bit inconsistent in parsing options from ffserver.conf, also try a ffserver restart or rearranging the order of Audio and Video declarations in your <Stream> section.

Q: What formats/codecs/containers can ffserver handle/stream?
A: Should be all formats ffmpeg can Encode to: see > ffmpeg -formats for that

Q: May I indent stuff in the ffserver.conf config file for better readability?
A: Seems so. I’ve done it and it works.

Q: Is streaming from a file still broken?
A: As it seems it is still broken. One of the developers admits it is at least not working very well. So far, I haven’t got it working with a revision 20182 ffserver. Anyway, up-to-date SVN versions seem to break/fix it from time to time. Hints indicate that the 0.5 ffmpeg release is stable in that regard.

Q: What’s the official ffserver name/spelling?
A: Seems to be FFserver.

FFmpeg issues when feeding to FFserver

Q: I get the error: http://localhost:8090/feed1.ffm: I/O error occurred. Usually that means that input file is truncated and/or corrupted.
A: This error in most cases means that ffmpegis completely unable to connect to the feed1.ffm file in the first place. 1. Check if ffserver is really running. 2. Check if you typed the correct IP:Port. 3. Check if you can connect with your browser to http://localhost:8090/stat.html (if you set up this special stream).

Q: I get the error message: http://localhost:8090/feed1.ffm: Unknown format.
A: Usually this means your ffserver.conf file has contradicting settings for “MaxBandWidth” and stream bandwidth: for example:  input.avi (=1872kbps) > MaxBandWidth (=400kbps). via Try setting MaxBandWidth to a value that has enough headroom, like 10000 and test again.

Q: ffmpeg does not appear to be really doing something, and connecting to the resulting ffserver stream either caches a few % then breaks or doesn’t connect at all.
A: Check if your ffmpeg/transcoding machine is fast enough to handle the transcoding, try lowering the input video’s quality, reduce the transcoding work by leveling source format and destination stream format or migrate to a bigger CPU.

Q: I get “rc buffer underflow” error when ffmpeg starts encoding and feeding to ffserver.
A: If we can believe this post from 2005, this is no error and occurs on the beginning of encoding. Also might be related to this, also from 2005. My experience: ignore it.

Whishlist (things I think are missing in FFserver)

  • Even out hickups in incoming feeds/streams (which currently lead to clients loosing connection)
  • HTTP-Live-Streaming,  see RFC (currently only Apple’s and Wowza’s server have an implmenetation)
  • Ogg-Video Streaming (.ogg audio streaming is supported, is .ogv?) Icecast does it, halfway…

Working <Stream> sections

While trying to get things working, I came across a number of Stream-Settings which worked for my revision20182 ffserver. Some reside here for quick copy&past, in case you want to test them.

# works
# <Stream test.swf>
#    Feed feed1.ffm
#    Format swf
#    VideoCodec flv
#    VideoFrameRate 15
#    VideoBufferSize 80000
#    VideoBitRate 100
#    VideoQMin 1
#    VideoQMax 5
#    VideoSize 352×288
#    PreRoll 0
#    Noaudio
# </Stream>

# works, asf seems to be the most stable
#<Stream test.asf>
#    Feed feed1.ffm
#    Format asf
#    VideoFrameRate 15
#    VideoSize 720×480
#    VideoBitRate 256
#    VideoBufferSize 40
#    VideoGopSize 30
#    AudioBitRate 64
#    StartSendOnKey
# </Stream>

# works
# <Stream test.asf>
#    Feed feed1.ffm
#    Format asf
#    VideoFrameRate 15
#    VideoSize 720×480
#    VideoBitRate 728
#    VideoBufferSize 40
#    VideoGopSize 30
#    AudioBitRate 64
#    StartSendOnKey
# </Stream>

# works
# <Stream test.mp3>
#    Feed feed1.ffm
#    Format mp2
#    AudioCodec libmp3lame
#    AudioBitRate 128
#    AudioChannels 1
#    AudioSampleRate 44100
#    NoVideo
# </Stream>

# Real with audio and video at 64 kbits (from example.conf)
# works in mplayer and real-player
# <Stream test.rm>
#    Feed feed1.ffm
#    Format rm
#    AudioBitRate 32
#    VideoBitRate 128
#    VideoFrameRate 25
#    VideoGopSize 25
# </Stream>

# works in mplayer and real-player
# <Stream test.rm>
#    Feed feed1.ffm
#    Format rm
#    VideoBitRate 128
#    VideoFrameRate 25
#    VideoGopSize 25
#    AudioBitRate 64
# </Stream>

# Multipart JPEG (from example conf)
# works, but speeds your video up, setting  FrameRate to 25 for example fixes this
# <Stream test.mjpg>
#    Feed feed1.ffm
#    Format mpjpeg
#    VideoFrameRate 2
#    VideoIntraOnly
#    NoAudio
#    Strict -1
# </Stream>