Sunteți pe pagina 1din 5

FFmpeg – the swiss army knife of Internet Streaming –

part IV
30 August 2011 sonnati

PART I – Introduction (revised 02-jul-2012)


PART II – Parameters and recipes (revised 02-jul-2012)
PART III – Encoding in H.264 (revised 02-jul-2012)
PART IV – FFmpeg for streaming (revised 02-jul-2012)
PART V – Advanced usage (revised, 19-oct-2012)
PART VI – Filtering (new, 19-oct-2012)

Fourth Part

In this article I will focus on the support for RTMP that makes FFmpeg an excellent tool for
enhancing the capabilities of the Adobe Flash Streaming Ecosystem.

FFmpeg introduced a strong support for RTMP streaming with the release 0.5 by the
inclusion of the librtmp (rtmpdump) core. An RTMP stream can be used both as an input
and/or as an output in a command line.

The required syntax is:

rtmp_proto://server[:port][/application][/stream] options

where rtmp_proto can be: “rtmp“, “rtmpt“, “rtmpte“, “rtmps“, “rtmpte“, “rtmpts” and
options contain a list of space-separated options in the form key=val (more info here).

Using some of the parameters that we have seen in the first three parts of the series, it’s
possible to do a lot of things that the standard Flash Streaming Ecosystem cannot offer.
Sometimes there are minor bugs but generally speaking the rtmplib works well and helps
FMS to fill the gap with some advanced feature of Wowza Server (like re-purposing of
rtp/rtsp stream, TS-stream and so on). FFmpeg works with FMS as well as Wowza Server and
RED5, so in the article I will use FMS as a generic term to mean any “RTMP-server”.

1. STREAM A FILE TO FMS AS IF IT WERE LIVE

With the help of FFmpeg it is possible for example to stream a pre-encoded file to FMS as if
it were a live source. This can be very useful for test purpose but also to create pseudo-live
channels.

ffmpeg -re -i localFile.mp4 -c copy -f flv rtmp://server/live/streamName

