[FFmpeg-devel] HLS Segmenter and the "hls_time" option

Ibrahim Tachijian barhom at netsat.se
Fri Aug 26 11:58:46 EEST 2016


Thanks this actually does what I expected it to do.
For me this option will help a lot, and we would really be interested in
this eventually reaching git.

Thanks to Steven Liu's patch we will be able to use this to start live
streams faster. Great job!

Below follows what command I ran and the output m3u8 playlist.

/root/ffmpeg_patched -analyzeduration 1000000 -i udp://MCAST_ADDR:3301 -map
0:0 -map 0:1 -c:v libx264 -preset superfast -g 25 -b:v 900k -maxrate 900k
-bufsize 2000k -filter:v yadif -c:a libfdk_aac -b:a 64k -hls_time 5
*-hls_init_time
1* -hls_list_size 10 -hls_allow_cache 0 -hls_flags delete_segments -f hls
/tmp/playlist.m3u8

The output M3U8 of patched ffmpeg:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:3
#EXTINF:1.000000,
playlist3.ts
#EXTINF:1.000000,
playlist4.ts
#EXTINF:1.000000,
playlist5.ts
#EXTINF:1.000000,
playlist6.ts
#EXTINF:1.000000,
playlist7.ts
#EXTINF:1.000000,
playlist8.ts
#EXTINF:1.600000,
playlist9.ts
#EXTINF:1.000000,
playlist10.ts
#EXTINF:4.000000,
playlist11.ts
#EXTINF:5.000000,
playlist12.ts


On Fri, Aug 26, 2016 at 8:37 AM Steven Liu <lingjiujianke at gmail.com> wrote:

