Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#1642 closed enhancement (fixed)

-f segment: automagically generate #EXTM3U tags to -segment_list generated playlists

Reported by: kelexel Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: segment, HLS, m3u8
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: yes

Description

Summary of the bug:
It is more a feature request actually.
When using -f segment and -segment_list, the produced playlist is not HTTPLiveStreaming friendly.
The request is to add a way to templat'ify the playlists generated with -sgement_list, or to at least give a third "-segment_list_type extm3u" to comply with HLS

When using something like:

ffmpeg .... -f segment -segment_time 5 -segment_list_type flat -segment_list stream.m3u8 -y -segment_format mpegts  stream%05d.ts

Produces a playlist like:

test00001.ts
test00002.ts

We currently can produce playlists of the type -segment_list_type flat or -segment_list_type ext.
Flat corresponds to the HLS requirements BUT, we miss the valuable #EXTM3 tags on the top of the file, like

#EXTM3U
#EXT-X-STREAM-INF:
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:1

test00001.ts
test00002.ts

The above will play fine on iOS (tested via apache & nginx)
(libavformat/hls.c seems to have a few other tags listed.. https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/hls.c#L741-746 )

Other per-file-tags might be useful too, but as you probably guessed, I'm no expert, I leave you wise guys figure that out.

Best regards

Change History (32)

comment:1 follow-up: Changed 4 years ago by kelexel

I came up with a patch to libavformat/segment.c allowing a third -list-type EXTM3U

You can now generate iOS HLS friendly playlists.

http://pastebin.com/pB0TRcJ3

Please review, comment (& merge if you approve ;)

Regards.

comment:2 in reply to: ↑ 1 Changed 4 years ago by saste

  • Analyzed by developer set
  • Keywords m3u8 added
  • Reproduced by developer set
  • Resolution set to fixed
  • Status changed from new to closed

Replying to kelexel:

I came up with a patch to libavformat/segment.c allowing a third -list-type EXTM3U

You can now generate iOS HLS friendly playlists.

http://pastebin.com/pB0TRcJ3

Please review, comment (& merge if you approve ;)

Applied a different variant (I didn't read your reply here, but my variant should be somewhat more generic/robust).

Commit is:

commit e5ae2f912626e72821d6e152dabf7c89fe1f5119
Author: Stefano Sabatini <stefasab@gmail.com>
Date:   Wed Aug 15 11:06:34 2012 +0200

    lavf/segment: add M3U8 list support
    
    Address trac ticket #1642.

comment:3 follow-up: Changed 4 years ago by kelexel

I am sorry, but I think your patch is not fully HLS compliant !

First of, you did not add #EXT-X-TARGETDURATION:X in segment_list_open, you added in in segment_list_close, no clue why. From my tests and compared m3u8 playlists, this tag needs to sit on top, otherwise you cannot use HLS for live (RTMP) transcoding !
Because when live transcoding, we do not have the end of the stream yet, so we are not issuing a segment_list_close until a very long time. But, iOS clients need to know right now about #EXT-X-TARGETDURATION, thus the absolute need to have it in segment_list_open and not in segment_list_close.

Second, I do not understand your per-file generated #EXTINF tags.

Here is the result of what it produced for me:

#EXTM3U
#EXT-X-VERSION:4
#EXTINF:11.217433,
alpha_720p00000.ts
#EXTINF:9.605956,
alpha_720p00001.ts
#EXTINF:9.617756,
alpha_720p00002.ts
#EXTINF:6.033333,
alpha_720p00003.ts
#EXT-X-TARGETDURATION:11
#EXT-X-ENDLIST

First, my segment_time is 10, here we have 11 (no clue why).
Second, I thought #EXTINF should give the duration of each segment, where here, we get wacky, decrementing durations (why?!)

Conclusion, this patch does bring some m3u8 goodness, and is certainly more elegant that my (unexperienced) patch.

But it does not work with live transcoded HLS streams, and produces doubtful m3u8 playlists.

If you want to fix it, move #EXT-X-TARGETDURATION on top, ensure it has a valid segment_time and fix (or explain) the wacky #EXTINF tags

Next time, maybe just have a quick look at the patches proposed.
Even if not being that elegant, they might contain some useful infos.

Thank you.

Last edited 4 years ago by kelexel (previous) (diff)

comment:4 Changed 4 years ago by kelexel

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:5 in reply to: ↑ 3 Changed 4 years ago by saste

  • Resolution set to fixed
  • Status changed from reopened to closed

Replying to kelexel:

I am sorry, but I think your patch is not fully HLS compliant !

First of, you did not add #EXT-X-TARGETDURATION:X in segment_list_open, you added in in segment_list_close, no clue why. From my tests and compared m3u8 playlists, this tag needs to sit on top, otherwise you cannot use HLS for live (RTMP) transcoding !
Because when live transcoding, we do not have the end of the stream yet, so we are not issuing a segment_list_close until a very long time. But, iOS clients need to know right now about #EXT-X-TARGETDURATION, thus the absolute need to have it in segment_list_open and not in segment_list_close.

The format was written based on:
http://tools.ietf.org/html/draft-pantos-http-live-streaming-08

which is the only official M3U8 spec as far as I know. Note that there is no requirement of the tag to be at the top of the file, and since the file is supposed to be read and parsed at once this should not be an issue.

The reason why it is written at the end is because it is much simpler from the coding point of view (you don't know the maximum segment duration until you write all files, so this avoids caching information in the segment).

Second, I do not understand your per-file generated #EXTINF tags.

Here is the result of what it produced for me:

#EXTM3U
#EXT-X-VERSION:4
#EXTINF:11.217433,
alpha_720p00000.ts
#EXTINF:9.605956,
alpha_720p00001.ts
#EXTINF:9.617756,
alpha_720p00002.ts
#EXTINF:6.033333,
alpha_720p00003.ts
#EXT-X-TARGETDURATION:11
#EXT-X-ENDLIST

First, my segment_time is 10, here we have 11 (no clue why).
Second, I thought #EXTINF should give the duration of each segment, where here, we get wacky, decrementing durations (why?!)

This is expected and not wrong (apart from the computation of target duration, which had to be "12" in the example below, patch fixing that already integrated). Please read the segment documentation, keep in mind that video segments are split at key-frames, and it is not in general possible to get predictable durations for each segment.

Conclusion, this patch does bring some m3u8 goodness, and is certainly more elegant that my (unexperienced) patch.

But it does not work with live transcoded HLS streams, and produces doubtful m3u8 playlists.

If you want to fix it, move #EXT-X-TARGETDURATION on top, ensure it has a valid segment_time and fix (or explain) the wacky #EXTINF tags

Next time, maybe just have a quick look at the patches proposed.
Even if not being that elegant, they might contain some useful infos.

My segment patchset predates your patch:
http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/149665

Note that I was not aware of your patch until I opened trac for closing the ticket, otherwise I would have tried to adapt your patch for integration. In general you're advised to send patches to ML if you want to work on them, as they will usually attract more attention.

Thank you.

comment:6 follow-up: Changed 4 years ago by kelexel

Hi, first of all, many thanks for your time invested in this issue.

Now, the real issue resides in the #EXT-X-TARGETDURATION being written at the end of the file.
Because it is only written when ffmpeg exepects to have reached the end of the file, this behavior from your patch will really, definitely, break HLS.

Keep in mind I am talking about transcoding to -f segment a live (RTMP in my case) feed, for which you have no clue of when the feed ends - so no clue of when you will invoke segment_list_close)

All I can do is encourage you to check by yourself, using any source file and -f segment, outputing mpegts files to a dir, and use an iOS device to read said files.

The playlist will be read by the client each time the client will reach the last file specified in the playlist, and keep doing it until it eventually reaches a #EXT-X-ENDLIST) in said playlist.

If the iOS device has no clue of the segment length it should expect, it will miserably fail to read said stream (at least on iOS 5.x)

So, once again, your patch will work for known duration files, i.e.: I'm transcoding a file, because the client will find in the playlist, at the end, both the EXT-X-TARGETDURATION and mostly EXT-X-ENDFILE tags, and all the segments to read the file, so the iOS device and mobile safari will be happy and know where your steam starts, when it ends and in how many segments, and the length of said segments it should be expecting.

I won't argue on the pseuso scarse (I agree) RFC on m3u8.
But real-life tests show that if that tag is not present at the top of the file, it will simply not work.

iOS devices need to know that tag to accept reading the mpeg2ts segments. If it doesn't find that tag it simply throws an error. When you are doing live transcoding of a current video stream, you have no idea when the stream will end, so your only chance is to put that tag in segment_list_open and really not in segment_list_close

I am not arguing who patched what first, I am not a developer, just an aware-user.
All I can say is that if you use my (dirty) patch on previous sources, your iOS device will play a live and pre-recorded stream fine.
But, if you use your patch, than iOS devices will only play pre-recorded streams, and fail to play live-transcoded streams.

That's all I'm trying to point out.

With all due respect to you and the ffmpeg community.

Please consider modifying your patch.

Best regards.

Last edited 4 years ago by kelexel (previous) (diff)

comment:7 Changed 4 years ago by kelexel

Finally, I can only point you towards apple own docs on HLS (after all, we are in this mess because of them), you will see none of their samples look like what your patch is generating as playlist. https://developer.apple.com/library/ios/#technotes/tn2288/_index.html#//apple_ref/doc/uid/DTS40012238

1) EXT-X-TARGETDURATION always sits on top
2) EXTINF always contains the -segment_time, not the real time of the file