The -re option tells FFmpeg to read the input file in realtime and not in the standard as-fast-
as-possible manner. With -c copy (alias -acodec copy -vcodec copy ) I’m telling FFmpeg to
copy the essences of the input file without transcoding, then to package them in an FLV
container (-f flv) and send the final bitstream to an rtmp destination
(rtmp://server/live/streamName).

The input file must have audio and video codec compatible with FMS, for example H.264 for
video and AAC for audio but any supported codecs combination should work.
Obviously it would be also possible to encode on the fly the input video. In this case
remember that the CPU power requested for a live encoding can be high and cause loss in
frame rate or stuttering playback on subscribers’ side.

In which scenario can be useful a command like that ?

For example, suppose to have created a communication or conference tool in AIR. One of
the partecipants at the conference could fetch a local file and stream it to the conference
FMS to show, in realtime, the same file to other partecipants. Leveraging the “native
process” feature of AIR it is simple to launch a command line like the one above and do the
job. In this scenario, probably you will have to transcode the input, or check for the
compatibility of codecs analyzing the input up front (remember ffmpeg -i INPUT trick we
spoke about in the second article).

2. GRAB AN RTMP SOURCE

Using a command like this:

ffmpeg -i rtmp://server/live/streamName -c copy dump.flv

It’s possible to dump locally the content of a remote RTMP stream. This can be useful for
test/audit/validation purpose. It works for both live and on-demand content.

3. TRANSCODE LIVE RTMP TO LIVE RTMP

One of the more interesting scenario is when you want to convert a format to a different
one for compatibility sake or to change the characteristics of the original stream.

Let’s suppose to have a Flash Player based app that do a live broadcast. You know that until
FP11, Flash can only encode using the old Sorenson spark for video and NellyMoser ASAO or
Speex for audio. You may use a live transcoding command to enhance the compression of
the video transcoding from Sorenson to H.264:

ffmpeg -i rtmp://server/live/originalStream -c:a copy -c:v libx264 -vpre slow -f flv


rtmp://server/live/h264Stream

This could be useful to reduce bandwidth usage especially in live broadcasting where latency
it’s not a problem.
The next release of FMS will also offer support for the Apple HTTP Live Streaming (like
Wowza already do). So it will be possible to use FMS to stream live to iOS device. But FMS
does not transcode the stream essence, it performs only a repackaging or repurposing of the
original essences. But FFmpeg can help us to convert the uncompliant Sorenson-Speex
stream to a H.264-AAC stream in this way:
ffmpeg -i rtmp://server/live/originalStream -c:a libfaac -ar 44100 -ab 48k -c:v libx264 -vpre slow -vpre baseline
-f flv rtmp://server/live/h264Stream

(UPDATE: libfaac is now an external library and maybe you can have problem encoding in
AAC – Read part V of the series to know more about this topic.)

See also the point 4 and 5 to know how to generate a multibitrate stream to be compliant
with Apple requirements for HLS. This approach will be useful also with FP11 that encode in
H.264, but generate only one stream.

Another common scenario is when you are using FMLE to make a live broadcast. The
standard windows version of FMLE supports only MP3 and not AAC for audio encoding (plug-
in required). This may be a problem when you want to use your stream also to reach iOS
devices with FMS or Wowza (iOS requires AAC for HLS streams). Again FFmpeg can help us:

ffmpeg -i rtmp://server/live/originalStream -acodec libfaac -ar 44100 -ab 48k -vcodec copy -f flv
rtmp://server/live/h264_AAC_Stream

On the other hand, I have had the opposite problem recently with an AIR 2.7+ apps for iOS.
AIR for iOS does not support by now H.264 or AAC streaming with the classical netStream
object, but I needed to subscribe AAC streams generated for the desktops. FFmpeg helped
me in transcoding AAC streams to MP3 for the AIR on iOS app.

Again, you probably know that Apple HLS requires an audio only AAC stream with a bitrate
less than 64Kbit/s for the compliance of video streaming apps, but at the same time you
probably want to offer an higher audio quality for your live streaming (on desktop fpo
istance). Unfortunately FMLE encode at multiple bitrates only the video track while use a
unique audio preset for all bitrates. With FFmpeg is possible to generate a dedicated audio
only stream in AAC with bitrate less than 64Kbit/s.

4. GENERATE BASELINE FOR LOW-END DEVICES

Very similarly, if you want to be compliant with older iOS versions or other mobile devices
(older BB for istance) you need to encode in Baseline profile, but at the same time you may
want to leverage high profile for desktop HDS. So you could use FMLE to generate high
profile streams, with high quality AAC and then generate server side a baseline set of multi-
bitrate streams for HLS and/or low end devices compatibility.

This command read from FMS the highest quality of a multi bitrate set generated by FMLE
and starting from that generate 3 scaled down versions in baseline profile for HLS or Mobile.
The last stream is an audio only AAC bitstream at 48Kbit/s.

ffmpeg -re -i rtmp://server/live/high_FMLE_stream -acodec copy -vcodec x264lib -s 640x360 -b 500k -vpre
medium -vpre baseline rtmp://server/live/baseline_500k -acodec copy -vcodec x264lib -s 480x272 -b 300k -
vpre medium -vpre baseline rtmp://server/live/baseline_300k -acodec copy -vcodec x264lib -s 320x200 -b 150k
-vpre medium -vpre baseline rtmp://server/live/baseline_150k -acodec libfaac -vn -ab 48k
rtmp://server/live/audio_only_AAC_48k

UPDATE: using the -x264opts parameter you may rewrite the command like this:
ffmpeg -re -i rtmp://server/live/high_FMLE_stream -c:a copy -c:v x264lib -s 640x360 -x264opts
bitrate=500:profile=baseline:preset=slow rtmp://server/live/baseline_500k -c:a copy -c:v x264lib -s 480x272 -
x264opts bitrate=300:profile=baseline:preset=slow rtmp://server/live/baseline_300k -c:a copy -c:v x264lib -s
320x200 -x264opts bitrate=150:profile=baseline:preset=slow rtmp://server/live/baseline_150k -c:a libfaac -vn -
b:a 48k rtmp://server/live/audio_only_AAC_48k

(UPDATE: libfaac is now an external library and maybe you can have problem encoding in
AAC – Read part V of the series to know more about this topic.)

5. ENCODE LIVE FROM LOCAL GRABBING DEVICES

FFmpeg can use also a local AV source, so it’s possible to encode live directly from FFmpeg
and bypass completely FMLE. I suggest to do that only in very controlled scenarios because
FMLE offers precious, addictional functions like auto-encoding adjust to keep as low as
possible the latency when the bandwidth between the acquisition point and the server is not
perfect.

This is an example of single bitrate:

ffmpeg -r 25 -f dshow -s 640x480 -i video="video source name":audio="audio source name" -vcodec libx264 -b
600k -vpre slow -acodec libfaac -ab 128k rtmp://server/application/stream_name

Join this command line and the previous and you have a multi-bitrate live encoding
configuration for desktop and mobile.

6. ENCODE SINGLE PICTURES WITH H.264 INTRA COMPRESSION

H.264 has a very efficient Intra compression mode, so it is possible to leverage it for picture
compression. I have estimated an improvement of around 50% in compression compared to
JPG. Last year I have discussed estensively the possibility to use this kind of image
compression to protect professional footage with FMS and RTMPE. Here you find the article,
and this is the command line:

ffmpeg.exe -i INPUT.jpg -an -vcodec libx264 -coder 1 -flags +loop -cmp +chroma -subq 10 -qcomp 0.6 -qmin 10 -
qmax 51 -qdiff 4 -flags2 +dct8x8 -trellis 2 -partitions +parti8x8+parti4x4 -crf 24 -threads 0 -r 25 -g 25 -y
OUTPUT.mp4

Change -crf to modulate encoding quality (and compression rate).

UPDATES

Sometimes when connecting to FMS you may receive some cryptic error. It may help to
enclose the destination RTMP address in double quotes and add the option live=1. ES:

ffmpeg -i rtmp://server/live/originalStream -c:a copy -c:v libx264 -vpre slow -f flv


"rtmp://server/live/h264Stream live=1"

Other info on RTMP dump libray: http://ffmpeg.org/ffmpeg.html#toc-rtmp


CONCLUSIONS

There are a lot of other scenarios where using FFmpeg with FMS (or Wowza) can help you
creating new exciting services for you projects and overcome the limitations of the current
Flash Video Ecosystem, so now it’s up to you. Try to mix my examples and post comments
about new ways of customization that you have found of your RTMP delivery system.
Remember also to follow the discussion on my twitter account (@sonnati).

[Index]

PART I – Introduction (revised 02-jul-2012)


PART II – Parameters and recipes (revised 02-jul-2012)
PART III – Encoding in H.264 (revised 02-jul-2012)
PART IV – FFmpeg for streaming (revised 02-jul-2012)
PART V – Advanced usage (revised, 19-oct-2012)
PART VI – Filtering (new, 19-oct-2012)

S-ar putea să vă placă și