diff mbox series

[FFmpeg-devel,v3] hlsenc: expand hls_fmp4_init_filename with strftime()

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

Checks

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

Commit Message

Nikola Pajkovsky Oct. 27, 2020, 11:28 a.m. UTC
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(-)

Comments

Nikola Pajkovsky Nov. 3, 2020, 12:54 p.m. UTC | #1
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 Nov. 23, 2020, 7:23 a.m. UTC | #2
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);
ffmpeg Nov. 23, 2020, 8:32 a.m. UTC | #3
> 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 Nov. 30, 2020, 9:29 a.m. UTC | #4
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);
Liu Steven Nov. 30, 2020, 9:30 a.m. UTC | #5
> 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 mbox series

Patch

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);