Please consider fixing your patch to make it HLS compliant

(And please, this is no ego race, forget my patch, just commit something that you have tested and confirmed working, and you will get my diamonds4ever consideration - even if you probably don't care ;)

Thank you.

Last edited 4 years ago by kelexel (previous) (diff)

comment:8 Changed 4 years ago by kelexel

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:9 in reply to: ↑ 6 Changed 4 years ago by saste

Replying to kelexel:

Hi, first of all, many thanks for your time invested in this issue.

Now, the real issue resides in the #EXT-X-TARGETDURATION being written at the end of the file.
Because it is only written when ffmpeg exepects to have reached the end of the file, this behavior from your patch will really, definitely, break HLS.

Keep in mind I am talking about transcoding to -f segment a live (RTMP in my case) feed, for which you have no clue of when the feed ends - so no clue of when you will invoke segment_list_close)

All I can do is encourage you to check by yourself, using any source file and -f segment, outputing mpegts files to a dir, and use an iOS device to read said files.

The playlist will be read by the client each time the client will reach the last file specified in the playlist, and keep doing it until it eventually reaches a #EXT-X-ENDLIST) in said playlist.

If the iOS device has no clue of the segment length it should expect, it will miserably fail to read said stream (at least on iOS 5.x)

So, once again, your patch will work for known duration files, i.e.: I'm transcoding a file, because the client will find in the playlist, at the end, both the EXT-X-TARGETDURATION and mostly EXT-X-ENDFILE tags, and all the segments to read the file, so the iOS device and mobile safari will be happy and know where your steam starts, when it ends and in how many segments, and the length of said segments it should be expecting.

