2016-08-11 23:04 GMT+08:00 Steven Liu <lingjiujia...@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 <li...@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. > > +@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel