Commit 2793ebd6 authored by Michael Niedermayer's avatar Michael Niedermayer

avformat/hlsenc: implement program_date_time

Reviewed-by: 's avatarSteven Liu <lingjiujianke@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 4fb6f9de
...@@ -522,6 +522,9 @@ behavior on some players when the time between keyframes is inconsistent, ...@@ -522,6 +522,9 @@ behavior on some players when the time between keyframes is inconsistent,
but may make things worse on others, and can cause some oddities during but may make things worse on others, and can cause some oddities during
seeking. This flag should be used with the @code{hls_time} option. seeking. This flag should be used with the @code{hls_time} option.
@item hls_flags program_date_time
Generate @code{EXT-X-PROGRAM-DATE-TIME} tags.
@item hls_playlist_type event @item hls_playlist_type event
Emit @code{#EXT-X-PLAYLIST-TYPE:EVENT} in the m3u8 header. Forces Emit @code{#EXT-X-PLAYLIST-TYPE:EVENT} in the m3u8 header. Forces
@option{hls_list_size} to 0; the playlist can only be appended to. @option{hls_list_size} to 0; the playlist can only be appended to.
......
...@@ -64,6 +64,7 @@ typedef enum HLSFlags { ...@@ -64,6 +64,7 @@ typedef enum HLSFlags {
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), HLS_APPEND_LIST = (1 << 6),
HLS_PROGRAM_DATE_TIME = (1 << 7),
} HLSFlags; } HLSFlags;
typedef enum { typedef enum {
...@@ -128,6 +129,7 @@ typedef struct HLSContext { ...@@ -128,6 +129,7 @@ typedef struct HLSContext {
char *method; char *method;
double initial_prog_date_time;
} HLSContext; } HLSContext;
static int hls_delete_old_segments(HLSContext *hls) { static int hls_delete_old_segments(HLSContext *hls) {
...@@ -481,6 +483,7 @@ static int hls_window(AVFormatContext *s, int last) ...@@ -481,6 +483,7 @@ static int hls_window(AVFormatContext *s, int last)
char *key_uri = NULL; char *key_uri = NULL;
char *iv_string = NULL; char *iv_string = NULL;
AVDictionary *options = NULL; AVDictionary *options = NULL;
double prog_date_time = hls->initial_prog_date_time;
if (!use_rename && !warned_non_file++) if (!use_rename && !warned_non_file++)
av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporarly partial files\n"); av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporarly partial files\n");
...@@ -533,6 +536,19 @@ static int hls_window(AVFormatContext *s, int last) ...@@ -533,6 +536,19 @@ static int hls_window(AVFormatContext *s, int last)
if (hls->flags & HLS_SINGLE_FILE) if (hls->flags & HLS_SINGLE_FILE)
avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n",
en->size, en->pos); en->size, en->pos);
if (hls->flags & HLS_PROGRAM_DATE_TIME) {
time_t tt;
int milli;
struct tm *tm, tmpbuf;
char buf0[128], buf1[128];
tt = (int64_t)prog_date_time;
milli = av_clip(lrint(1000*(prog_date_time - tt)), 0, 999);
tm = localtime_r(&tt, &tmpbuf);
strftime(buf0, sizeof(buf0), "%FT%T", tm);
strftime(buf1, sizeof(buf1), "%z", tm);
avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1);
prog_date_time += en->duration;
}
if (hls->baseurl) if (hls->baseurl)
avio_printf(out, "%s", hls->baseurl); avio_printf(out, "%s", hls->baseurl);
avio_printf(out, "%s\n", en->filename); avio_printf(out, "%s\n", en->filename);
...@@ -710,6 +726,12 @@ static int hls_write_header(AVFormatContext *s) ...@@ -710,6 +726,12 @@ static int hls_write_header(AVFormatContext *s)
hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE; hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
hls->start_pts = AV_NOPTS_VALUE; hls->start_pts = AV_NOPTS_VALUE;
if (hls->flags & HLS_PROGRAM_DATE_TIME) {
time_t now0;
time(&now0);
hls->initial_prog_date_time = now0;
}
if (hls->format_options_str) { if (hls->format_options_str) {
ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0); ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
if (ret < 0) { if (ret < 0) {
...@@ -1005,6 +1027,7 @@ static const AVOption options[] = { ...@@ -1005,6 +1027,7 @@ static const AVOption options[] = {
{"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"}, {"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"},
{"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" },
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
// Also please add any ticket numbers that you believe might be affected here // Also please add any ticket numbers that you believe might be affected here
#define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MAJOR 57
#define LIBAVFORMAT_VERSION_MINOR 48 #define LIBAVFORMAT_VERSION_MINOR 48
#define LIBAVFORMAT_VERSION_MICRO 102 #define LIBAVFORMAT_VERSION_MICRO 103
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \
......
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