> 2016-08-26 14:00 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:
>
> >
> >
> > 2016-08-26 10:34 GMT+08:00 Ibrahim Tachijian <barhom at netsat.se>:
> >
> >> In my use case scenario I only need it for the very first couple of
> >> segments.
> >> After 5 segments it is not a problem anymore to have 5 second segments
> >> only.
> >>
> >>
> >>
> >> On Fri, Aug 26, 2016 at 4:25 AM Steven Liu <lingjiujianke at gmail.com>
> >> wrote:
> >>
> >> > 2016-08-26 10:10 GMT+08:00 Ibrahim Tachijian <barhom at netsat.se>:
> >> >
> >> > > yes that is correct Steven.
> >> > >
> >> > > On Fri, Aug 26, 2016 at 3:41 AM Steven Liu <lingjiujianke at gmail.com
> >
> >> > > wrote:
> >> > >
> >> > > > 2016-08-26 8:17 GMT+08:00 Ibrahim Tachijian <barhom at netsat.se>:
> >> > > >
> >> > > > > Steven, I am not sure you understood me correctly or perhaps I
> did
> >> > not
> >> > > > > explain myself optimally.
> >> > > > >
> >> > > > > We still want to split by keyframe in a normal fashion. But, for
> >> > > example,
> >> > > > > would like the first 5 segments to have an "hls_time" of 1s and
> >> the
> >> > > rest
> >> > > > of
> >> > > > > the segments after the first 5 to have an "hls_time" of 5s.
> >> > > > >
> >> > > > > An made up option would be (hls_time_initial Seconds,Number)
> >> > > > >
> >> > > > >    - "-hls_time_initial 1,5 -hls_time 5"
> >> > > > >
> >> > > > > The output playlist would contain segments (split at keyframes)
> 5
> >> > > > segments
> >> > > > > of length 1s and then any segment after the initial 5 segment
> >> would
> >> > be
> >> > > > 5s.
> >> > > > >
> >> > > > > Is it clear what I am trying to explain?
> >> > > > >
> >> > > > > What do you think? Do you know how this can be achieved?
> >> > > > >
> >> > > > > Thanks,
> >> > > > >
> >> > > > > On Fri, Aug 26, 2016 at 2:06 AM Steven Liu <
> >> lingjiujianke at gmail.com>
> >> > > > > wrote:
> >> > > > >
> >> > > > > > 2016-08-26 7:39 GMT+08:00 Ibrahim Tachijian <barhom at netsat.se
> >:
> >> > > > > >
> >> > > > > > > Hello,
> >> > > > > > >
> >> > > > > > > I've been thinking about an option for "hls_time" that is
> not
> >> > > > currently
> >> > > > > > > supported by FFMpeg and I would like feedback to if some of
> >> you
> >> > may
> >> > > > > think
> >> > > > > > > this is useful or utterly unnecessary.
> >> > > > > > >
> >> > > > > > > I find scenarios where we sometimes want to create an HLS
> >> output
> >> > > and
> >> > > > > > would
> >> > > > > > > like the *first couple of segments* to be shorter than the
> >> *rest
> >> > of
> >> > > > the
> >> > > > > > > segments.*
> >> > > > > > >
> >> > > > > > > For example starting off with 1s segments up to N segments
> >> then
> >> > > > switch
> >> > > > > to
> >> > > > > > > 5s segments.
> >> > > > > > >
> >> > > > > > > The reasoning is simply to have the playlist.m3u8 and first
> >> > segment
> >> > > > > > > available *asap.*
> >> > > > > > >
> >> > > > > > > What do you think? Do you know how this can be achieved?
> >> > > > > > >
> >> > > > > > > Thanks,
> >> > > > > > >
> >> > > > > >
> >> > > > > > ffmpeg split segment use hlsenc by keyframe, if you want to
> >> split
> >> > > > segment
> >> > > > > > *ASAP*,
> >> > > > > > you can try set your streaming *GOP(Group Of Picture)*
> shorter,
> >> > > > > > for example: gop_size = 60,  c->time_base =
> (AVRational){1,60};
> >> > > > > > in command line : -r:v 60 -g 60
> >> > > > > >
> >> > > > > > if can accept split segment at non-keyframe, you can use
> >> hls_time
> >> > and
> >> > > > > > hls_flags split_by_time.
> >> > > > > > _______________________________________________
> >> > > > >
> >> > > > you mean:
> >> > > >
> >> > > > segment-0.ts,segment-1.ts,segment-2.ts,segment-3.ts,segment-4.ts
> >> these
> >> > > 5
> >> > > > segments duration is 1s
> >> > > > and
> >> > > > segment-5.ts,segment-6.ts,segment-7.ts ...... these segment
> >> duration is
> >> > > 5
> >> > > > or set by hls_time
> >> > > > Is that right i understand?
> >> > >
> >> > >
> >> > OK , Thanks.
> >> > That a good idea, but i have a question:
> >> > when ffmpeg update the segment list after 10 segments, there have a
> new
> >> > user to play the hls playlist, the m3u8 segments every ts segments'
> >> > duration is the 5s.
> >> > So do you want exec a new ffmpeg when every one play the hls playlist
> ?
> >>
> >>
> > Dose this patch can fix your request?
> >
> >
> > update patch
>
>
> Test process:
> localhost:ffmpeg liuqi$ ./ffmpeg -v verbose -re -i
> ~/Movies/objectC/facebook.mp4 -c copy -f hls -hls_time 3 -hls_list_size 3
> -hls_flags split_by_time aaaa_output.m3u8
> ffmpeg version N-81462-gbcd1153 Copyright (c) 2000-2016 the FFmpeg
> developers
>   built with Apple LLVM version 7.3.0 (clang-703.0.31)
>   configuration: --enable-fontconfig --enable-gpl --enable-libass
> --enable-libbluray --enable-libfreetype --enable-libmp3lame
> --enable-libspeex --enable-libx264 --enable-libx265 --enable-version3
>   libavutil      55. 29.100 / 55. 29.100
>   libavcodec     57. 54.100 / 57. 54.100
>   libavformat    57. 48.100 / 57. 48.100
>   libavdevice    57.  0.102 / 57.  0.102
>   libavfilter     6. 55.100 /  6. 55.100
>   libswscale      4.  1.100 /  4.  1.100
>   libswresample   2.  1.100 /  2.  1.100
>   libpostproc    54.  0.100 / 54.  0.100
> [h264 @ 0x7f94f1813c00] Reinit context to 1280x720, pix_fmt: yuv420p
> Input #0, mov,mp4,m4a,3gp,3g2,mj2, from
> '/Users/liuqi/Movies/objectC/facebook.mp4':
>   Metadata:
>     major_brand     : isom
>     minor_version   : 1
>     compatible_brands: isomavc1
>     creation_time   : 2015-02-02 18:19:19
>   Duration: 00:45:02.06, start: 0.000000, bitrate: 2708 kb/s
>     Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 /
> 0x31637661), yuv420p, 1280x714 (1280x720) [SAR 1:1 DAR 640:357], 2576 kb/s,
> 25 fps, 25 tbr, 25k tbn, 50 tbc (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:19
>       handler_name    : GPAC ISO Video Handler
>     Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
> stereo, fltp, 127 kb/s (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:23
>       handler_name    : GPAC ISO Audio Handler
> [hls @ 0x7f94f3004800] Using AVStream.codec to pass codec parameters to
> muxers is deprecated, use AVStream.codecpar instead.
>     Last message repeated 1 times
> [mpegts @ 0x7f94f180b800] muxrate VBR, pcr every 5 pkts, sdt every
> 2147483647, pat/pmt every 2147483647 pkts
> Output #0, hls, to 'aaaa_output.m3u8':
>   Metadata:
>     major_brand     : isom
>     minor_version   : 1
>     compatible_brands: isomavc1
>     encoder         : Lavf57.48.100
>     Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 /
> 0x31637661), yuv420p, 1280x714 (0x0) [SAR 1:1 DAR 640:357], q=2-31, 2576
> kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:19
>       handler_name    : GPAC ISO Video Handler
>     Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
> stereo, 127 kb/s (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:23
>       handler_name    : GPAC ISO Audio Handler
> Stream mapping:
>   Stream #0:0 -> #0:0 (copy)
>   Stream #0:1 -> #0:1 (copy)
> Press [q] to stop, [?] for help
> Automatically inserted bitstream filter 'h264_mp4toannexb'; args=''
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:00:03.04 bitrate=N/A speed=
>  1x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:00:06.12 bitrate=N/A
> speed=1.01x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:00:08.64 bitrate=N/A speed=
>  1x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:10:11.73 bitrate=N/A speed=
>  1x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:20:14.74 bitrate=N/A speed=
>  1x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:30:17.76 bitrate=N/A speed=
>  1x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:40:20.84 bitrate=N/A speed=
>  1x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:50:23.89 bitrate=N/A speed=
>  1x
> [hls @ 0x7f94f3004800] EXT-X-MEDIA-SEQUENCE:6
> frame=  601 fps= 25 q=-1.0 Lsize=N/A time=00:00:24.29 bitrate=N/A speed=
> 1x
> video:7099kB audio:370kB subtitle:0kB other streams:0kB global headers:0kB
> muxing overhead: unknown
> Input file #0 (/Users/liuqi/Movies/objectC/facebook.mp4):
>   Input stream #0:0 (video): 601 packets read (7269480 bytes);
>   Input stream #0:1 (audio): 1139 packets read (379370 bytes);
>   Total: 1740 packets (7648850 bytes) demuxed
> Output file #0 (aaaa_output.m3u8):
>   Output stream #0:0 (video): 601 packets muxed (7269480 bytes);
>   Output stream #0:1 (audio): 1139 packets muxed (379370 bytes);
>   Total: 1740 packets (7648850 bytes) muxed
> localhost:ffmpeg liuqi$
> localhost:ffmpeg liuqi$ ./ffmpeg -v verbose -re -i
> ~/Movies/objectC/facebook.mp4 -c copy -f hls -hls_init_time 1 -hls_time 5
> -hls_flags split_by_time output_test.m3u8
> ffmpeg version N-81462-gbcd1153 Copyright (c) 2000-2016 the FFmpeg
> developers
>   built with Apple LLVM version 7.3.0 (clang-703.0.31)
>   configuration: --enable-fontconfig --enable-gpl --enable-libass
> --enable-libbluray --enable-libfreetype --enable-libmp3lame
> --enable-libspeex --enable-libx264 --enable-libx265 --enable-version3
>   libavutil      55. 29.100 / 55. 29.100
>   libavcodec     57. 54.100 / 57. 54.100
>   libavformat    57. 48.100 / 57. 48.100
>   libavdevice    57.  0.102 / 57.  0.102
>   libavfilter     6. 55.100 /  6. 55.100
>   libswscale      4.  1.100 /  4.  1.100
>   libswresample   2.  1.100 /  2.  1.100
>   libpostproc    54.  0.100 / 54.  0.100
> [h264 @ 0x7fedf4017600] Reinit context to 1280x720, pix_fmt: yuv420p
> Input #0, mov,mp4,m4a,3gp,3g2,mj2, from
> '/Users/liuqi/Movies/objectC/facebook.mp4':
>   Metadata:
>     major_brand     : isom
>     minor_version   : 1
>     compatible_brands: isomavc1
>     creation_time   : 2015-02-02 18:19:19
>   Duration: 00:45:02.06, start: 0.000000, bitrate: 2708 kb/s
>     Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 /
> 0x31637661), yuv420p, 1280x714 (1280x720) [SAR 1:1 DAR 640:357], 2576 kb/s,
> 25 fps, 25 tbr, 25k tbn, 50 tbc (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:19
>       handler_name    : GPAC ISO Video Handler
>     Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
> stereo, fltp, 127 kb/s (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:23
>       handler_name    : GPAC ISO Audio Handler
> [hls @ 0x7fedf4000600] Using AVStream.codec to pass codec parameters to
> muxers is deprecated, use AVStream.codecpar instead.
>     Last message repeated 1 times
> [mpegts @ 0x7fedf3008a00] muxrate VBR, pcr every 5 pkts, sdt every
> 2147483647, pat/pmt every 2147483647 pkts
> Output #0, hls, to 'output_test.m3u8':
>   Metadata:
>     major_brand     : isom
>     minor_version   : 1
>     compatible_brands: isomavc1
>     encoder         : Lavf57.48.100
>     Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 /
> 0x31637661), yuv420p, 1280x714 (0x0) [SAR 1:1 DAR 640:357], q=2-31, 2576
> kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:19
>       handler_name    : GPAC ISO Video Handler
>     Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
> stereo, 127 kb/s (default)
>     Metadata:
>       creation_time   : 2015-02-02 18:19:23
>       handler_name    : GPAC ISO Audio Handler
> Stream mapping:
>   Stream #0:0 -> #0:0 (copy)
>   Stream #0:1 -> #0:1 (copy)
> Press [q] to stop, [?] for help
> Automatically inserted bitstream filter 'h264_mp4toannexb'; args=''
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:00:00.52 bitrate=N/A
> speed=1.02x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:00:01.56 bitrate=N/A
> speed=1.03x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:00:03.08 bitrate=N/A
> speed=1.01x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:00:03.56 bitrate=N/A speed=
>  1x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:00:05.12 bitrate=N/A
> speed=1.01x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:10:06.12 bitrate=N/A speed=
>  1x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:20:09.70 bitrate=N/A speed=
>  1x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:30:14.80 bitrate=N/A speed=
>  1x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:40:19.88 bitrate=N/A speed=
>  1x
> [hls @ 0x7fedf4000600] EXT-X-MEDIA-SEQUENCE:50:20.90 bitrate=N/A speed=
>  1x
> frame=  529 fps= 25 q=-1.0 Lsize=N/A time=00:00:21.35 bitrate=N/A speed=
> 1x
> video:6506kB audio:324kB subtitle:0kB other streams:0kB global headers:0kB
> muxing overhead: unknown
> Input file #0 (/Users/liuqi/Movies/objectC/facebook.mp4):
>   Input stream #0:0 (video): 529 packets read (6661710 bytes);
>   Input stream #0:1 (audio): 1001 packets read (332091 bytes);
>   Total: 1530 packets (6993801 bytes) demuxed
> Output file #0 (output_test.m3u8):
>   Output stream #0:0 (video): 529 packets muxed (6661710 bytes);
>   Output stream #0:1 (audio): 1001 packets muxed (332091 bytes);
>   Total: 1530 packets (6993801 bytes) muxed
> localhost:ffmpeg liuqi$
>
>
> And recover segments duration time by hls_time after init hls window.
> This is reuqested by Ibrahim Tachijian
>
> Signed-off-by: LiuQi <liuqi at gosun.com>
> ---
>  libavformat/hlsenc.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index e65f002..f5ceb60 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -85,6 +85,7 @@ typedef struct HLSContext {
>      AVFormatContext *vtt_avf;
>
>      float time;            // Set by a private option.
> +    float init_time;            // Set by a private option.
>      int max_nb_segments;   // Set by a private option.
>      int  wrap;             // Set by a private option.
>      uint32_t flags;        // enum HLSFlags
> @@ -706,7 +707,7 @@ static int hls_write_header(AVFormatContext *s)
>      int vtt_basename_size;
>
>      hls->sequence       = hls->start_sequence;
> -    hls->recording_time = hls->time * AV_TIME_BASE;
> +    hls->recording_time = (hls->init_time ? hls->init_time : hls->time) *
> AV_TIME_BASE;
>      hls->start_pts      = AV_NOPTS_VALUE;
>
>      if (hls->format_options_str) {
> @@ -860,9 +861,19 @@ static int hls_write_packet(AVFormatContext *s,
> AVPacket *pkt)
>      AVStream *st = s->streams[pkt->stream_index];
>      int64_t end_pts = hls->recording_time * hls->number;
>      int is_ref_pkt = 1;
> +    int init_list_dur = 0;
> +    int after_init_list_dur = 0;
>      int ret, can_split = 1;
>      int stream_index = 0;
>
> +    if (hls->sequence - hls->nb_entries > hls->start_sequence &&
> hls->init_time > 0) {
> +        /* reset end_pts, hls->recording_time at end of the init hls list
> */
> +        init_list_dur = hls->init_time * hls->nb_entries * AV_TIME_BASE;
> +        after_init_list_dur = (hls->sequence - hls->nb_entries ) *
> hls->time * AV_TIME_BASE;
> +        hls->recording_time = hls->time * AV_TIME_BASE;
> +        end_pts = init_list_dur + after_init_list_dur ;
> +    }
> +
>      if( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
>          oc = hls->vtt_avf;
>          stream_index = 0;
> @@ -972,6 +983,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
>  static const AVOption options[] = {
>      {"start_number",  "set first number in the sequence",
>  OFFSET(start_sequence),AV_OPT_TYPE_INT64,  {.i64 = 0},     0, INT64_MAX,
> E},
>      {"hls_time",      "set segment length in seconds",
> OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E},
> +    {"hls_init_time", "set segment length in seconds at init list",
>     OFFSET(init_time),    AV_OPT_TYPE_FLOAT,  {.dbl = 0},     0, FLT_MAX,
> E},
>      {"hls_list_size", "set maximum number of playlist entries",
>  OFFSET(max_nb_segments),    AV_OPT_TYPE_INT,    {.i64 = 5},     0,
> INT_MAX, E},
>      {"hls_ts_options","set hls mpegts list of options for the container
> format used for hls", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str
> = NULL},  0, 0,    E},
>      {"hls_vtt_options","set hls vtt list of options for the container
> format used for hls", OFFSET(vtt_format_options_str), AV_OPT_TYPE_STRING,
> {.str = NULL},  0, 0,    E},
> --
> 2.7.4 (Apple Git-66)
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>


More information about the ffmpeg-devel mailing list