Commit 445c30ba authored by Steven Liu's avatar Steven Liu Committed by Michael Niedermayer

lavf/hlsenc: add append_list flag into hlsenc

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: 's avatarLiuQi <liuqi@gosun.com>
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 57503fab
...@@ -495,6 +495,10 @@ Will produce the playlist, @file{out.m3u8}, and a single segment file, ...@@ -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 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. 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 @item hls_flags round_durations
Round the duration info in the playlist file segment info to integer Round the duration info in the playlist file segment info to integer
values, instead of using floating point. values, instead of using floating point.
......
...@@ -63,6 +63,7 @@ typedef enum HLSFlags { ...@@ -63,6 +63,7 @@ typedef enum HLSFlags {
HLS_DISCONT_START = (1 << 3), HLS_DISCONT_START = (1 << 3),
HLS_OMIT_ENDLIST = (1 << 4), HLS_OMIT_ENDLIST = (1 << 4),
HLS_SPLIT_BY_TIME = (1 << 5), HLS_SPLIT_BY_TIME = (1 << 5),
HLS_APPEND_LIST = (1 << 6),
} HLSFlags; } HLSFlags;
typedef enum { typedef enum {
...@@ -265,6 +266,14 @@ static int hls_encryption_start(AVFormatContext *s) ...@@ -265,6 +266,14 @@ static int hls_encryption_start(AVFormatContext *s)
return 0; 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) static int hls_mux_init(AVFormatContext *s)
{ {
HLSContext *hls = s->priv_data; HLSContext *hls = s->priv_data;
...@@ -389,6 +398,54 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double ...@@ -389,6 +398,54 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double
return 0; 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) static void hls_free_segments(HLSSegment *p)
{ {
HLSSegment *en; HLSSegment *en;
...@@ -752,6 +809,10 @@ static int hls_write_header(AVFormatContext *s) ...@@ -752,6 +809,10 @@ static int hls_write_header(AVFormatContext *s)
if ((ret = hls_mux_init(s)) < 0) if ((ret = hls_mux_init(s)) < 0)
goto fail; goto fail;
if (hls->flags & HLS_APPEND_LIST) {
parse_playlist(s, s->filename);
}
if ((ret = hls_start(s)) < 0) if ((ret = hls_start(s)) < 0)
goto fail; goto fail;
...@@ -927,6 +988,7 @@ static const AVOption options[] = { ...@@ -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"}, {"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"}, {"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"}, {"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", "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 }, {"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" }, {"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" },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment