From patchwork Tue Oct 27 11:28:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikola Pajkovsky X-Patchwork-Id: 23243 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 59F1C44B9C2 for ; Tue, 27 Oct 2020 13:29:08 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 33ABF68A9E1; Tue, 27 Oct 2020 13:29:08 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from box.pajkovsky.cz (box.pajkovsky.cz [168.119.153.206]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0E39B680053 for ; Tue, 27 Oct 2020 13:29:02 +0200 (EET) Received: from authenticated-user (box.pajkovsky.cz [168.119.153.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by box.pajkovsky.cz (Postfix) with ESMTPSA id 2AC0042ED2; Tue, 27 Oct 2020 12:29:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=pajkovsky.cz; s=mail; t=1603798141; bh=BnvYPGPPgA8Xndr9+DPabXjVlqa16mE3tR6MMuPn3+U=; h=From:To:Cc:Subject:Date:From; b=WA/ixLH+wlOgipSiSbEwUPZ4UW0QmWeBqhNL9Y871DBpCSFZd+F+WEvB/w59TvB6a nlMEgAmMdO7cDRRG5tDw1XB5Y1jrknmq4VxeSL8MMlOspqTP+24OuJWJJz7Gm32XTJ a2cbiVB3pPNs5jJC8gyconF4Nsbac3UJRxC60IY37KN1AQvxPu4l+rRHPQfxFYdT94 b4k2Sp0KF7SvVBiYjO3meSYoopxbZR1RA5dlP6V1SG2bwb+GQmZKk3HeZC1dh1Dl6b PESNw6Rl2yaJ0nXSHz6YTMpbi1s2wUv8PMEvUUi4Fl9xvQRyt90/snK/DhyunCkh7e NnCk5v18ZMdNQ== From: Nikola Pajkovsky To: ffmpeg-devel@ffmpeg.org Date: Tue, 27 Oct 2020 12:28:59 +0100 Message-Id: <31ce1f1789ac33712015af217394ef72f016fb16.1603695205.git.nikola@pajkovsky.cz> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3] hlsenc: expand hls_fmp4_init_filename with strftime() X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Steven Liu , Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" init.mp4 can be expanded with strftime() the same way as hls_segment_filename. Signed-off-by: Nikola Pajkovsky --- 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);