Message ID | 31ce1f1789ac33712015af217394ef72f016fb16.1603695205.git.nikola@pajkovsky.cz |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v3] hlsenc: expand hls_fmp4_init_filename with strftime() | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
Nikola Pajkovsky <nikola@pajkovsky.cz> writes: Ping? > init.mp4 can be expanded with strftime() the same way as > hls_segment_filename. > > Signed-off-by: Nikola Pajkovsky <nikola@pajkovsky.cz> > --- > v2: fix memleak on strftime failure > v3: use av_free() insted of free() > > doc/muxers.texi | 7 ++++++ > libavformat/hlsenc.c | 54 +++++++++++++++++++++++++++++++++++--------- > 2 files changed, 50 insertions(+), 11 deletions(-) > > diff --git a/doc/muxers.texi b/doc/muxers.texi > index 813b4678f409..179b9239517b 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above. > @item hls_fmp4_init_filename @var{filename} > Set filename to the fragment files header file, default filename is @file{init.mp4}. > > +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime. > +@example > +ffmpeg -i in.nut -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8 > +@end example > +This will produce init like this > +@file{1602678741_init.mp4} > + > @item hls_fmp4_init_resend > Resend init file after m3u8 file refresh every time, default is @var{0}. > > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index cbfd8f7c0d41..3457ed5201bf 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -259,6 +259,29 @@ typedef struct HLSContext { > int has_video_m3u8; /* has video stream m3u8 list */ > } HLSContext; > > +static int strftime_expand(const char *fmt, char **dest) > +{ > + int r = 1; > + time_t now0; > + struct tm *tm, tmpbuf; > + char *buf; > + > + buf = av_mallocz(MAX_URL_SIZE); > + if (!buf) > + return AVERROR(ENOMEM); > + > + time(&now0); > + tm = localtime_r(&now0, &tmpbuf); > + r = strftime(buf, MAX_URL_SIZE, fmt, tm); > + if (!r) { > + av_free(buf); > + return AVERROR(EINVAL); > + } > + *dest = buf; > + > + return r; > +} > + > static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, > AVDictionary **options) > { > @@ -1660,19 +1683,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) > ff_format_set_url(oc, filename); > } else { > if (c->use_localtime) { > - time_t now0; > - struct tm *tm, tmpbuf; > - int bufsize = strlen(vs->basename) + MAX_URL_SIZE; > - char *buf = av_mallocz(bufsize); > - if (!buf) > - return AVERROR(ENOMEM); > - time(&now0); > - tm = localtime_r(&now0, &tmpbuf); > - ff_format_set_url(oc, buf); > - if (!strftime(oc->url, bufsize, vs->basename, tm)) { > + int r; > + char *expanded = NULL; > + > + r = strftime_expand(vs->basename, &expanded); > + if (r < 0) { > av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); > - return AVERROR(EINVAL); > + return r; > } > + ff_format_set_url(oc, expanded); > > err = sls_flag_use_localtime_filename(oc, c, vs); > if (err < 0) { > @@ -2980,6 +2999,19 @@ static int hls_init(AVFormatContext *s) > return ret; > } > > + if (hls->use_localtime) { > + int r; > + char *expanded = NULL; > + > + r = strftime_expand(vs->fmp4_init_filename, &expanded); > + if (r < 0) { > + av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); > + return r; > + } > + av_free(vs->fmp4_init_filename); > + vs->fmp4_init_filename = expanded; > + } > + > p = strrchr(vs->m3u8_name, '/'); > if (p) { > char tmp = *(++p);
Nikola Pajkovsky <nikola@pajkovsky.cz> writes: > Nikola Pajkovsky <nikola@pajkovsky.cz> writes: > > Ping? Ping. Steven, Andreas, can you look at the the latest iteration of the path? >> init.mp4 can be expanded with strftime() the same way as >> hls_segment_filename. >> >> Signed-off-by: Nikola Pajkovsky <nikola@pajkovsky.cz> >> --- >> v2: fix memleak on strftime failure >> v3: use av_free() insted of free() >> >> doc/muxers.texi | 7 ++++++ >> libavformat/hlsenc.c | 54 +++++++++++++++++++++++++++++++++++--------- >> 2 files changed, 50 insertions(+), 11 deletions(-) >> >> diff --git a/doc/muxers.texi b/doc/muxers.texi >> index 813b4678f409..179b9239517b 100644 >> --- a/doc/muxers.texi >> +++ b/doc/muxers.texi >> @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above. >> @item hls_fmp4_init_filename @var{filename} >> Set filename to the fragment files header file, default filename is @file{init.mp4}. >> >> +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime. >> +@example >> +ffmpeg -i in.nut -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8 >> +@end example >> +This will produce init like this >> +@file{1602678741_init.mp4} >> + >> @item hls_fmp4_init_resend >> Resend init file after m3u8 file refresh every time, default is @var{0}. >> >> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c >> index cbfd8f7c0d41..3457ed5201bf 100644 >> --- a/libavformat/hlsenc.c >> +++ b/libavformat/hlsenc.c >> @@ -259,6 +259,29 @@ typedef struct HLSContext { >> int has_video_m3u8; /* has video stream m3u8 list */ >> } HLSContext; >> >> +static int strftime_expand(const char *fmt, char **dest) >> +{ >> + int r = 1; >> + time_t now0; >> + struct tm *tm, tmpbuf; >> + char *buf; >> + >> + buf = av_mallocz(MAX_URL_SIZE); >> + if (!buf) >> + return AVERROR(ENOMEM); >> + >> + time(&now0); >> + tm = localtime_r(&now0, &tmpbuf); >> + r = strftime(buf, MAX_URL_SIZE, fmt, tm); >> + if (!r) { >> + av_free(buf); >> + return AVERROR(EINVAL); >> + } >> + *dest = buf; >> + >> + return r; >> +} >> + >> static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, >> AVDictionary **options) >> { >> @@ -1660,19 +1683,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) >> ff_format_set_url(oc, filename); >> } else { >> if (c->use_localtime) { >> - time_t now0; >> - struct tm *tm, tmpbuf; >> - int bufsize = strlen(vs->basename) + MAX_URL_SIZE; >> - char *buf = av_mallocz(bufsize); >> - if (!buf) >> - return AVERROR(ENOMEM); >> - time(&now0); >> - tm = localtime_r(&now0, &tmpbuf); >> - ff_format_set_url(oc, buf); >> - if (!strftime(oc->url, bufsize, vs->basename, tm)) { >> + int r; >> + char *expanded = NULL; >> + >> + r = strftime_expand(vs->basename, &expanded); >> + if (r < 0) { >> av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >> - return AVERROR(EINVAL); >> + return r; >> } >> + ff_format_set_url(oc, expanded); >> >> err = sls_flag_use_localtime_filename(oc, c, vs); >> if (err < 0) { >> @@ -2980,6 +2999,19 @@ static int hls_init(AVFormatContext *s) >> return ret; >> } >> >> + if (hls->use_localtime) { >> + int r; >> + char *expanded = NULL; >> + >> + r = strftime_expand(vs->fmp4_init_filename, &expanded); >> + if (r < 0) { >> + av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >> + return r; >> + } >> + av_free(vs->fmp4_init_filename); >> + vs->fmp4_init_filename = expanded; >> + } >> + >> p = strrchr(vs->m3u8_name, '/'); >> if (p) { >> char tmp = *(++p);
> 2020年11月23日 下午3:23,Nikola Pajkovsky <nikola@pajkovsky.cz> 写道: > > Nikola Pajkovsky <nikola@pajkovsky.cz> writes: > >> Nikola Pajkovsky <nikola@pajkovsky.cz> writes: >> >> Ping? > > Ping. Steven, Andreas, can you look at the the latest iteration of the > path? > >>> init.mp4 can be expanded with strftime() the same way as >>> hls_segment_filename. >>> >>> Signed-off-by: Nikola Pajkovsky <nikola@pajkovsky.cz> >>> --- >>> v2: fix memleak on strftime failure >>> v3: use av_free() insted of free() Ok to me >>> >>> doc/muxers.texi | 7 ++++++ >>> libavformat/hlsenc.c | 54 +++++++++++++++++++++++++++++++++++--------- >>> 2 files changed, 50 insertions(+), 11 deletions(-) >>> >>> diff --git a/doc/muxers.texi b/doc/muxers.texi >>> index 813b4678f409..179b9239517b 100644 >>> --- a/doc/muxers.texi >>> +++ b/doc/muxers.texi >>> @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above. >>> @item hls_fmp4_init_filename @var{filename} >>> Set filename to the fragment files header file, default filename is @file{init.mp4}. >>> >>> +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime. >>> +@example >>> +ffmpeg -i in.nut -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8 >>> +@end example >>> +This will produce init like this >>> +@file{1602678741_init.mp4} >>> + >>> @item hls_fmp4_init_resend >>> Resend init file after m3u8 file refresh every time, default is @var{0}. >>> >>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c >>> index cbfd8f7c0d41..3457ed5201bf 100644 >>> --- a/libavformat/hlsenc.c >>> +++ b/libavformat/hlsenc.c >>> @@ -259,6 +259,29 @@ typedef struct HLSContext { >>> int has_video_m3u8; /* has video stream m3u8 list */ >>> } HLSContext; >>> >>> +static int strftime_expand(const char *fmt, char **dest) >>> +{ >>> + int r = 1; >>> + time_t now0; >>> + struct tm *tm, tmpbuf; >>> + char *buf; >>> + >>> + buf = av_mallocz(MAX_URL_SIZE); >>> + if (!buf) >>> + return AVERROR(ENOMEM); >>> + >>> + time(&now0); >>> + tm = localtime_r(&now0, &tmpbuf); >>> + r = strftime(buf, MAX_URL_SIZE, fmt, tm); >>> + if (!r) { >>> + av_free(buf); >>> + return AVERROR(EINVAL); >>> + } >>> + *dest = buf; >>> + >>> + return r; >>> +} >>> + >>> static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, >>> AVDictionary **options) >>> { >>> @@ -1660,19 +1683,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) >>> ff_format_set_url(oc, filename); >>> } else { >>> if (c->use_localtime) { >>> - time_t now0; >>> - struct tm *tm, tmpbuf; >>> - int bufsize = strlen(vs->basename) + MAX_URL_SIZE; >>> - char *buf = av_mallocz(bufsize); >>> - if (!buf) >>> - return AVERROR(ENOMEM); >>> - time(&now0); >>> - tm = localtime_r(&now0, &tmpbuf); >>> - ff_format_set_url(oc, buf); >>> - if (!strftime(oc->url, bufsize, vs->basename, tm)) { >>> + int r; >>> + char *expanded = NULL; >>> + >>> + r = strftime_expand(vs->basename, &expanded); >>> + if (r < 0) { >>> av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >>> - return AVERROR(EINVAL); >>> + return r; >>> } >>> + ff_format_set_url(oc, expanded); >>> >>> err = sls_flag_use_localtime_filename(oc, c, vs); >>> if (err < 0) { >>> @@ -2980,6 +2999,19 @@ static int hls_init(AVFormatContext *s) >>> return ret; >>> } >>> >>> + if (hls->use_localtime) { >>> + int r; >>> + char *expanded = NULL; >>> + >>> + r = strftime_expand(vs->fmp4_init_filename, &expanded); >>> + if (r < 0) { >>> + av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >>> + return r; >>> + } >>> + av_free(vs->fmp4_init_filename); >>> + vs->fmp4_init_filename = expanded; >>> + } >>> + >>> p = strrchr(vs->m3u8_name, '/'); >>> if (p) { >>> char tmp = *(++p); > > -- > Nikola > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Nikola Pajkovsky <nikola@pajkovsky.cz> writes: > Nikola Pajkovsky <nikola@pajkovsky.cz> writes: > >> Nikola Pajkovsky <nikola@pajkovsky.cz> writes: >> >> Ping? > > Ping. Steven, Andreas, can you look at the the latest iteration of the > path? Hey, is there any problem with the patch? >>> init.mp4 can be expanded with strftime() the same way as >>> hls_segment_filename. >>> >>> Signed-off-by: Nikola Pajkovsky <nikola@pajkovsky.cz> >>> --- >>> v2: fix memleak on strftime failure >>> v3: use av_free() insted of free() >>> >>> doc/muxers.texi | 7 ++++++ >>> libavformat/hlsenc.c | 54 +++++++++++++++++++++++++++++++++++--------- >>> 2 files changed, 50 insertions(+), 11 deletions(-) >>> >>> diff --git a/doc/muxers.texi b/doc/muxers.texi >>> index 813b4678f409..179b9239517b 100644 >>> --- a/doc/muxers.texi >>> +++ b/doc/muxers.texi >>> @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above. >>> @item hls_fmp4_init_filename @var{filename} >>> Set filename to the fragment files header file, default filename is @file{init.mp4}. >>> >>> +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime. >>> +@example >>> +ffmpeg -i in.nut -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8 >>> +@end example >>> +This will produce init like this >>> +@file{1602678741_init.mp4} >>> + >>> @item hls_fmp4_init_resend >>> Resend init file after m3u8 file refresh every time, default is @var{0}. >>> >>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c >>> index cbfd8f7c0d41..3457ed5201bf 100644 >>> --- a/libavformat/hlsenc.c >>> +++ b/libavformat/hlsenc.c >>> @@ -259,6 +259,29 @@ typedef struct HLSContext { >>> int has_video_m3u8; /* has video stream m3u8 list */ >>> } HLSContext; >>> >>> +static int strftime_expand(const char *fmt, char **dest) >>> +{ >>> + int r = 1; >>> + time_t now0; >>> + struct tm *tm, tmpbuf; >>> + char *buf; >>> + >>> + buf = av_mallocz(MAX_URL_SIZE); >>> + if (!buf) >>> + return AVERROR(ENOMEM); >>> + >>> + time(&now0); >>> + tm = localtime_r(&now0, &tmpbuf); >>> + r = strftime(buf, MAX_URL_SIZE, fmt, tm); >>> + if (!r) { >>> + av_free(buf); >>> + return AVERROR(EINVAL); >>> + } >>> + *dest = buf; >>> + >>> + return r; >>> +} >>> + >>> static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, >>> AVDictionary **options) >>> { >>> @@ -1660,19 +1683,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) >>> ff_format_set_url(oc, filename); >>> } else { >>> if (c->use_localtime) { >>> - time_t now0; >>> - struct tm *tm, tmpbuf; >>> - int bufsize = strlen(vs->basename) + MAX_URL_SIZE; >>> - char *buf = av_mallocz(bufsize); >>> - if (!buf) >>> - return AVERROR(ENOMEM); >>> - time(&now0); >>> - tm = localtime_r(&now0, &tmpbuf); >>> - ff_format_set_url(oc, buf); >>> - if (!strftime(oc->url, bufsize, vs->basename, tm)) { >>> + int r; >>> + char *expanded = NULL; >>> + >>> + r = strftime_expand(vs->basename, &expanded); >>> + if (r < 0) { >>> av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >>> - return AVERROR(EINVAL); >>> + return r; >>> } >>> + ff_format_set_url(oc, expanded); >>> >>> err = sls_flag_use_localtime_filename(oc, c, vs); >>> if (err < 0) { >>> @@ -2980,6 +2999,19 @@ static int hls_init(AVFormatContext *s) >>> return ret; >>> } >>> >>> + if (hls->use_localtime) { >>> + int r; >>> + char *expanded = NULL; >>> + >>> + r = strftime_expand(vs->fmp4_init_filename, &expanded); >>> + if (r < 0) { >>> + av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >>> + return r; >>> + } >>> + av_free(vs->fmp4_init_filename); >>> + vs->fmp4_init_filename = expanded; >>> + } >>> + >>> p = strrchr(vs->m3u8_name, '/'); >>> if (p) { >>> char tmp = *(++p);
> 2020年11月30日 下午5:29,Nikola Pajkovsky <nikola@pajkovsky.cz> 写道: > > Nikola Pajkovsky <nikola@pajkovsky.cz> writes: > >> Nikola Pajkovsky <nikola@pajkovsky.cz> writes: >> >>> Nikola Pajkovsky <nikola@pajkovsky.cz> writes: >>> >>> Ping? >> >> Ping. Steven, Andreas, can you look at the the latest iteration of the >> path? > > Hey, is there any problem with the patch? I’ve said no problem to me, waiting Andreas :D > >>>> init.mp4 can be expanded with strftime() the same way as >>>> hls_segment_filename. >>>> >>>> Signed-off-by: Nikola Pajkovsky <nikola@pajkovsky.cz> >>>> --- >>>> v2: fix memleak on strftime failure >>>> v3: use av_free() insted of free() >>>> >>>> doc/muxers.texi | 7 ++++++ >>>> libavformat/hlsenc.c | 54 +++++++++++++++++++++++++++++++++++--------- >>>> 2 files changed, 50 insertions(+), 11 deletions(-) >>>> >>>> diff --git a/doc/muxers.texi b/doc/muxers.texi >>>> index 813b4678f409..179b9239517b 100644 >>>> --- a/doc/muxers.texi >>>> +++ b/doc/muxers.texi >>>> @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above. >>>> @item hls_fmp4_init_filename @var{filename} >>>> Set filename to the fragment files header file, default filename is @file{init.mp4}. >>>> >>>> +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime. >>>> +@example >>>> +ffmpeg -i in.nut -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8 >>>> +@end example >>>> +This will produce init like this >>>> +@file{1602678741_init.mp4} >>>> + >>>> @item hls_fmp4_init_resend >>>> Resend init file after m3u8 file refresh every time, default is @var{0}. >>>> >>>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c >>>> index cbfd8f7c0d41..3457ed5201bf 100644 >>>> --- a/libavformat/hlsenc.c >>>> +++ b/libavformat/hlsenc.c >>>> @@ -259,6 +259,29 @@ typedef struct HLSContext { >>>> int has_video_m3u8; /* has video stream m3u8 list */ >>>> } HLSContext; >>>> >>>> +static int strftime_expand(const char *fmt, char **dest) >>>> +{ >>>> + int r = 1; >>>> + time_t now0; >>>> + struct tm *tm, tmpbuf; >>>> + char *buf; >>>> + >>>> + buf = av_mallocz(MAX_URL_SIZE); >>>> + if (!buf) >>>> + return AVERROR(ENOMEM); >>>> + >>>> + time(&now0); >>>> + tm = localtime_r(&now0, &tmpbuf); >>>> + r = strftime(buf, MAX_URL_SIZE, fmt, tm); >>>> + if (!r) { >>>> + av_free(buf); >>>> + return AVERROR(EINVAL); >>>> + } >>>> + *dest = buf; >>>> + >>>> + return r; >>>> +} >>>> + >>>> static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, >>>> AVDictionary **options) >>>> { >>>> @@ -1660,19 +1683,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) >>>> ff_format_set_url(oc, filename); >>>> } else { >>>> if (c->use_localtime) { >>>> - time_t now0; >>>> - struct tm *tm, tmpbuf; >>>> - int bufsize = strlen(vs->basename) + MAX_URL_SIZE; >>>> - char *buf = av_mallocz(bufsize); >>>> - if (!buf) >>>> - return AVERROR(ENOMEM); >>>> - time(&now0); >>>> - tm = localtime_r(&now0, &tmpbuf); >>>> - ff_format_set_url(oc, buf); >>>> - if (!strftime(oc->url, bufsize, vs->basename, tm)) { >>>> + int r; >>>> + char *expanded = NULL; >>>> + >>>> + r = strftime_expand(vs->basename, &expanded); >>>> + if (r < 0) { >>>> av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >>>> - return AVERROR(EINVAL); >>>> + return r; >>>> } >>>> + ff_format_set_url(oc, expanded); >>>> >>>> err = sls_flag_use_localtime_filename(oc, c, vs); >>>> if (err < 0) { >>>> @@ -2980,6 +2999,19 @@ static int hls_init(AVFormatContext *s) >>>> return ret; >>>> } >>>> >>>> + if (hls->use_localtime) { >>>> + int r; >>>> + char *expanded = NULL; >>>> + >>>> + r = strftime_expand(vs->fmp4_init_filename, &expanded); >>>> + if (r < 0) { >>>> + av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); >>>> + return r; >>>> + } >>>> + av_free(vs->fmp4_init_filename); >>>> + vs->fmp4_init_filename = expanded; >>>> + } >>>> + >>>> p = strrchr(vs->m3u8_name, '/'); >>>> if (p) { >>>> char tmp = *(++p); > > -- > Nikola > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". Thanks Steven Liu
diff --git a/doc/muxers.texi b/doc/muxers.texi index 813b4678f409..179b9239517b 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above. @item hls_fmp4_init_filename @var{filename} Set filename to the fragment files header file, default filename is @file{init.mp4}. +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime. +@example +ffmpeg -i in.nut -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8 +@end example +This will produce init like this +@file{1602678741_init.mp4} + @item hls_fmp4_init_resend Resend init file after m3u8 file refresh every time, default is @var{0}. diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index cbfd8f7c0d41..3457ed5201bf 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -259,6 +259,29 @@ typedef struct HLSContext { int has_video_m3u8; /* has video stream m3u8 list */ } HLSContext; +static int strftime_expand(const char *fmt, char **dest) +{ + int r = 1; + time_t now0; + struct tm *tm, tmpbuf; + char *buf; + + buf = av_mallocz(MAX_URL_SIZE); + if (!buf) + return AVERROR(ENOMEM); + + time(&now0); + tm = localtime_r(&now0, &tmpbuf); + r = strftime(buf, MAX_URL_SIZE, fmt, tm); + if (!r) { + av_free(buf); + return AVERROR(EINVAL); + } + *dest = buf; + + return r; +} + static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, AVDictionary **options) { @@ -1660,19 +1683,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) ff_format_set_url(oc, filename); } else { if (c->use_localtime) { - time_t now0; - struct tm *tm, tmpbuf; - int bufsize = strlen(vs->basename) + MAX_URL_SIZE; - char *buf = av_mallocz(bufsize); - if (!buf) - return AVERROR(ENOMEM); - time(&now0); - tm = localtime_r(&now0, &tmpbuf); - ff_format_set_url(oc, buf); - if (!strftime(oc->url, bufsize, vs->basename, tm)) { + int r; + char *expanded = NULL; + + r = strftime_expand(vs->basename, &expanded); + if (r < 0) { av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); - return AVERROR(EINVAL); + return r; } + ff_format_set_url(oc, expanded); err = sls_flag_use_localtime_filename(oc, c, vs); if (err < 0) { @@ -2980,6 +2999,19 @@ static int hls_init(AVFormatContext *s) return ret; } + if (hls->use_localtime) { + int r; + char *expanded = NULL; + + r = strftime_expand(vs->fmp4_init_filename, &expanded); + if (r < 0) { + av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); + return r; + } + av_free(vs->fmp4_init_filename); + vs->fmp4_init_filename = expanded; + } + p = strrchr(vs->m3u8_name, '/'); if (p) { char tmp = *(++p);
init.mp4 can be expanded with strftime() the same way as hls_segment_filename. Signed-off-by: Nikola Pajkovsky <nikola@pajkovsky.cz> --- v2: fix memleak on strftime failure v3: use av_free() insted of free() doc/muxers.texi | 7 ++++++ libavformat/hlsenc.c | 54 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 11 deletions(-)