videojs / videojs-contrib-quality-levels

Other
154 stars 52 forks source link

Has no quality level / can't select qualities despite overrideNative in Safari desktop #129

Closed shonsirsha closed 2 years ago

shonsirsha commented 2 years ago

Description

In Safari (desktop), the array (qualityLevels()) is empty and thus I cant switch between qualities, even with this options:

const videoJsOptions = {
    autoplay: false,
    preload: "auto",
    controls: true,
    poster: thumbnailURL,
    sources: [
        {
            src: liveURL,
            type: "application/x-mpegURL",
            withCredentials: false,
        },
    ],
    html5: {
        nativeAudioTracks: false,
        nativeVideoTracks: false,
        hls: {
            overrideNative: true,
        },
    },
};

This works well for this person's project (not react though): https://jsfiddle.net/geukvmhn/ -> Check it out in Safari, the qualities are shown.

But it doesn't work at all for me. Basically, I am struggling to override the native HLS engine in Safari (desktop) - more specifically I am struggling to find what are the correct options to override the native HLS engine in Safari.

Here's the full component code

import React, { useRef, useState, useEffect } from "react";
import videojs from "video.js";
import _ from "videojs-contrib-quality-levels";

// those imports are important
import qualitySelector from "videojs-hls-quality-selector";

const VideoPlayerHLS = ({ liveURL, videoId, finishesVideo, thumbnailURL }) => {
    const videoRef = useRef();
    const [player, setPlayer] = useState(undefined);
    const [callFinishVideoAPI, setCallFinishVideoAPI] = useState(false);
    const [vidDuration, setVidDuration] = useState(50000);

    useEffect(() => {
        if (player) {
            player.src({
                src: liveURL,
                type: "application/x-mpegURL",
                withCredentials: false,
            });
            player.poster(thumbnailURL);
            setCallFinishVideoAPI(false);
            setVidDuration(50000);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [videoId, liveURL, thumbnailURL]);

    useEffect(() => {
        if (callFinishVideoAPI) {
            finishesVideo();
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [callFinishVideoAPI]);

    useEffect(() => {
        const videoJsOptions = {
            autoplay: false,
            preload: "auto",
            controls: true,
            poster: thumbnailURL,
            sources: [
                {
                    src: liveURL,
                    type: "application/x-mpegURL",
                    withCredentials: false,
                },
            ],
            html5: {
                hls: {
                    overrideNative: true,
                },
                nativeAudioTracks: false,
                nativeVideoTracks: false,
            },
        };

        const p = videojs(
            videoRef.current,
            videoJsOptions,
            function onPlayerReady() {
                // console.log('onPlayerReady');
            }
        );

        console.log(p.qualityLevels());
        setPlayer(p);
        return () => {
            if (player) player.dispose();
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    useEffect(() => {
        if (player) player.hlsQualitySelector({ displayCurrentQuality: true });
    }, [player]);
    return (
        <div data-vjs-player>
            <video
                ref={videoRef}
                onLoadedMetadata={(e, px) => {
                    // console.log(e.target.duration);
                    setVidDuration(e.target.duration);
                }}
                onTimeUpdate={(e) => {
                    if (e.target.currentTime >= vidDuration - 10) {
                        setCallFinishVideoAPI(true);
                    }
                }}
                className="vidPlayer video-js vjs-default-skin vjs-big-play-centered"
            ></video>
        </div>
    );
};

export default VideoPlayerHLS;

Thanks.

gkatsev commented 2 years ago

I'm actually unable to quality levels in the jsfiddle you've linked above. For your example, I would recommend not putting the sources in the sources option but instead pass it into player.src() after the player is ready instead. Can you try it and also set up a live example on a site like https://codesandbox.io/? It's very hard to figure out the issues without that.

shonsirsha commented 2 years ago

@gkatsev Thank you so much for your reply. Im not changing sources for now, but here's on codesandbox:

https://codesandbox.io/s/quality-changer-m3ne7

On chrome (desktop), works fine.. but Safari (desktop) it doesn't. Exact same behaviour as what I have in my local. Btw im using videojs-hls-quality-selector too - to display the quality selector. But the problem is in safari there's no qualityLevels to beginwith.

Thanks again for your time.

gkatsev commented 2 years ago

Looks like switching from html5.hls.overrideNative to html5.vhs.overrideNative fixes it. While vhs is the new property, hls is supposed to continue working still. Not sure what's up there.

shonsirsha commented 2 years ago

@gkatsev Hey, thanks for your response. The vhs broke its ability to rewind, please see here on Safari:

https://codesandbox.io/s/quality-changer-m3ne7?file=/src/index.js

When you skip forward (lets say to minute 1), and go back (lets say to 30s), u can see that it wont go back, but rather jumps forward and basically the player is broken and cant play anymore.

I believe this is a critical issue. Thanks again.

shonsirsha commented 2 years ago

Hi @gkatsev, firstly, I am sorry, but is this github issue the right place to ask about this bug? I'm currently super stuck with this and would need this to be fixed soon-ish, therefore really appreciate any help. 😓

To re-iterate the problem: vhs fixes the main issue, that it's showing the quality selector on Safari desktop, but breaks the whole player when user does what I described above (my above comment) - which makes this vhs unacceptable to use / unusable.

And.. hls seems to not work anymore as we both discovered.

:/ Any help?? Thanks 🙇‍♂️

gkatsev commented 2 years ago

Sorry, we've been super busy the last couple of weeks. It's still on the backlog and while I want to get back to it soon, it may take some time still, unfortunately.

shonsirsha commented 2 years ago

@gkatsev , thanks for replying. Any updates / do we have any alternative for this? (showing quality levels on Safari desktop as hls and vhs didnt work).

Thanks so much!

gkatsev commented 2 years ago

So, the seeking thing looks like it'll be fixed via https://github.com/videojs/video.js/pull/7527. Though, it's worth noting that we still don't recommend using overrideNative on Safari and recommend relying on the native behavior.

Using hls or vhs should be the same, though, it's not working. Once we fix hls, it'll function the same as if set via vhs. I'll look into it next.

shonsirsha commented 2 years ago

@gkatsev Ah sorry I pointed out the wrong issue in my last comment.

So the issue wasnt about showing the qualityLevels again. That got fixed after using vhs -> overrideNative: true as you said here.

The problem now is just that the option of vhs -> overrideNative: true, which displays the quality levels correctly, actually breaks the seeking mechanism.

DEMO: https://codesandbox.io/s/quality-changer-forked-eb37t?file=/src/index.js

Explanation: When you skip forward (lets say to minute 1), and go back (lets say to 30s), the player wont go back, but rather jumps forward and then it's frozen and just become totally unusable.

Basically, the whole player breaks when user seeks back on a player that uses vhs -> overrideNative: true in Safari Desktop

I think you understood this already, but I just wanted to re-iterate as I mentioned a wrong issue in the last comment.

Thx so much!

gkatsev commented 2 years ago

the option thing will be fixed https://github.com/videojs/http-streaming/pull/1222

As I mentioned, at first glance, it seems like the seeking issue should be fixed via videojs/video.js#7527.

gkatsev commented 2 years ago

The Video.js PR has been merged and is available in 7.17.1.

LuoyeAn commented 2 years ago

The latest version of video.js still has the same issue. Any suggestion here?

gkatsev commented 2 years ago

@TingtingAn can you open a new issue with more details about what's happening? Please include a live minimal test page on codepen or codesandbox. Thanks.