[FFmpeg-devel] [PATCH] delete the old segment file from hls list

Steven Liu lingjiujianke at gmail.com
Sat Aug 30 05:27:12 CEST 2014


On Aug 28, 2014, at 4:52 AM, Anshul <anshul.ffmpeg at gmail.com> wrote:

> On August 22, 2014 8:01:20 AM IST, Steven Liu <lingjiujianke at gmail.com> wrote:
>> repost new patch:
>> 
>> when update the hls m3u8 list, the old file is not unlinked
>> this patch can do this operation
>> delete the old ts segment which not show in m3u8,
>> use hls_sync_list.
>> 
>> Signed-off-by: Steven Liu <qi.liu at chinacache.com>
>> ---
>> libavformat/hlsenc.c |   15 ++++++++++++++-
>> 1 files changed, 14 insertions(+), 1 deletions(-)
>> 
>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> index 11f1e5b..fc1063e 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -30,6 +30,10 @@
>> 
>> #include "avformat.h"
>> #include "internal.h"
>> +#if HAVE_UNISTD_H
>> +#include <unistd.h>
>> +#endif
>> +
>> 
>> typedef struct HLSSegment {
>>    char filename[1024];
>> @@ -50,6 +54,7 @@ typedef struct HLSContext {
>>    float time;            // Set by a private option.
>>    int max_nb_segments;   // Set by a private option.
>>    int  wrap;             // Set by a private option.
>> +    int  sync_list;
>> 
>>    int64_t recording_time;
>>    int has_video;
>> @@ -96,6 +101,7 @@ static int hls_mux_init(AVFormatContext *s)
>> static int hls_append_segment(HLSContext *hls, double duration)
>> {
>>    HLSSegment *en = av_malloc(sizeof(*en));
>> +    int ret = 0;
>> 
>>    if (!en)
>>        return AVERROR(ENOMEM);
>> @@ -115,7 +121,13 @@ static int hls_append_segment(HLSContext *hls,
>> double
>> duration)
>> if (hls->max_nb_segments && hls->nb_entries >= hls->max_nb_segments) {
>>        en = hls->segments;
>>        hls->segments = en->next;
>> -        av_free(en);
>> +        if (hls->sync_list) {
>> +            ret = unlink(en->filename);
>> +            if (ret < 0) {
>> +                av_log(hls->avf, AV_LOG_WARNING, "remove %s failed\n",
>> en->filename);
>> +            }
>> +        }
>> +        av_free(en);
>>    } else
>>        hls->nb_entries++;
>> 
>> @@ -340,6 +352,7 @@ static const AVOption options[] = {
>>    {"hls_list_size", "set maximum number of playlist entries",
>> OFFSET(max_nb_segments),    AV_OPT_TYPE_INT,    {.i64 = 5},     0,
>> INT_MAX,
>> E},
>>    {"hls_wrap",      "set number after which the index wraps",
>> OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
>>    {"hls_base_url",  "url to prepend to each playlist entry",
>> OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E},
>> +    {"hls_sync_list", "remove old ts segment for sync the file with
>> the
>> m3u8 list",  OFFSET(sync_list),    AV_OPT_TYPE_INT,    {.i64 = 0},    
>> 0,
>> INT_MAX, E},
>>    { NULL },
>> };
>> 
>> --
>> 1.7.1
>> 
>> 
>> 
>> 2014-08-21 16:51 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:
>> 
>>> Hi Stefano,
>>> if unistd is not available under Linux,
>>> it will output error message when compile the source code.
>>> 
>>>      [root at testrtmp ffmpeg]# make
>>> CC      libavformat/hlsenc.o
>>> libavformat/hlsenc.c: In function ‘hls_append_segment’:
>>> libavformat/hlsenc.c:125: error: implicit declaration of function
>> ‘unlink’
>>> make: *** [libavformat/hlsenc.o] Error 1
>>> [root at testrtmp ffmpeg]#
>>> 
>>> 
>>> 
>>> the follow is the new patch:
>>> 
>>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>>> index 11f1e5b..fc1063e 100644
>>> 
>>> --- a/libavformat/hlsenc.c
>>> +++ b/libavformat/hlsenc.c
>>> @@ -30,6 +30,10 @@
>>> 
>>> #include "avformat.h"
>>> #include "internal.h"
>>> +#if HAVE_UNISTD_H
>>> +#include <unistd.h>
>>> +#endif
>>> +
>>> 
>>> typedef struct HLSSegment {
>>>     char filename[1024];
>>> @@ -50,6 +54,7 @@ typedef struct HLSContext {
>>>     float time;            // Set by a private option.
>>>     int max_nb_segments;   // Set by a private option.
>>>     int  wrap;             // Set by a private option.
>>> +    int  sync_list;        // Set by a private option.
>>> 
>>>     int64_t recording_time;
>>>     int has_video;
>>> @@ -96,6 +101,7 @@ static int hls_mux_init(AVFormatContext *s)
>>> 
>>> static int hls_append_segment(HLSContext *hls, double duration)
>>> {
>>>     HLSSegment *en = av_malloc(sizeof(*en));
>>> +       int ret = 0;
>>> 
>>>     if (!en)
>>>         return AVERROR(ENOMEM);
>>> @@ -115,7 +121,13 @@ static int hls_append_segment(HLSContext *hls,
>> double
>>> duration)
>>> 
>>>     if (hls->max_nb_segments && hls->nb_entries >=
>> hls->max_nb_segments) {
>>>         en = hls->segments;
>>>         hls->segments = en->next;
>>> -        av_free(en);
>>> +        if (hls->sync_list) {
>>> +            ret = unlink(en->filename);
>>> +            if (ret < 0) {
>>> +                av_log(hls->avf, AV_LOG_WARNING, "remove %s
>> failed\n",
>>> en->filename);
>>> +            }
>>> +        }
>>> +           av_free(en);
>>>     } else
>>>         hls->nb_entries++;
>>> 
>>> @@ -340,6 +352,7 @@ static const AVOption options[] = {
>>>     {"hls_list_size", "set maximum number of playlist entries",
>>> OFFSET(max_nb_segments),    AV_OPT_TYPE_INT,    {.i64 = 5},     0,
>> INT_MAX,
>>> E},
>>>     {"hls_wrap",      "set number after which the index wraps",
>>> OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
>>>     {"hls_base_url",  "url to prepend to each playlist entry",
>>> OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E},
>>> +    {"hls_sync_list", "remove old ts segment for sync the file with
>> the
>>> m3u8 list",  OFFSET(sync_list),    AV_OPT_TYPE_INT,    {.i64 = 0},   
>> 0,
>>> INT_MAX, E},
>>>     { NULL },
>>> };
>>> 
>>> If you want sync the file with the m3u8 list, please use the
>> hls_sync_list
>>> parameter, default it is 0, and !0 is enable the sync operation.
>>> 
>>> Thanks,
>>> 
>>> 
>>> 
>>> 2014-08-14 18:25 GMT+08:00 Stefano Sabatini <stefasab at gmail.com>:
>>> 
>>> On date Monday 2014-08-11 17:39:37 +0800, Steven Liu encoded:
>>>>> Hi Guys,
>>>>> 
>>>>>     The FFmpeg hls module can make m3u8 and ts, but it dosen't
>> delete
>>>> the
>>>>> old ts segment file.
>>>>>      If always run this module, the disk will full, so this patch
>> can
>>>> fix
>>>>> the problem.
>>>>>      When update the segment list m3u8 file, it will delete the
>> ts
>>>> segment
>>>>> out range from the list file.
>>>>> 
>>>>>     before use this patch:
>>>>> [root at localhost ffmpeg]# ls *.ts *.m3u8
>>>>> a0.ts  a10.ts  a11.ts  a12.ts  a13.ts  a14.ts  a15.ts  a16.ts 
>> a17.ts
>>>>> a18.ts  a19.ts  a1.ts  a20.ts  a2.ts  a3.ts  a4.ts  a5.ts  a6.ts 
>> a7.ts
>>>>> a8.ts  a9.ts  a.m3u8
>>>>> [root at localhost ffmpeg]# cat a.m3u8
>>>>> #EXTM3U
>>>>> #EXT-X-VERSION:3
>>>>> #EXT-X-TARGETDURATION:11
>>>>> #EXT-X-MEDIA-SEQUENCE:16
>>>>> #EXTINF:10.427075,
>>>>> a16.ts
>>>>> #EXTINF:10.427075,
>>>>> a17.ts
>>>>> #EXTINF:10.427075,
>>>>> a18.ts
>>>>> #EXTINF:10.427075,
>>>>> a19.ts
>>>>> #EXTINF:3.670330,
>>>>> a20.ts
>>>>> #EXT-X-ENDLIST
>>>>> [root at localhost ffmpeg]#
>>>>> 
>>>>> after use this patch:
>>>>> [root at localhost ffmpeg]# ls *.ts *.m3u8
>>>>> a10.ts  a11.ts  a12.ts  a13.ts  a9.ts  a.m3u8
>>>>> [root at localhost ffmpeg]# cat a.m3u8
>>>>> #EXTM3U
>>>>> #EXT-X-VERSION:3
>>>>> #EXT-X-TARGETDURATION:11
>>>>> #EXT-X-MEDIA-SEQUENCE:9
>>>>> #EXTINF:10.427075,
>>>>> a9.ts
>>>>> #EXTINF:10.427075,
>>>>> a10.ts
>>>>> #EXTINF:10.427075,
>>>>> a11.ts
>>>>> #EXTINF:10.427075,
>>>>> a12.ts
>>>>> #EXTINF:2.335665,
>>>>> a13.ts
>>>>> #EXT-X-ENDLIST
>>>>> [root at localhost ffmpeg]#
>>>>> 
>>>>> -------------------------------------------
>>>>> The patch context:
>>>>> 
>>>>> when update the hls m3u8 list, the old file is not unlinked
>>>>> this patch can do this operation
>>>>> 
>>>>> Signed-off-by: Steven Liu <qi.liu at chinacache.com>
>>>>> ---
>>>>> libavformat/hlsenc.c |    5 +++++
>>>>> 1 files changed, 5 insertions(+), 0 deletions(-)
>>>>> 
>>>>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>>>>> index 11f1e5b..2ee0970 100644
>>>>> --- a/libavformat/hlsenc.c
>>>>> +++ b/libavformat/hlsenc.c
>>>>> @@ -30,6 +30,10 @@
>>>>> 
>>>>> #include "avformat.h"
>>>>> #include "internal.h"
>>>>> +#if HAVE_UNISTD_H
>>>>> +#include <unistd.h>
>>>>> +#endif
>>>>> +
>>>>> 
>>>>> typedef struct HLSSegment {
>>>>>     char filename[1024];
>>>>> @@ -115,6 +119,7 @@ static int hls_append_segment(HLSContext *hls,
>>>> double
>>>>> duration)
>>>>>     if (hls->max_nb_segments && hls->nb_entries >=
>>>> hls->max_nb_segments) {
>>>>>         en = hls->segments;
>>>>>         hls->segments = en->next;
>>>>> +        unlink(en->filename);
>>>> 
>>>> Check for the return value, and log an explicit error message in
>> case
>>>> of failure.
>>>> 
>>>>>         av_free(en);
>>>>>     } else
>>>>>         hls->nb_entries++;
>>>> 
>>>> Also, in order not to alter the standard behavior, I think it might
>> be
>>>> safer to add an option to enable this behavior. Also, what happens
>> if
>>>> unistd.h is not available?
>>>> --
>>>> FFmpeg = Frightening and Forgiving Monstrous Proud Elastic Gadget
>>>> _______________________________________________
>>>> ffmpeg-devel mailing list
>>>> ffmpeg-devel at ffmpeg.org
>>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>>> 
>>> 
>>> 
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> Why not use hls_wrap option, which gives you the same behavior.
> 
> I achive same thing using hls_wrap.
> 
> -Anshul
> 
> 
Hi Anshul,

	Because if want remove the old segment ts file, must use hls_wrap and hls_list_size, otherwise the hls_wrap can not remove the 
	file which is not in the m3u8 list.

	So this patch can do it by just one option.


Steven


More information about the ffmpeg-devel mailing list