diff options
author | Bodecs Bela <bodecsb@vivanet.hu> | 2016-12-27 10:40:35 +0800 |
---|---|---|
committer | Bodecs Bela <bodecsb@vivanet.hu> | 2016-12-27 10:40:35 +0800 |
commit | 0ff8c6b6d5243becfa73ff6960348a949055617b (patch) | |
tree | f759840fac8a80a177a9f06031d13af3772d80a8 /libavformat | |
parent | c7c0046efc3a05e52d0a6da4da9f0beae47c0847 (diff) | |
download | ffmpeg-0ff8c6b6d5243becfa73ff6960348a949055617b.tar.gz |
avformat/hlsenc: strftime identifiers and segment index
in filenames
Putting date/time values into segment filenames is very usefull.
But to produce non-conflicting segment filenames with -use_localtime
option with date/time
values in hls_segment_filename option, sometimes is not enough.
Like in cases when multiple segments produced in the same second.
But hlsenc currently does not make possible to use segment index (%d) at
the
same time whe use_localtime is in effect, due to identifier conflict.
This patch makes possible to use strftime identifiers and still put
segment index (%d) at same time in segment filenames by introducing
second_level_segment_index flag. When -use_localtime is active,
identifier %d is for month day index, so %%d is the segment index
placeholder. This enhanced behaviour only exists when new
second_level_segment_index flag is specified.
For instance putting 'segment_%Y%m%d%H%M%S_%%05d.ts' value into
-hls_segment_filename option and specifing -hls_flags
second_level_segment_index and -use_localtime 1, may produce segment
filename as 'segment_20161230235758_00002.ts'
An example:
ffmpeg -loglevel info -y -f lavfi -i color=c=red:size=640x480:r=25 -f
lavfi -i anullsrc=r=44100:cl=stereo -c:v mpeg2video -g 25 -acodec aac
-cutoff 20000 -ac 2 -ar 44100 -ab 192k -f hls -hls_time 3 -hls_list_size
5 -hls_flags delete_segments+second_level_segment_index -use_localtime 1
-hls_segment_filename "segment_%Y%m%d%H%M%S_%%05d.ts" stream.m3u8
will produce segments filenames:
....
segment_20161227005902_00013.ts
segment_20161227005902_00014.ts
segment_20161227005902_00015.ts
segment_20161227005903_00016.ts
segment_20161227005903_00017.ts
segment_20161227005903_00018.ts
segment_20161227005903_00019.ts
segment_20161227005903_00020.ts
....
Signed-off-by: Bela Bodecs <bodecsb@vivanet.hu>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/hlsenc.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 648e775dfa..cf4d4bd7e9 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -66,6 +66,7 @@ typedef enum HLSFlags { HLS_SPLIT_BY_TIME = (1 << 5), HLS_APPEND_LIST = (1 << 6), HLS_PROGRAM_DATE_TIME = (1 << 7), + HLS_SECOND_LEVEL_SEGMENT_INDEX = (1 << 8), // include segment index in segment filenames when use_localtime e.g.: %%03d } HLSFlags; typedef enum { @@ -717,7 +718,19 @@ static int hls_start(AVFormatContext *s) av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n"); return AVERROR(EINVAL); } - + if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) { + char * filename = av_strdup(oc->filename); // %%d will be %d after strftime + if (!filename) + return AVERROR(ENOMEM); + if (av_get_frame_filename2(oc->filename, sizeof(oc->filename), + filename, c->wrap ? c->sequence % c->wrap : c->sequence, + AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) { + av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', you can try to remove second_level_segment_index flag\n", filename); + av_free(filename); + return AVERROR(EINVAL); + } + av_free(filename); + } if (find_segment_by_filename(c->segments, oc->filename) || find_segment_by_filename(c->old_segments, oc->filename)) { av_log(c, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", oc->filename); @@ -900,7 +913,11 @@ static int hls_write_header(AVFormatContext *s) av_strlcat(hls->basename, pattern, basename_size); } } - + if (!hls->use_localtime && (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX)) { + av_log(hls, AV_LOG_ERROR, "second_level_segment_index hls_flag requires use_localtime to be true\n"); + ret = AVERROR(EINVAL); + goto fail; + } if(hls->has_subtitle) { if (hls->flags & HLS_SINGLE_FILE) @@ -1156,6 +1173,7 @@ static const AVOption options[] = { {"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"}, {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX, E, "flags"}, + {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 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" }, |