[FFmpeg-devel] [PATCH] add append_list flag into hlsenc
Steven Liu
lingjiujianke at gmail.com
Mon Aug 15 06:17:56 EEST 2016
2016-08-11 23:04 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:
> When ffmpeg exit by exception, start a new ffmpeg will cover the old
> segment list, add this flag can continue append the new segments into old
> hls segment list
>
> Signed-off-by: LiuQi <liuqi at gosun.com>
> ---
> doc/muxers.texi | 4 ++++
> libavformat/hlsenc.c | 63 ++++++++++++++++++++++++++++++
> ++++++++++++++++++++++
> 2 files changed, 67 insertions(+)
>
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index 5873269..2e95c6f 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -495,6 +495,10 @@ Will produce the playlist, @file{out.m3u8}, and a
> single segment file,
> Segment files removed from the playlist are deleted after a period of time
> equal to the duration of the segment plus the duration of the playlist.
>
> + at item hls_flags append_list
> +Append new segments into the end of old segment list,
> +and remove the @code{#EXT-X-ENDLIST} from the old segment list.
> +
> @item hls_flags round_durations
> Round the duration info in the playlist file segment info to integer
> values, instead of using floating point.
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index 9f076ba..a570db4 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -63,6 +63,7 @@ typedef enum HLSFlags {
> HLS_DISCONT_START = (1 << 3),
> HLS_OMIT_ENDLIST = (1 << 4),
> HLS_SPLIT_BY_TIME = (1 << 5),
> + HLS_APPEND_LIST = (1 << 6),
> } HLSFlags;
>
> typedef enum {
> @@ -265,6 +266,14 @@ static int hls_encryption_start(AVFormatContext *s)
> return 0;
> }
>
> +static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
> +{
> + int len = ff_get_line(s, buf, maxlen);
> + while (len > 0 && av_isspace(buf[len - 1]))
> + buf[--len] = '\0';
> + return len;
> +}
> +
> static int hls_mux_init(AVFormatContext *s)
> {
> HLSContext *hls = s->priv_data;
> @@ -389,6 +398,55 @@ static int hls_append_segment(struct AVFormatContext
> *s, HLSContext *hls, double
> return 0;
> }
>
> +static int parse_playlist(AVFormatContext *s, const char *url)
> +{
> + HLSContext *hls = s->priv_data;
> + AVIOContext *in;
> + int ret = 0, is_segment = 0;
> + int64_t new_start_pos;
> + int64_t duration = 0;
> + char line[1024];
> + const char *ptr;
> +
> + if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
> + &s->interrupt_callback, NULL,
> + s->protocol_whitelist,
> s->protocol_blacklist)) < 0)
> + return ret;
> +
> + read_chomp_line(in, line, sizeof(line));
> + if (strcmp(line, "#EXTM3U")) {
> + ret = AVERROR_INVALIDDATA;
> + goto fail;
> + }
> +
> + while (!avio_feof(in)) {
> + read_chomp_line(in, line, sizeof(line));
> + if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
> + duration = atoi(ptr);
> + } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
> + hls->sequence = atoi(ptr);
> + } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
> + } else if (av_strstart(line, "#EXTINF:", &ptr)) {
> + is_segment = 1;
> + hls->duration = atof(ptr);
> + } else if (av_strstart(line, "#", NULL)) {
> + continue;
> + } else if (line[0]) {
> + if (is_segment) {
> + new_start_pos = avio_tell(hls->avf->pb);
> + hls->size = new_start_pos - hls->start_pos;
> + av_strlcpy(hls->avf->filename, line, sizeof(line));
> + hls_append_segment(s, hls, hls->duration, hls->start_pos,
> hls->size);
> + is_segment = 0;
> + }
> + }
> + }
> +
> +fail:
> + avio_close(in);
> + return ret;
> +}
> +
> static void hls_free_segments(HLSSegment *p)
> {
> HLSSegment *en;
> @@ -752,6 +810,10 @@ static int hls_write_header(AVFormatContext *s)
> if ((ret = hls_mux_init(s)) < 0)
> goto fail;
>
> + if (hls->flags & HLS_APPEND_LIST) {
> + parse_playlist(s, s->filename);
> + }
> +
> if ((ret = hls_start(s)) < 0)
> goto fail;
>
> @@ -927,6 +989,7 @@ static const AVOption options[] = {
> {"discont_start", "start the playlist with a discontinuity tag", 0,
> AV_OPT_TYPE_CONST, {.i64 = HLS_DISCONT_START }, 0, UINT_MAX, E, "flags"},
> {"omit_endlist", "Do not append an endlist when ending stream", 0,
> AV_OPT_TYPE_CONST, {.i64 = HLS_OMIT_ENDLIST }, 0, UINT_MAX, E, "flags"},
> {"split_by_time", "split the hls segment by time which user set by
> hls_time", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SPLIT_BY_TIME }, 0, UINT_MAX,
> E, "flags"},
> + {"append_list", "append the new segments into old hls segment list",
> 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX, E, "flags"},
> {"use_localtime", "set filename expansion with strftime at segment
> creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
> {"use_localtime_mkdir", "create last directory component in
> strftime-generated filename", OFFSET(use_localtime_mkdir),
> AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
> {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type),
> AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E,
> "pl_type" },
> --
> 2.7.4 (Apple Git-66)
>
>
ping
More information about the ffmpeg-devel
mailing list