Closed oelbaga closed 2 years ago
hi facing the same issue, any solution?
Hi @oelbaganwg and @piyushsharma21
HLS.js relies on HTML5 video and MediaSource Extensions for playback.
All iPhone browsers (iOS) do not have MediaSourceExtension available, and therefore Hls.js will not work. If you check Hls.isSupported()
on an iPhone you will see that function returns false
.
Here's an example in the README that shows how to handle this: https://github.com/video-dev/hls.js#embedding-hlsjs,
See this part, in particular:
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSrc;
}
And just to add color to @dylanjha's helpful comment - on iOS you specifically need to NOT initialize Hls.js on the video element. (by checking Hls.isSupported()
)
iOS can use the normal <video><source></video>
HTML since Safari has native HLS support. Initializing Hls.js on the <video>
will prevent the native HLS functionality from working at all.
My iPhone 10 does not even work with native HLS, it says not supported. So I have to load the default mp4 video, which is 400Mb and this gives me 206 error...Any clue?
@piyushsharma21
This solution didn't work for me because Hls.isSupported
always returned true. i made the following adjustments to make it work:
import Hls from "hls.js";
import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
interface PlayerProps {
src?: string;
poster: string;
onPlay(): void;
onPlayFailed(): void;
}
export const Player = forwardRef<{}, PlayerProps>(({ src, poster, onPlay, onPlayFailed }, ref) => {
const videoRef = useRef<HTMLVideoElement | null>(null);
const hlsRef = useRef<Hls | null>(null);
useEffect(() => {
if (!src || !videoRef.current) return;
const supportHLS = Boolean(videoRef.current.canPlayType("application/vnd.apple.mpegurl"));
if (supportHLS) {
videoRef.current.src = src;
videoRef.current.play().then(onPlay).catch(onPlayFailed);
} else {
hlsRef.current = new Hls();
const hls = hlsRef.current;
hls.on(Hls.Events.MEDIA_ATTACHED, function () {
videoRef.current!.play().then(onPlay).catch(onPlayFailed);
});
hls.loadSource(src);
hls.attachMedia(videoRef.current);
return () => {
hls.destroy();
};
}
}, [src]);
useImperativeHandle(ref, () => videoRef.current!, []);
return (
<video className="w-full h-full object-cover" playsInline ref={videoRef} poster={poster}>
<source src={src} type="application/x-mpegURL"></source>
</video>
);
});
Hls.isSupported always returned true
iOS versions 17.1 and up are supported since hls.js@v1.5.0 using ManagedMediaSource:
Please file a new bug if isSupported
returns true and playback with HLS.js is not comparable to Safari's built-in HLS support.
The latest release of HLS.js as of this writing is v1.5.7.
i made the following adjustments to make it work
This is good if you prefer to use built-in HLS support when available. Note that some platforms with built-in HLS support return true for HTMLMediaElement.canPlayType("application/vnd.apple.mpegurl")
, which do not have the same level of HLS support as HLS.js or Safari. Test the built-in HLS support in Android and Edge browsers before using them over HLS.js.
Ok, setting the video element src directly to something like XXXXXXX.m3u8 works, but what if it included multiple quality levels and of course ability to set the level manually is needed? setting it in hls.js is very straightforward, but what about ios devices that doesn't support hls.js?
setting it in hls.js is very straightforward, but what about ios devices that doesn't support hls.js?
Unfortunately the native video element on iOS, which supports .m3u8
sources does not have a quality level selector nor an API that I know of to manually set the quality level
What version of Hls.js are you using?
1.0.11
What browser (including version) are you using?
Safari
What OS (including version) are you using?
IOS 14 & 15
Test stream
https://hls-js.netlify.app/demo/
Configuration
Additional player setup steps
No response
Checklist
Steps to reproduce
Expected behaviour
Embedded video should play
What actually happened?
Video player doesn't play video
Console output
Chrome media internals output
No response