devcshort / react-hls

Simple React component for playing hls/rtmp live streams.
https://www.npmjs.com/package/react-hls-player
MIT License
118 stars 48 forks source link

Add support for iOS web browsers #13

Closed durgendra closed 3 years ago

durgendra commented 3 years ago

This is not working on ios browsers, I guess because hls are natively supported on ios browsers and even hls.js (https://github.com/video-dev/hls.js) has to be handled separately for ios browers

As I am using react-hls, do you have suggestion on what to include in codes to make it work on ios browsers?

                            <ReactHlsPlayer
                                url={this.state.video.hls_url}
                                autoplay={false}
                                controls={true}
                                width="100%"
                                height="auto"
                            />
devcshort commented 3 years ago

It looks like hls.js doesn't support iOS Safari, because iOS doesn't support media source extensions yet. Currently we are using hls.js as the only way of playing the video, so iOS isn't supported by this package.

globalstripe commented 3 years ago

Also doesn't worked in Chrome on IOS, so not a Safari issue. I guess what is really needed on IOS is a fallback to native player.

devcshort commented 3 years ago

Also doesn't worked in Chrome on IOS, so not a Safari issue. I guess what is really needed on IOS is a fallback to native player.

As far as I'm aware, all web browsers on iOS use the same engine that Safari uses. Apple doesn't allow custom web browsers. So even Google Chrome uses Safari's engine under the hood.

Unless something has changed recently

durgendra commented 3 years ago

I moved to react-player and now videos are playing on ios browsers

https://www.npmjs.com/package/react-player

<ReactPlayer className='react-player' url={this.state.video.hls_url} controls={true} width='100%' height='auto' />

devcshort commented 3 years ago

Thanks for sharing that @durgendra

matt-pawley commented 3 years ago

I was able achieve this by using the .isSupported() method from hls.js.

Example React component as follows:

// Other imports
import ReactHlsPlayer from 'react-hls-player';
import HlsJs from 'hls.js';

const Video = () => {
    let videoSource = VIDEO_SOURCE_MP4;

    // Safari browsers (iOS, ipadOS and macOS) have built in HLS support
    if (document.createElement('video').canPlayType('application/vnd.apple.mpegurl')) {
        videoSource = VIDEO_SOURCE_HLS;
    }

    return (
        <div className="video">
            {HlsJs.isSupported() ? (
                <ReactHlsPlayer
                    poster={VIDEO_POSTER}
                    url={VIDEO_SOURCE_HLS}
                    autoplay
                    muted
                    controls
                    loop
                    width="100%"
                />
            ) : (
                <video
                    poster={VIDEO_POSTER}
                    src={videoSource}
                    autoPlay
                    muted
                    controls
                    loop
                    width="100%"
                />
            )}
        </div>
    );
});

Minor gripe that the casing of autoPlay between the video element and react-hls-player library and incompatible so you can't simply spread the common props.

devcshort commented 3 years ago

I was able achieve this by using the .isSupported() method from hls.js.

Example React component as follows:

// Other imports
import ReactHlsPlayer from 'react-hls-player';
import HlsJs from 'hls.js';

const Video = () => {
    let videoSource = VIDEO_SOURCE_MP4;

    // Safari browsers (iOS, ipadOS and macOS) have built in HLS support
    if (document.createElement('video').canPlayType('application/vnd.apple.mpegurl')) {
        videoSource = VIDEO_SOURCE_HLS;
    }

    return (
        <div className="video">
            {HlsJs.isSupported() ? (
                <ReactHlsPlayer
                    poster={VIDEO_POSTER}
                    url={VIDEO_SOURCE_HLS}
                    autoplay
                    muted
                    controls
                    loop
                    width="100%"
                />
            ) : (
                <video
                    poster={VIDEO_POSTER}
                    src={videoSource}
                    autoPlay
                    muted
                    controls
                    loop
                    width="100%"
                />
            )}
        </div>
    );
});

Minor gripe that the casing of autoPlay between the video element and react-hls-player library and incompatible so you can't simply spread the common props.

Noted. I'll try to fix the props issue when I have a bit of extra time. I'll probably see about adding in this functionality as well to the library so it will do the checks of HLS compatibility and fallback to hls.js

devcshort commented 3 years ago

@toughdeveloper I've fixed the props issue in the latest version. The root level of the video player now supports all regular video element props with the proper casing. Another big change is the move from using url to now using src. This should make it easier to use all the common props that you'd expect from a video player. I haven't added the fallback to a regular video component yet when HLS is supported, but that's definitely on the agenda for something I'd like to do.

devcshort commented 3 years ago

Latest version works with Safari, using @toughdeveloper 's recommendation above. Closing this issue. Thank you for providing the solution to this.