LL-HLS broadcasting
Hello everyone!
I am trying to make LL-HLS broadcasting work.
I used the demo from webrtc_to_hls and setup partial_segment_duration to 500ms,
and got # Logger.warning("File storage does not support LL-HLS. The partial segment is omitted.")
On further investigation on source code I couldn't find Membrane.HTTPAdaptiveStream.Storages.FileStorage function to store partial segments properly.
How can I achieve LL-HLS with Membrane framework?
PS: Also, for LL-HLS, i believe, the HLS Controller should be slightly different, because it should send not full files but parts of them depending on a request (even when those files are still in editing mode)
6 Replies
HI @kurmetaubanov
The
webrtc_to_hls
demo only handles regular HLS.
We have two projects that use LL-HLS and both of them implement custom storage and controller for LL-HLS.
* Jellyfish (SFU) - https://github.com/jellyfish-dev/jellyfish
* Membrane Live - https://github.com/membraneframework-labs/membrane_liveGitHub
GitHub - jellyfish-dev/jellyfish: General purpose media server. Sup...
General purpose media server. Supports WebRTC, HLS, RTSP, SIP - jellyfish-dev/jellyfish
GitHub
GitHub - membraneframework-labs/membrane_live: Webinar app in React...
Webinar app in React, Phoenix and Membrane. Contribute to membraneframework-labs/membrane_live development by creating an account on GitHub.
wow, that's cool, i am going to watch it now!
hi @karolkonkol
I created HTTPAdaptiveStream.Storage behaviour to handle LL-HLS, the only thing i changed was lines to write partial segments as files using their own names from metadata. That worked for hls.js player, but iPhone still stucks without playing (just blank screen on the player, with progress rolling infinitely).
I went to Apple developer HLS examples pages and iPhone's playlist looks like ranged segments that should be sent with 206 response.
I tried to lookup how that type of storage and controller was implemented in Jellyfish but couldn't trasfer it to my project due to it's ETS logic.
I want to understand, does the Jellyfish LL HLS work for iPhones?
Is there some example of module of Membrane.HTTPAdaptiveStream.Manifest behaviour that can produce Apple type manifest?
Maybe I am wrong and the reason iPhones doesn't play my LLHLS stream is not in the m3u8 file?
I have vast experience with LL-HLS for iphones and I have to say that working around them is a pain in the ass...
Overall, the hls.js is very forgiving and will take almost anything you throw at it. On the other hand Apple's implementation is strongly relying on the specification, it only takes a single MUST mismatch from a spec and the stream becomes unplayable.
You can look at this set of apple's tools: https://developer.apple.com/documentation/http-live-streaming/using-apple-s-http-live-streaming-hls-tools
And look for
mediastreamvalidator
. It will throw tons of errors at you and it has the right to do so.
To give you an example: WebRTC doesn't force you to produce keyframes at regular intervals (where for other methods of streaming you are able to set constant 2 second intervals), if you for instance fail to match expected segment duration (within a small error margin) the iPhones player refuses to play it.Apple Developer Documentation
Using Apple’s HTTP Live Streaming (HLS) Tools | Apple Developer Doc...
Segment your video stream and create media playlists for successful transmission with Apple’s provided tools.
Also another note, Safari won't tell you anything why exactly the stream is not playable, no descriptive error. The best pick is to use a native iPhone app integrating their AVPlayer and try to capture the errors it produces and printing them out.
@Qizot thank you for suggestions and tips and for confirming me that it is a specification thing that doesn't match
Yes I have been using iPhone iOS emulator with Safari Developer tool to debug network API calls and found out it will not tell me the errors but will act itself way different than hls.js
i will have to look at mediastreamvalidator of Apple HLS tools...
I was hoping someone solved this before...) and has correctly working Membrane.HTTPAdaptiveStream.Manifest implementation)