I won't argue on the pseuso scarse (I agree) RFC on m3u8.
But real-life tests show that if that tag is not present at the top of the file, it will simply not work.

iOS devices need to know that tag to accept reading the mpeg2ts segments. If it doesn't find that tag it simply throws an error. When you are doing live transcoding of a current video stream, you have no idea when the stream will end, so your only chance is to put that tag in segment_list_open and really not in segment_list_close

I see there are several issues here.

First of all, I confirm that the M3U8 feature is not broken, in the sense that it complies with the specifications I read so far (the document I linked before, and the one you proposed), so I still consider this ticket closed.

Second, you are doing some assumptions about M3U8 which are against the specifications, for example about the position of the EXT-X-TARGETDURATION tag. Note that I have no idea of how this RTMP -> HLS thing works at all, and I can't test it. So if you can provide a reproducible failure with the M3U8 generated by ffmpeg, or simply confirm that moving the EXT-X-TARGETDURATION at the begin of the file will fix it, please do.

My assumption was that the M3U8 file was read at once and parsed and converted by the reader into a list of files to read, and the duration information could be retrieved whatever its position was. In case the file is read continuously we can't predict the maximum duration of the segments in the list, not without a crystal ball, so the solution in this case would be to provide a "fake" EXT-X-TARGETDURATION at the begin of the file as you seem to suggest (which would be against M3U8 specifications).

Note that this can be done if it fixes a problem, e.g. by providing a new type m3u8-hls or switch, but note again that this ticket is about M3U8 playlists, and not concerned with the weird additional requirements of live transcoding whatsoever, so it belongs to a separate ticket.

