[FFmpeg-trac] #6888(undetermined:new): HLS segmenter doesn't cut .m4s files at its expected duration

FFmpeg trac at avcodec.org
Sun Dec 3 21:56:16 EET 2017


#6888: HLS segmenter doesn't cut .m4s files at its expected duration
-------------------------------------+-------------------------------------
             Reporter:  beloko       |                     Type:  defect
               Status:  new          |                 Priority:  normal
            Component:               |                  Version:  git-
  undetermined                       |  master
             Keywords:  HLS          |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 Hello,

 I'm attempting to create an HLS stream with fragmented MP4 files instead
 of usual MPEG2-TS files. Because the next step for Ultra HD broadcasting
 will require the HEVC video codec. And Apple won't support MPEG2-TS to
 broadcast HEVC contents.

 Now, I see FFMPEG embeds some new parameters to create fMP4 streams inside
 its HLS segmenter : ''-hls_segment_type'' and ''-hls_fmp4_init_filename''.
 So I decided to climb on the bandwagon.

 I'm able to create an HLS stream with fragmented MP4. Share this stream
 throught my local web server. And succesfully watch its video content from
 an iPhone or any video player having fMP4 supports. macOS Safari (High
 Sierra) and Windows Edge (Fall Creators) browsers are also ready.

 Here is my FFMPEG command line :

 {{{
 ffmpeg.exe -i
 "http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4"
 -loglevel verbose -threads 0 -an -sn -vcodec libx264 -force_key_frames
 "expr:gte(t,n_forced*4)" -r 25 -f hls -hls_time 4 -hls_list_size 99999
 -start_number 1 -hls_segment_type fmp4 -hls_fmp4_init_filename
 "C:\inetpub\wwwroot\fmp4_x264\init.mp4" -t 30
 "C:\inetpub\wwwroot\fmp4_x264\big_bunny.m3u8"
 }}}

 I set the ''-hls_time'' to segment every 4 seconds and the
 ''-force_key_frames'' to create an IFrame every 4 seconds. Unfortunately
 the Apple Mediastreamvalidator tool find errors about segment length.


 {{{
 Belokos-Mac:~ beloko$ mediastreamvalidator
 http://192.168.1.3/fmp4_x264/big_bunny.m3u8
 mediastreamvalidator: Version 1.2(170822)

 [/fmp4_x264/big_bunny.m3u8] Started root playlist download
 [/fmp4_x264/big_bunny.m3u8] Started media playlist download
 [/fmp4_x264/big_bunny.m3u8] All media files delivered and have end tag,
 stopping

 --------------------------------------------------------------------------------
 http://192.168.1.3/fmp4_x264/big_bunny.m3u8
 --------------------------------------------------------------------------------
 Processed 8 out of 8 segments
 Average segment duration: 3.250000
 Total segment bitrates (all discontinuities): average: 3915.87 kb/s, max:
 6866.19 kb/s


 Discontinuity: sequence: 0, parsed segment count: 8 of 8, duration: 26.000
 sec, average: 3915.87 kb/s, max: 6866.19 kb/s
 Track ID: 1
 Video Codec: avc1
 Video profile: High
 Video level: 4.0
 Video resolution: 1920x1080
 Video average IDR interval: 3.500000, Standard deviation: 1.152215
 Video frame rate: 25.000

 --------------------------------------------------------------------------------
 MUST fix issues
 --------------------------------------------------------------------------------

 Error: Playlist vs segment duration mismatch
 --> Detail:  Segment duration 8.0000, Playlist duration: 4.0000
 --> Source:  http://192.168.1.3/fmp4_x264/big_bunny.m3u8 - big_bunny1.m4s
 }}}

 Here is the .m3u8 content :


 {{{
 #EXTM3U
 #EXT-X-VERSION:7
 #EXT-X-TARGETDURATION:4
 #EXT-X-MEDIA-SEQUENCE:1
 #EXT-X-MAP:URI="C:\inetpub\wwwroot\fmp4_x264\init.mp4"
 #EXTINF:4.000000,
 big_bunny1.m4s
 #EXTINF:4.000000,
 big_bunny2.m4s
 #EXTINF:4.000000,
 big_bunny3.m4s
 #EXTINF:4.000000,
 big_bunny4.m4s
 #EXTINF:4.000000,
 big_bunny5.m4s
 #EXTINF:3.520000,
 big_bunny6.m4s
 #EXTINF:0.480000,
 big_bunny7.m4s
 #EXTINF:2.000000,
 big_bunny8.m4s
 #EXT-X-ENDLIST
 }}}


 And here is the duration I get for each .m4s segmented file using FFProbe
 :
 . big_bunny1.m4s = 00:00:08.00
 . big_bunny2.m4s = 00:00:04.00
 . big_bunny3.m4s = 00:00:04.00
 . big_bunny4.m4s = 00:00:04.00
 . big_bunny5.m4s = 00:00:04.00
 . big_bunny6.m4s = 00:00:03.52
 . big_bunny7.m4s = 00:00:00.44
 . big_bunny8.m4s = 00:00:02.00


 ----


 Finally I can fix the duration length for segments ''big_bunny6.m4s'' and
 ''big_bunny7.m4s''.

 Here is the command line updated :

 {{{
 ffmpeg.exe -i
 "http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4"
 -loglevel verbose -threads 0 -an -sn -vcodec libx264 -force_key_frames
 "expr:gte(t,n_forced*4)" -sc_threshold 0 -r 25 -f hls -hls_time 4
 -hls_list_size 99999 -start_number 1 -hls_segment_type fmp4
 -hls_fmp4_init_filename "C:\inetpub\wwwroot\fmp4_x264\init.mp4" -t 30
 "C:\inetpub\wwwroot\fmp4_x264\big_bunny.m3u8"
 }}}

 I use the ''-sc_threshold'' parameter to disable the scene cuts detection.
 Then FFMPEG isn't granted to intelligently insert some IFrames to optimize
 video quality. And the HLS segmenter can't cut at a wrong IFrames before
 expected segment duration.

 Here is the .m3u8 content :

 {{{
 #EXTM3U
 #EXT-X-VERSION:7
 #EXT-X-TARGETDURATION:4
 #EXT-X-MEDIA-SEQUENCE:1
 #EXT-X-MAP:URI="init.mp4"
 #EXTINF:4.000000,
 big_bunny1.m4s
 #EXTINF:4.000000,
 big_bunny2.m4s
 #EXTINF:4.000000,
 big_bunny3.m4s
 #EXTINF:4.000000,
 big_bunny4.m4s
 #EXTINF:4.000000,
 big_bunny5.m4s
 #EXTINF:4.000000,
 big_bunny6.m4s
 #EXTINF:2.000000,
 big_bunny7.m4s
 #EXT-X-ENDLIST
 }}}

 Everything looks fine. Each segments holds 4 seconds. But the sum of all
 segments duration should be 30 seconds because I used ''-t 30''
 parameters. Here I calculate (6 x 4) + (1 x 2) = 26 seconds. 4 seconds are
 missing.

 So here is what I can inspect about each segment with FFProbe :
 . big_bunny1.m4s = 00:00:08.00
 . big_bunny2.m4s = 00:00:04.00
 . big_bunny3.m4s = 00:00:04.00
 . big_bunny4.m4s = 00:00:04.00
 . big_bunny5.m4s = 00:00:04.00
 . big_bunny6.m4s = 00:00:04.00
 . big_bunny7.m4s = 00:00:02.00

 Now (1 x 8) + (5 x 4) + (1 x 2) = 30 seconds.

 Seems the first .m4s segment file isn't properly cut at the expected
 duration by the HLS segmenter.


 ----


 PS/ to probe .m4s files I have to concatenate the init.mp4 file with each
 .m4s file to create a clean video file. Because .mp4 contains video
 headers and .m4s contains the video stream.

 Here is the command line to concatenate properly and inspect the first
 segment :

 {{{
 ffmpeg.exe -i
 "concat:C:\inetpub\wwwroot\fmp4_x264\init.mp4|C:\inetpub\wwwroot\fmp4_x264\big_bunny1.m4s"
 -codec copy C:\inetpub\wwwroot\fmp4_x264\concated1.mp4
 ffprobe C:\inetpub\wwwroot\fmp4_x264\concated1.mp4
 }}}

--
Ticket URL: <https://trac.ffmpeg.org/ticket/6888>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list