[FFmpeg-user] HLS segment duration for multiple framerate encoding

Yisrael lushimaps at hotmail.com
Tue Jul 21 19:17:10 CEST 2015


I am trying to encode a video to HLS in multiple bitrates (and, 
therefore, according to apple's recommendations, multiple frame rates). 
 I am doing this on video files (not live streams).



I can get one HLS working fine when I have a single variant, or
 multiple variants of the same framerate.  But when I have variants of 
different framerates, I can't get the segment durations to line up.



For example, here are the first few lines of the m3u8 file of the same video encoded a 15 fps and 30 fps. Note the durations of the first segments have _different_lengths_. Also the TARGETDURATION is different.



    #EXT-X-TARGETDURATION:10

    #EXTINF:9.023222,

    640_0.ts



    #EXT-X-TARGETDURATION:9

    #EXTINF:9.000000,

    960_0.ts





My objective is to make a multi-bitrate (and multi-framerate) 
stream that will pass apple's mediastreamvalidator test.  I have spent a
 few days scouring all the forums, tutorials, mailing lists, 
messageboards etc...and I still can't get the streams to have segments 
of matching durations when I use a different framerate...and without 
that, it won't pass the test.



I have tried different segment options (segment vs. hls), 
different keyframes options (-g / -force_key_frames), ffmpeg 2 pass 
methods, as well as just using ffmpeg for transcoding and segmenting 
with apple's segmenter. Even the apple segmentor is ends up segmenting 
the files so the audio cuts off in the middle of each segment...



I'm sure this is something that can be done and is done 
regularly - can anyone please enlighten me?  (for anyone else reading 
this later on, considder this an interesting summary of ways to use 
ffmpeg to create an HLS stream.)



So, what am I doing wrong and how do I do it right?

  

Also, can anyone explain what the differences are between -g / -force_key_frames and between  hls / segment - and which one is preferable to use?



====================================================================

ffmpeg version 2.7.1-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2015 the FFmpeg developers

built with gcc 4.9.2 (Debian 4.9.2-21)

configuration: --enable-gpl --enable-version3 --disable-shared 
--disable-debug --enable-runtime-cpudetect --enable-libmp3lame 
--enable-libx264 --enable-libx265 --enable-libwebp --enable-libspeex 
--enable-libvorbis --enable-libvpx --enable-libfreetype 
--enable-fontconfig --enable-libxvid --enable-libopencore-amrnb 
--enable-libopencore-amrwb --enable-libtheora --enable-libvo-aacenc 
--enable-libvo-amrwbenc --enable-gray --enable-libopenjpeg 
--enable-libopus --enable-libass --enable-gnutls --enable-libvidstab 
--enable-libsoxr --cc=gcc-4.9

libavutil      54. 27.100 / 54. 27.100

libavcodec     56. 41.100 / 56. 41.100

libavformat    56. 36.100 / 56. 36.100

libavdevice    56.  4.100 / 56.  4.100

libavfilter     5. 16.101 /  5. 16.101

libswscale      3.  1.101 /  3.  1.101

libswresample   1.  2.100 /  1.  2.100

libpostproc    53.  3.100 / 53.  3.100







SOURCE:          
http://www.caminandes.com/download/01_llama_drama_1080p.zip  (from open 
movie project - note it is 24 fps - maybe that is the problem?)

  Resolution:    1920x1080

  FrameRate:     24

  Profile:       h264 High



TARGET:          HLS

 VARIANT 1:

  Resolution:    480x270

  FrameRate:     15

  Video Bitrate: 400

  Audio Bitrate: 64 

  Keyframe:      45 frames (3 seconds)

  Profile:       h264 Baseline, 3.0

  Segment Size:  9 seconds



 VARIANT 2:

  Resolution:    640x360

  FrameRate:     30  (yes, I am increasing the bitrate - but trying it with 24 didn't help either)

  Video Bitrate: 1200

  Audio Bitrate: 96 

  Keyframe:      90 frames (3 seconds)

  Profile:       h264 Baseline, 3.1

  Segment Size:  9 seconds



 VARIANT 3:

  Resolution:    960x540

  FrameRate:     30  

  Video Bitrate: 1600

  Audio Bitrate: 128 

  Keyframe:      90 frames (3 seconds)

  Profile:       h264 Main, 3.1

  Segment Size:  9 seconds





Here is a summary of the methods I have tried and some of their
 outputs:  (I am aware that libfdk_aac is a better codec, but my version
 currently doesn't have that compiled in)





0) hls commands, -force_key_frames

----------------------------------

  ./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 15 -profile:v baseline -level 3 -b:v 400k -maxrate 
428.00k -force_key_frames "expr:gte(t,n_forced*3)" -vf "scale=480:-1" 
-hls_list_size 0 -hls_time 9 480_.m3u8

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 30 -profile:v baseline -level 3.1 -b:v 1200k -maxrate 
1284.00k -force_key_frames "expr:gte(t,n_forced*3)" -vf "scale=640:-1" 
-hls_list_size 0 -hls_time 9 640_.m3u8

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 30 -profile:v main -level 3.1 -b:v 1568k -maxrate 
1677.76k -force_key_frames "expr:gte(t,n_forced*3)" -vf "scale=960:-1" 
-hls_list_size 0 -hls_time 9 960_.m3u8



  

    #EXT-X-TARGETDURATION:10

    #EXTINF:9.023222,

    480_0.ts



    #EXT-X-TARGETDURATION:10

    #EXTINF:9.023222,

    640_0.ts



    #EXT-X-TARGETDURATION:9

    #EXTINF:9.000000,

    960_0.ts





1) hls commands, -g 