Also I suppose that the -segment_list_size option was designed with that scenario in mind, so maybe you could adapt your setup to make use of that feature.

I am not arguing who patched what first, I am not a developer, just an aware-user
All I can say is that if you use my (dirty) patch on previous sources, your iOS device will play a live and pre-recorded stream fine.

Just to clarify, I'm happy to apply (or even modify/readapt) other people patches, only I care if that things work properly.

comment:10 follow-up: Changed 4 years ago by kelexel

Hi again,

So, a little background, here are my encoding settings:

	cmd="$ffmpeg -threads 2 -i rtmp://1.2.3.4:1935/app/streamName -re -acodec libfaac -ar 44000 -b:a 48k -vcodec libx264 -s 426x250  -b:v 128k -vpre libx264-ipod320 -flags -global_header -map 0 -f segment -segment_time 10 -segment_list_size 10 -segment_list ${stream}_240p.m3u8 -segment_list_type m3u8 -segment_format mpegts ${stream}_240p%05d.ts"

Right now, if using your patch, you end up with such :
http://bit.ly/S9K36g < recorded, working on iOS.
The action to produce such was the following: publish a stream on the rtmp server, start ffmpeg, unpublish the stream on the rtmp server.
Your patch did was you expected from it:

  • invoke segment_list_open when starting to encode
  • receive video & audio stream >> transcode >> segment it
  • invoke segment_list_close when no more rtmp stream is detected

(notice the valid duration on top of the iOS player)

The problem is this typical behavior breaks LIVE streaming

Here is why:
http://bit.ly/MFQqhg < bugged live, not working on iOS
as stated, iOS devices require EXT-X-TARGETDURATION to be readable in the playlist.
problem is right now:

  • invoke segment_list_open
  • receive video & audio streams >> transcode >> segment for an unknown duration, remember this is Live
  • invoke segment_list_close >> uh-oh we've reached the end of the show, previous segments were probably deleted, we broke HLS !!

