1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

avformat/hlsenc: implement program_date_time

Reviewed-by: Steven Liu <lingjiujianke@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer 2016-09-07 21:34:44 +02:00
parent 4fb6f9de0c
commit 2793ebd6cb
3 changed files with 27 additions and 1 deletions

View File

@ -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.

View File

@ -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 {
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)
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)
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)
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[] = {
{"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" },

View File

@ -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, \