-------------------

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf h264_mp4toannexb 
-flags -global_header -vcodec libx264 -strict -2 -acodec aac -r 15 
-profile:v baseline -level 3 -b:v 400k -maxrate 428.00k -g 45 -vf 
"scale=480:-1" -hls_list_size 0 -hls_time 9 480_.m3u8

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 30 -profile:v baseline -level 3.1 -b:v 1200k -maxrate 
1284.00k -g 90 -vf "scale=640:-1" -hls_list_size 0 -hls_time 9 640_.m3u8

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 30 -profile:v main -level 3.1 -b:v 1568k -maxrate 
1677.76k -g 90 -vf "scale=960:-1" -hls_list_size 0 -hls_time 9 960_.m3u8





    #EXT-X-TARGETDURATION:12

    #EXTINF:11.156556,

    480_0.ts



    #EXT-X-TARGETDURATION:12

    #EXTINF:11.056556,

    640_0.ts



    #EXT-X-TARGETDURATION:12

    #EXTINF:11.033333,

    960_0.ts







2) segment commands, -g

-----------------------

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 15 -profile:v baseline -level 3 -b:v 400k -maxrate 
428.00k -g 45 -vf "scale=480:-1" -f segment -segment_list 480_.m3u8 
-segment_time 9 -segment_list_type m3u8 -segment_list_flags -cache+live 
480_%05d.ts

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 30 -profile:v baseline -level 3.1 -b:v 1200k -maxrate 
1284.00k -g 90 -vf "scale=640:-1" -f segment -segment_list 640_.m3u8 
-segment_time 9 -segment_list_type m3u8 640_%05d.ts

./ffmpeg -y -i ../infile.mp4 -pix_fmt yuv420p -vbsf 
h264_mp4toannexb -flags -global_header -vcodec libx264 -strict -2 
-acodec aac -r 30 -profile:v main -level 3.1 -b:v 1568k -maxrate 
1677.76k -g 90 -vf "scale=960:-1" -f segment -segment_list 960_.m3u8 
-segment_time 9 -segment_list_type m3u8 960_%05d.ts



    #EXT-X-TARGETDURATION:12

    #EXTINF:11.156556,

    480_00000.ts



    #EXT-X-TARGETDURATION:12

    #EXTINF:11.056556,

    640_00000.ts



    #EXT-X-TARGETDURATION:12

    #EXTINF:11.100000,

    960_00000.ts







3) muti-pass (couldn't get it to work - based on: 
https://sonnati.wordpress.com/2012/07/02/ffmpeg-the-swiss-army-knife-of-internet-streaming-part-v/
 )

-------------

#FIRST PASS

./ffmpeg -i ../infile.mp4 -pass 1 -an -vcodec libx264 -r 30 
-b:v 1200k -bufsize 1200k -keyint_min 60 -g 120 -s 640x360  -f mpegts -y
 /dev/null

#SECOND PASS

./ffmpeg -i ../infile.mp4 -pass 2 -an -vcodec libx264 -r 30 -b:v 1200k -bufsize 1200k -keyint_min 60 -g 120 -s 640x360  640_.mp4

#SECOND PASS WITH DIFFERENT FRAME RATE (FAILS)

./ffmpeg -i ../infile.mp4 -pass 2 -an -vcodec libx264 -r 15 -b:v 400k  -bufsize 400k  -keyint_min 30 -g 60  -s 480x270  480_.mp4



    #Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
 		 	   		  


More information about the ffmpeg-user mailing list