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:
parent
4fb6f9de0c
commit
2793ebd6cb
@ -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 {
|
|||||||
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" },
|
||||||
|
@ -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, \
|
||||||
|
Loading…
Reference in New Issue
Block a user