http://46.105.37.199/hls-bad/live_ok.m3u8 < working live on iOS
Here, EXT-X-TARGETDURATION is at the beginning of the file, notice how the iOS player will not display time (it's because it is in live mode, not record mode), and HLS works fine.
(notice the absence of duration, on top of the iOS player, this is live mode)

Conclusion, EXT-X-TARGETDURATION should REALLY be created by segment_list_open, and NOT by segment_list_close, otherwise, we break HLS

Remember their are several kinds of HLS, mainly record(also known as VOD mode) and live

In record we know the duration of the stream, it' start & end
In live we only know the start of the stream, no clue on its duration

So please, move that simple line to segment_list_open ..

Ps: not sure yet about EXTINF tags, I have to admit I'm unsure what to put there. It seems to work with and without this tag.

PPs: other working HLS setups I've seen use fixed length EXTINF (as previously reported)

PPPs: yes my encoding is really not good I just made a quick and dirty POC so you could see when it plays or not

Best regards.

Last edited 4 years ago by kelexel (previous) (diff)

comment:11 follow-up: Changed 4 years ago by kelexel

Note, in HLS-ilve here is what is happening:

When a client reads an .m3u8 file, and if no #EXT-X-ENDLIST is found in the playlist.m3u8 it's in live mode not vod mode.

In which client, when reaching the last file in the playlist, the client will automagically re-request the playlist until it find a playlist containing the #EXT-X-ENDLIST, in which case the stream won't be considered as "live" anymore.

Said paylist is supposed to have changed, hence -segment_list_limit 10, means we will only keep the last 10 segments of -segment_time 5 duration

Each time the playlist starts a new group of 10x segments, the following tag should be incremented: #EXT-X-MEDIA-SEQUENCE:1

So, on files 0->9, #EXT-X-MEDIA-SEQUENCE:1
On files 10->19 #EXT-X-MEDIA-SEQUENCE:2
And so on

Also, please look at apple docs under Index Files (Playlists): https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/HTTPStreamingArchitecture/HTTPStreamingArchitecture.html#//apple_ref/doc/uid/TP40008332-CH101-SW2

#EXT-X-TARGETDURATION:10

#EXTINF:10,

Which is the format I'm desperately trying to enforce here, and the one you don't want to :(

Last edited 4 years ago by kelexel (previous) (diff)

comment:12 in reply to: ↑ 10 ; follow-up: Changed 4 years ago by cehoyos

Replying to kelexel:

Right now, if using your patch, you end up with such :
http://bit.ly ...

Do not use external resources to describe a problem (they tend to disappear), please post all relevant and necessary information here.

comment:13 in reply to: ↑ 12 Changed 4 years ago by kelexel

Dully noted.

Although these are streams on a temp server, I will need to remove them in a couple of days

Best regards.

comment:14 in reply to: ↑ 11 Changed 4 years ago by saste

Replying to kelexel:

Note, in HLS-ilve here is what is happening:

When a client reads an .m3u8 file, and if no #EXT-X-ENDLIST is found in the playlist.m3u8 it's in live mode not vod mode.

In which client, when reaching the last file in the playlist, the client will automagically re-request the playlist until it find a playlist containing the #EXT-X-ENDLIST, in which case the stream won't be considered as "live" anymore.

Said paylist is supposed to have changed, hence -segment_list_limit 10, means we will only keep the last 10 segments of -segment_time 5 duration

Each time the playlist starts a new group of 10x segments, the following tag should be incremented: #EXT-X-MEDIA-SEQUENCE:1

So, on files 0->9, #EXT-X-MEDIA-SEQUENCE:1
On files 10->19 #EXT-X-MEDIA-SEQUENCE:2
And so on

Also, please look at apple docs under Index Files (Playlists): https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/HTTPStreamingArchitecture/HTTPStreamingArchitecture.html#//apple_ref/doc/uid/TP40008332-CH101-SW2

#EXT-X-TARGETDURATION:10

#EXTINF:10,

Which is the format I'm desperately trying to enforce here, and the one you don't want to :(

Thanks for the nice explanations.

I'm starting to understand how this live Apple thing works, and I see why it is not working in our case.

Basically I addef support to M3U8 playlists, trying to be as faithful as possible to the specification, but that was not compatible with how HLS works.

So, in order to make HLS work we need to:

  1. set defined interval of times. In our case we request that -segment_time will be defined (rather than the exclusive option -segment_times). Issue: we can't generate segments with regular duration, since this will depend on how I-frames are placed in the stream to segment.
  1. put EXT-X-TARGETDURATION at the begin of the file. As per point 1., we can't guarantee that the target duration will be honoured (thus breaking M3U8 specs), and we don't know which will be the maximum duration of the segments in the list. In this case we can "fake" the format and set the time specified by -segment_time as target duration.
  1. not put EXT-X-ENDLIST at the end of the file if the last segment was not reached and -segment_list_size is != 0, and we need to update EXT-X-MEDIA-SEQUENCE per each file list update.

So we need to understand which options will enable this behavior. For sure -segment_list_size should be specified. I'm not sure what should we do when both -segment_list_size and -segment_times are specified, possibly we should abort since I can't see a meaningful behavior in this case, assuming -segment_list_size was meant to deal with HLS.

I'll possibly come with a patch in the next few days, and I'll ask you to test it.

comment:15 follow-up: Changed 4 years ago by kelexel

I see, in essence m3u8(-specs) and HLS are mutually exclusive.

Why not keep the current m3u8 -segment_list_type you already created, and add another -segment_list_type m3u8_hls or just "hls" ?

So whatever your planned use for -segment_list_time, you could have goods from both worlds ?

Also, regarding 3., in some cases of HLS you will want -segment_list_size 0, why ? because HLS allows seek, so in case we are using -segment_list_size 0, no segments will be removed from the list, just incremented, allowing an HLS-friendly client to seek anywhere in the timeline up-to "now".. So it might still be useful to keep this option in HLS case .. (although you are correct, if the -segment_list_size is 0, we only need once EXT-X-MEDIA-SEQUENCE 1, since we don't regenerate the playlist) ..

Best regards.

comment:16 Changed 4 years ago by kelexel

Any news ..?

comment:17 Changed 4 years ago by vel2000

I can confirm this issue.
No device, neither iOS or Android, is able to play a "stream" generated from "live input".
When I patched segment.c, to write "EXT-X-TARGETDURATION" at the beginning of the m3u8, the streams play, but duration is not calculated, so I used a "fake value".
But this is more a dirty hack than anything else. :(
One more thing: if you use

#EXT-X-VERSION:4

VLC 2.0.3 won't play at all, because it expects a version:3
So I had to patch this too...

Last edited 4 years ago by vel2000 (previous) (diff)

comment:18 in reply to: ↑ 15 Changed 4 years ago by saste

Replying to kelexel:

I see, in essence m3u8(-specs) and HLS are mutually exclusive.

Why not keep the current m3u8 -segment_list_type you already created, and add another -segment_list_type m3u8_hls or just "hls" ?

So whatever your planned use for -segment_list_time, you could have goods from both worlds ?

Also, regarding 3., in some cases of HLS you will want -segment_list_size 0, why ? because HLS allows seek, so in case we are using -segment_list_size 0, no segments will be removed from the list, just incremented, allowing an HLS-friendly client to seek anywhere in the timeline up-to "now".. So it might still be useful to keep this option in HLS case .. (although you are correct, if the -segment_list_size is 0, we only need once EXT-X-MEDIA-SEQUENCE 1, since we don't regenerate the playlist) ..

Best regards.

Added an option -segment_list_live which should address the issue.

Would you mind to comment on ffmpeg-devel:
http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/150549

I'll attach the patches to test, which I posted to ffmpeg-devel, for your convenience.

comment:19 Changed 4 years ago by kelexel

saste: ahh, nice!
will test and report asap.

comment:20 Changed 4 years ago by kelexel

Ok, have tested on Master, applied the 3 attached patches (seems the sources changed a bit since you created your patch, but it succeeded with a few offsets)

And, I'm glad to report IT WORKS!
I've been "watching" myself for 30+ minutes on my iphone, with no issue so far.

For the record, here is my encoding line, I'm sure it can be improved tho (note, it's an extract from a script that handles an arbitrary $stream var ..):

ffmpeg -i rtmp://foo.ext/app/stream -re -acodec libfaac -ar 44000 -b:a 48k -vcodec libx264 -s 426x250  -b:v 128k -vpre libx264-ipod320 -flags -global_header -map 0 -f segment -segment_time 10 -segment_list_size 10 -segment_list ${stream}_240p.m3u8 -segment_list_live 1 -segment_list_type m3u8 -segment_format mpegts ${stream}_240p%05d.ts"

I think you can safely merge them to Master :)

Note, if someone using FreeBSD (-9 here) ever reads this thread, DO NOT attempt to compile ffmpeg Master using the built-in gcc-4.2 (as discussed here: http://ffmpeg.org/trac/ffmpeg/ticket/1464 ), as it will result in corrupt decoding of h264 streams.
Instead install another version (tested and working with gcc-4.6 from port tree), and add --enable-cc=/usr/local/bin/gcc46 to your compile line.

Last edited 4 years ago by kelexel (previous) (diff)

comment:21 Changed 4 years ago by kelexel

I might have spotted an issue.

Take the following example:

ffmpeg -i rtmp://foo.ext/app/stream ... -f ... -segment_list_live

Here we're transcoding a live rtmp feed, ok.

Problem:

If broadcaster disconnects from RTMP server (connection issue, whatever)
ffmpeg assumes the stream is ending, thus adds EXT-X-ENDLIST tag to the playlist.

HLS clients when seeing this tag will go from live > record mode, so the stream playback will end on the HLS clients.

Now, broadcaster comes back online, streams again to the rtmpd, and we re-start ffmpeg.
A new playlist is normally generated ... all *seems* fine BUT(!!!):

If HLS clients "refresh" the url, they will most likely pick the cached playlist rather than the one.. And since the cached playlist has EXT-X-ENDLIST in it, it will just "replay" the last containing segments and totally ignore the new server-side playlist.

So, in theory, if using -segment_list_live it is a bad idea to write EXT-X-ENDLIST..

BUT (hehe), there *seems* to be another -useful- tag, namely "#EXT-X-ALLOW-CACHE:1/0"
I think it's mostly meant for caching mpegts files, but might also work with the playlists.

Will test and report my findings..

Version 0, edited 4 years ago by kelexel (next)

comment:22 follow-up: Changed 4 years ago by kelexel

Confirmed.

If you add #EXT-X-ALLOW-CACHE:0 in the top of the playlist, it (as long as mpegts files) are not cached by the client.

So if broadcaster drops, and ffmpeg transcoding stops, and broadcaster comes back, and ffmpeg transcoding is restarted, hitting refresh on the clients will fetch a fresh playlist instead of the locally cached one.

May I suggest a -segment_no_cache setting that would append #EXT-X-ALLOW-CACHE:0 to the top of the playlist ?

comment:23 in reply to: ↑ 22 Changed 4 years ago by saste

Replying to kelexel:

Confirmed.

If you add #EXT-X-ALLOW-CACHE:0 in the top of the playlist, it (as long as mpegts files) are not cached by the client.

So if broadcaster drops, and ffmpeg transcoding stops, and broadcaster comes back, and ffmpeg transcoding is restarted, hitting refresh on the clients will fetch a fresh playlist instead of the locally cached one.

May I suggest a -segment_no_cache setting that would append #EXT-X-ALLOW-CACHE:0 to the top of the playlist ?

Not sure about this. I could automatically set #EXT-X-ALLOW-CACHE to 0 if live=1, or adopt a new flag to add to live, so that it would be -segment_list_flags +live-cache (in this case it would be better to set flags rather than separate _live, _cache options etc to have a shorter command line and ease extensibility).

Also, now that I think at it, I wonder if live/cache should be rather considered *segment* flags rather than *segment list* flags (but I tend to prefer the latter).

comment:24 follow-up: Changed 4 years ago by kelexel

Well, I'ld say it's up to you.
One thing is certain, as you stated in first part, if live=1 than, in theory we would require the EXT-X-ALLOW-CACHE 0 ..
Also, I do agree with you, this is relative to the playlist, not the segment itself, so I (IMO) would rather have it for *segement list* rather than *segment* ...

#edit: understood re "-segment_list_flags +live-cache" think it's a great idea!
one could then set +live-cache or +live+cache (or simply +live-cache and +live) as option ?

can't wait to see this merged to Master ;)

Last edited 4 years ago by kelexel (previous) (diff)

comment:25 in reply to: ↑ 24 Changed 4 years ago by saste

Replying to kelexel:

Well, I'ld say it's up to you.
One thing is certain, as you stated in first part, if live=1 than, in theory we would require the EXT-X-ALLOW-CACHE 0 ..
Also, I do agree with you, this is relative to the playlist, not the segment itself, so I (IMO) would rather have it for *segement list* rather than *segment* ...

#edit: understood re "-segment_list_flags +live-cache" think it's a great idea!
one could then set +live-cache or +live+cache (or simply +live-cache and +live) as option ?

can't wait to see this merged to Master ;)

Bump. Please try the attached patch.

comment:26 Changed 4 years ago by arut

kelexel, thanks a lot for your hard work towards native HLS support in ffmpeg.

There's another issue with HLS playlist. Playlist generation in ffmpeg is obviously not atomic. So if you serve ffmpeg-generated files with nginx a half-filled (or just empty?) playlist can arrive to a client. The atomic way is tempfile-on-the-same-fs/rename. I wish somebody could test that on a high-load server.

comment:27 Changed 4 years ago by saste

  • Resolution set to fixed
  • Status changed from reopened to closed

Should be fixed in:

commit 00d516454c77a77d11c97099cba069030d82a7cb
Author: Stefano Sabatini <stefasab@gmail.com>
Date:   Sat Sep 1 18:01:51 2012 +0200

    lavf/segment: add segment_list_flags option
    
    Allow to specify options affecting the segment list generation.
    
    In particular: add +live and +cache flags.
    
    For a full discussion read trac ticket #1642:
    http://ffmpeg.org/trac/ffmpeg/ticket/1642
    
    Also add live M3U8 generation example.

Please reopen the ticket if you have issues with it.

comment:28 Changed 4 years ago by kelexel

@arut: I have a quick and dirty fix for this.
ffmpeg generates 4x HLS streams for me: $name_240p, $name_360p, $name_480p, $name_720p
What I do is in the script that I use to launch ffmpeg, I first fork in bg a tiny sleeping function.
Said function waits like 25secs, than looks for .ts segments for at least 1 of these playlists. If found, it generates a multi-bitrate playlist as $name.m3u8 which i than link to iOS clients.
Meaning iOS clients seeing the $name.m3u8 will always have access to existing playlists/segments..

On a side note, can someone please test the above patch and playback on iOS ? More precisely audio playback ? I am trying to troubleshoot something on my end..
Thanks !

Last edited 4 years ago by kelexel (previous) (diff)
Note: See TracTickets for help on using tickets.