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

Nikola Pajkovsky nikola at pajkovsky.cz
Tue Nov 3 14:54:02 EET 2020


Nikola Pajkovsky <nikola at pajkovsky.cz> writes:

Ping?

> init.mp4 can be expanded with strftime() the same way as
> hls_segment_filename.
>
> Signed-off-by: Nikola Pajkovsky <nikola at 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.
> + at example
> +ffmpeg -i in.nut  -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8
> + at end example
> +This will produce init like this
> + at 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


More information about the ffmpeg-devel mailing list