Multi bitrate streaming

Steam recording with RTMPDump or FFmpeg.
Post Reply
Posts: 3
Joined: Mon Sep 01, 2014 11:48 am

Multi bitrate streaming

Post by xtruder » Mon Sep 15, 2014 9:11 am

Iam trying to send multiple stream versions to rtmp server and according to this documentations ffmpeg supports it: ... 3-part-iv/

Code taken from the article:

Code: Select all

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
However, when i try to send multi bitrate versions to my rtmp server (rtmp://streamkey1, rtmp://streamkey2), it recognizes only one, the last one in the string. Process does show combined bitrate of 2 streams, so it does output both.
Flash Media Live Encoder, when 2 quality settings are specified, outputs my stream correctly to streamkey1 and streamkey2 and is being recognized by the server as multi quality stream.

Any suggestions?

Posts: 20
Joined: Thu Jul 03, 2014 10:49 pm

Re: Multi bitrate streaming

Post by vayvanne » Mon Dec 19, 2016 2:06 am

Hi xtruder,
I do the same and just can't get streams properly aligned. I do a bit differently:

Code: Select all

ffmpeg -stats -re -rtmp_live live -i "rtmp://edge/live/stream" ^
-filter_complex "[0:v]split[a][b];[a]scale=540:-1[oa];[b]copy[ob]" ^
-map [oa] -c:v libx264 -profile:v main -level 3.0 -preset fast -b:v 500k -copyts -flags +global_header ^
-map 0:a -c:a copy -f flv "rtmp://localhost/live/500k" ^
-map [ob] -c:v libx264 -profile:v main -level 3.0 -preset fast -b:v 800k -copyts -flags +global_header ^
-map 0:a -c:a copy -f flv "rtmp://localhost/live/800k"
Checking the output:

Code: Select all

ffprobe -print_format csv -show_frames -i rtmp://localhost/live/500k | findstr I
And the same for the other stream in separate console window:

Code: Select all

ffprobe -print_format csv -show_frames -i rtmp://localhost/live/800k | findstr I
Key frame PTSes are not the same, they always starts from 0. The switch over the streams in player is not seamless.
The same ffmpeg setup but with output to HLS muxer works fine.
Playing now with -videosync 0, -copyts, -copytb params.

Posts: 51
Joined: Thu May 12, 2011 5:19 pm

Re: Multi bitrate streaming

Post by navilor » Mon Mar 13, 2017 11:57 pm

Your answer can be found over at my blog. ... -one-pass/

You do not need the -re option unless you are streaming from a file for pseudo live streaming. The lines in my blog, which I copied and modified below, should fix your PTS timing issue and align your keyframes for proper ABR content delivery.

Code: Select all

ffmpeg.exe -i i "rtmp://edge/live/stream"

-pix_fmt yuv420p -r 23.976 -vcodec libx264 -vf "scale=1920:1080" -b:v 3400k -preset veryfast -profile:v baseline -keyint_min 24 -g 48 -x264opts no-scenecut -acodec aac -b:a 96k -af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" -map_metadata -1 -f flv "rtmp://localhost/live/1080p

-pix_fmt yuv420p -r 23.976 -vcodec libx264 -vf "scale=1280:720" -b:v 1725k -preset veryfast -profile:v baseline -keyint_min 24 -g 48 -x264opts no-scenecut -acodec aac -b:a 96k -af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" -map_metadata -1 -f flv "rtmp://localhost/live/720p

-pix_fmt yuv420p -r 23.976 -vcodec libx264 -vf "scale=854:480" -b:v 960k -preset veryfast -profile:v baseline -keyint_min 24 -g 48 -x264opts no-scenecut -acodec aac -b:a 96k -af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" -map_metadata -1 -f flv "rtmp://localhost/live/480p

-pix_fmt yuv420p -r 23.976 -vcodec libx264 -vf "scale=480:360" -b:v 510k -preset veryfast -profile:v baseline -keyint_min 24 -g 48 -x264opts no-scenecut -acodec aac -b:a 96k -af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" -map_metadata -1 -f flv "rtmp://localhost/live/360p

-pix_fmt yuv420p -r 23.976 -vcodec libx264 -vf "scale=426:240" -b:v 320k -preset veryfast -profile:v baseline -keyint_min 24 -g 48 -x264opts no-scenecut -acodec aac -b:a 96k -af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" -map_metadata -1 -f flv "rtmp://localhost/live/240p

-pix_fmt yuv420p -r 23.976 -vcodec libx264 -vf "scale=284:160" -b:v 160k -preset veryfast -profile:v baseline -keyint_min 24 -g 48 -x264opts no-scenecut -acodec aac -b:a 96k -af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" -map_metadata -1 -f flv "rtmp://localhost/live/160p
-g 48 will define a GOP of 48 frames to create a two second GOP for the 23.976fps content. This works in conjunction with the no-scenecut option below.

-x264opts no-scenecut will force keyframes to be created per the GOP value that FFmpeg uses. The default for libx264 is to create a keyframe when it detects a scene change. If you inspect an output file with MediaInfo you will see "scenecut=40". When done properly that will be zero "scenecut=0". If this option is not used then keyframes will be misaligned for ABR content and segment sizes will be unpredictable.

-af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" helps to keep your audio lined up with the beginning of your stream or file. It is common for an input source to have the beginning of the video and the beginning of the audio start at different points. By using this your stream or file should have little to no audio drift or offset.

You can validate your GOP via this command line under Linux. If you are on Windows you can use Cygwin for the same result.

ffprobe -select_streams v -show_frames -show_entries frame=pict_type -of csv $inputfile | grep -n I | cut -d ':' -f 1

Posts: 332
Joined: Fri Mar 14, 2014 3:29 am

Re: Multi bitrate streaming

Post by llogan » Wed Mar 22, 2017 7:37 pm

Use the tee muxer:
  • Since the audio is going to be the same for all outputs encode it only once and use it for all outputs
  • Save a local copy with little extra overhead
  • Use efficient filtergraph design to minimize filtering
  • Optionally: Add the fifo muxer to re-connect on failed connections

Code: Select all

ffmpeg -i input
-filter_complex "[0:v]format=yuv420p,split=3[vunscaled][v1][v2];[v1]scale=-2:720[v720];[v2]scale=-2:480[v480]"
-map "[vunscaled]" -map "[v720]" -map "[v480]" -map 0:a
-c:v libx264 -g <output frame rate * 2> -preset <desired x264 encoding preset>
-c:a aac -b:a 128k
-b:v:0 <vunscaled_bitrate> -maxrate:v:0 <vunscaled_maxrate> -bufsize:v:0 <vunscaled_maxrate*2>
-b:v:1 <v720_bitrate> -maxrate:v:1 <v720_maxrate> -bufsize:v:1 <v720_maxrate*2>
-b:v:2 <v480_bitrate> -maxrate:v:2 <v480_maxrate> -bufsize:v:2 <v480_maxrate*2>
-flags +global_header -f tee
You will of course have to choose your desired values in the "<>".

Post Reply