http-live-streamingmediaelement.js

medialement.js not working for my hls on iphone


Here is my m3u8 file: cat 8.m3u8

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-MEDIA-SEQUENCE:1131
#EXT-X-TARGETDURATION:5
#EXTINF:4.950, no desc
1545049888215.ts
#EXTINF:4.950, no desc
1545049893218.ts

I serve it at as static file at http://104.248.205.68:31339/8.m3u8

I use mediaelemnts.js to run this hls video: jsfiddle

html:

<video width="240" height="160"  
    id="player1" src="http://104.248.205.68:31339/8.m3u8" 
    controls="controls" autoplay preload="auto" muted ></video>

js:

  $('video').mediaelementplayer({});

It works fine on chrome mac os desktop. But not working on iphone 8+ (safari and chrome). No errors in the console. Video just not played, black screen. In the fullscreen mode of video - the same.

At the same time, if I find a random m3u8 on the internet and use mediaelemnts.js to play it, it works well on the iPhone (at least in fullscreen mode) jsfiddle 2.

So I guess something wrong with my m3u8 file since other m3u8s are runnable on the iPhone.

If I open network tab while loading the problem page on Iphone, I see it's downloading the files but not showing video for some reason.

enter image description here

Update

I checked on android: galaxy s5 and galaxy s9+ in chrome: both works.

Update 2

Zip archive with ts files and m3u8: http://104.248.205.68:31339/8.m3u8.zip


Solution

  • When inspecting the media files [1] it can be found that the PMT (Program Map Table) signals that there is audio in the stream, but there are actually no TS packets for audio (i.e. no audio data) present.

    It looks like the player waits for the audio TS packets in order to build a common buffer for both, audio and video, and only then start playback. Since the stream lacks audio data that never happens. To back that up, you can use ffmpeg to remove the audio track from the media segments using the below command and find that playback would work once you do this.

    ffmpeg -i 1545049893218.ts -an -vcodec copy 1545049893218-v.ts

    Further, the reason this problem only manifests in Safari and Chrome on iOS is that in those cases mediaelement.js is using the browser's native capabilities to play HLS, instead of a JavaScript player (like hls.js) which is used on other platforms (e.g. Chrome on desktop) and is more tolerant to such problem cases.

    [1] E.g. using http://thumb.co.il/ or ffprobe


    EDIT:

    While the above may be sufficient to make it work on older Apple mobile devices - I tested on iPhone 6 iOS10 - newer devices seem to be more restrictive. The official HLS Authoring Spec states

    8.11. You MUST provide at least 6 segments in a live/linear playlist.

    which does not seem to be a hard requirement on some iOS versions. However, to ensure it to be working on all versions these requirements should be met.

    I did a quick test on iPhone X with iOS12 and found it would play if at least 3 segments are provided in the playlist by just duplicating the last segment entry.