videojs / videojs-contrib-hls

HLS library for video.js
http://videojs.github.io/videojs-contrib-hls/
Other
2.84k stars 793 forks source link

Going back to auto switching after manual possible? #227

Closed hdezela closed 9 years ago

hdezela commented 9 years ago

I've managed to work out how to switch bitrates manually:

    function verPlaylist(i) {
        vidPlayer.hls.selectPlaylist = function() {
            maestro = vidPlayer.hls.playlists.master;
            return maestro.playlists[i];
        };
    }

However, I can't seem to find a way to set it back to automatic, if I return the master playlist back it errors out, emptying the function does nothing...I can't seem to figure it out.

What I'm looking to do is have a switcher where the viewer can select any of the available bitrates (done!) or select "automatic" to give control back to the player.

gkatsev commented 9 years ago

You probably want to keep a reference to the old selectPlaylist before setting it.

var oldSelectPlaylist;
var customPlaylist = function() {
  oldSelectPlaylist = vidPlayer.hls.SelectPlaylist;
  vidPlayer.hls.selectPlaylist = function() {
    maestro = vidPlayer.hls.playlists.master;
    return maestro.playlists[i];
 };
var standardPlayling = function() {
  vidPlay.hls.selectPlaylist = oldSelectPlaylist;
}
hdezela commented 9 years ago

I was afraid you'd say that...when I do that it errors out complaining about this() being undefined and others. It seems to need access to a bunch of other (internally-declared) data to work. I'll try and see if I can re-write it as an external function.

hdezela commented 9 years ago

Well that was simple enough...I thought it was going to be much more trouble.

To return to automatic bandwidth switching you need to set the SelectPlaylist() function to:

        vidPlayer.hls.selectPlaylist = function() {
            var player =
                vidPlayer.player(),
                effectiveBitrate,
                sortedPlaylists = vidPlayer.hls.playlists.master.playlists.slice(),
                bandwidthPlaylists = [],
                i = sortedPlaylists.length,
                variant,
                bandwidthBestVariant,
                resolutionBestVariant;
            sortedPlaylists.sort(videojs.Hls.comparePlaylistBandwidth);
            while (i--) {
                variant = sortedPlaylists[i];
                if (!variant.attributes || !variant.attributes.BANDWIDTH) { continue; }
                effectiveBitrate = variant.attributes.BANDWIDTH * 1.1;
                if (effectiveBitrate < player.hls.bandwidth) {
                    bandwidthPlaylists.push(variant);
                    if (!bandwidthBestVariant) {
                        bandwidthBestVariant = variant;
                    }
                }
            }
            i = bandwidthPlaylists.length;
            bandwidthPlaylists.sort(videojs.Hls.comparePlaylistResolution);
            while (i--) {
                variant = bandwidthPlaylists[i];
                if (!variant.attributes || !variant.attributes.RESOLUTION || !variant.attributes.RESOLUTION.width || !variant.attributes.RESOLUTION.height) { continue; }
                if (variant.attributes.RESOLUTION.width <= 1920 && variant.attributes.RESOLUTION.height <= 1080) { resolutionBestVariant = variant; break; }
            }
            return resolutionBestVariant || bandwidthBestVariant || sortedPlaylists[0];
        };

Although I think it would be easier (cleaner?) to have something built-in that you can just call like

vidPlayer.hls.selectPlaylist = function('auto') {}

Doing that is beyond my JS knowledge though.

dmlap commented 9 years ago

Good to hear @gkatsev's solution worked for you. Closing this one.