[FFmpeg-devel] [PATCH] lavf/hlsenc: add append_list flag into hlsenc
Steven Liu
lingjiujianke at gmail.com
Sun Aug 21 08:03:02 EEST 2016
Fix unused *duration*
remove the #EXT-X-ENDLIST and #EXT-X-TARGETDURATION tags,
keep intened with hls->duratin, hls->start_pos, hls->size.
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 | 62
++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 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..e65f002 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,54 @@ 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;
+ 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-MEDIA-SEQUENCE:", &ptr)) {
+ hls->sequence = atoi(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) {
+ is_segment = 0;
+ new_start_pos = avio_tell(hls->avf->pb);
+ hls->size = new_start_pos - hls->start_pos;
+ av_strlcpy(hls->avf->filename, line, sizeof(line));
+ ret = hls_append_segment(s, hls, hls->duration,
hls->start_pos, hls->size);
+ if (ret < 0)
+ goto fail;
+ hls->start_pos = new_start_pos;
+ }
+ }
+ }
+
+fail:
+ avio_close(in);
+ return ret;
+}
+
static void hls_free_segments(HLSSegment *p)
{
HLSSegment *en;
@@ -752,6 +809,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 +988,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)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-lavf-hlsenc-add-append_list-flag-into-hlsenc.patch
Type: application/octet-stream
Size: 5184 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20160821/8c818d06/attachment.obj>
More information about the ffmpeg-devel
mailing list