Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to video.js 8 #4439

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Upgrade to video.js 8 #4439

wants to merge 2 commits into from

Conversation

unixfox
Copy link
Member

@unixfox unixfox commented Feb 19, 2024

Description

The final plugin that was stopping us from upgrading to a newer video.js version was https://github.com/jfujita/videojs-http-source-selector. There is now a replacement plugin available officially by video.js: https://github.com/videojs/videojs-contrib-quality-menu.

This PR aims to use this new plugin and upgrade to video.js 8.

Drawbacks

Fixes

Confirmed

Unsure

PR depends on

TODO

@raxod502
Copy link

raxod502 commented Mar 9, 2024

Fix or try to understand the reason why video.js is overriding padding-top for .player-dimensions.vjs-fluid

I can answer that one for you, it is because the CSS selector in video.js got slightly more specific due to an unrelated change videojs/video.js#7724 which was released in 7.19.1. Thus the Invidious CSS no longer takes precedence.

Not being a CSS expert myself I don't know what the most future-proof way to increase the precedence of the selector on the Invidious side would be. Adding the extra :not(.vjs-audio-only-mode) conditional would fix it but this is surely the wrong way. In my fork I added !important and that also fixed it, but we all know !important is a bad idea.

@stonerl
Copy link

stonerl commented Mar 15, 2024

Issue #4199 is not fixed. I just tested this PR on macOS 14.4 with Safari 17.4 and still get the error message.

if (!video_data.params.listen && video_data.params.quality === 'dash') {
var quality_menu_button = document.getElementsByClassName('vjs-quality-menu-button');
for (var i = 0; i < quality_menu_button.length; i++) {
quality_menu_button[i].className += ' vjs-icon-cog';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to remove this when videojs-contrib-quality-menu is upgraded to 1.0.2

@unixfox
Copy link
Member Author

unixfox commented Apr 28, 2024

@stonerl

Issue #4199 is not fixed. I just tested this PR on macOS 14.4 with Safari 17.4 and still get the error message.

Maybe an upstream bug: videojs/video.js#8641. Thank you for the info.

@raxod502
Copy link

I use code like this in my fork, it's a combination of your work and my own:

Diff listing
diff --git a/assets/js/player.js b/assets/js/player.js
index 71c5e7da..c83d9d5e 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -18,7 +18,7 @@ var options = {
             'Spacer',
             'captionsButton',
             'audioTrackButton',
-            'qualitySelector',
+            'qualityMenuButton',
             'playbackRateMenuButton',
             'fullscreenToggle'
         ]
@@ -157,6 +157,16 @@ player.on('timeupdate', function () {
     elem_iv_other.href = addCurrentTimeToURL(base_url_iv_other, domain);
 });
 
+player.one('playing', function () {
+
+    if (!video_data.params.listen && video_data.params.quality === 'dash') {
+        var quality_menu_button = document.getElementsByClassName('vjs-quality-menu-button');
+        for (var i = 0; i < quality_menu_button.length; i++) {
+            quality_menu_button[i].className += ' vjs-icon-cog';
+        }
+    }
+});
+
 
 var shareOptions = {
     socials: ['fbFeed', 'tw', 'reddit', 'email'],
@@ -193,42 +203,47 @@ function isMobile() {
 }
 
 if (isMobile()) {
-    player.mobileUi({ touchControls: { seekSeconds: 5 * player.playbackRate() } });
-
-    var buttons = ['playToggle', 'volumePanel', 'captionsButton'];
-
-    if (!video_data.params.listen && video_data.params.quality === 'dash') buttons.push('audioTrackButton');
-    if (video_data.params.listen || video_data.params.quality !== 'dash') buttons.push('qualitySelector');
-
-    // Create new control bar object for operation buttons
-    const ControlBar = videojs.getComponent('controlBar');
-    let operations_bar = new ControlBar(player, {
-      children: [],
-      playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
+    player.mobileUi({
+        touchControls: {
+            seekSeconds: 5 * player.playbackRate(),
+        },
+        fullscreen: {
+            enterOnRotate: false,
+            exitOnRotate: false,
+            lockOnRotate: false,
+            lockToLandscapeOnEnter: false,
+        },
     });
-    buttons.slice(1).forEach(function (child) {operations_bar.addChild(child);});
-
-    // Remove operation buttons from primary control bar
-    var primary_control_bar = player.getChild('controlBar');
-    buttons.forEach(function (child) {primary_control_bar.removeChild(child);});
-
-    var operations_bar_element = operations_bar.el();
-    operations_bar_element.classList.add('mobile-operations-bar');
-    player.addChild(operations_bar);
 
-    // Playback menu doesn't work when it's initialized outside of the primary control bar
-    var playback_element = document.getElementsByClassName('vjs-playback-rate')[0];
-    operations_bar_element.append(playback_element);
-
-    // The share and http source selector element can't be fetched till the players ready.
     player.one('playing', function () {
-        var share_element = document.getElementsByClassName('vjs-share-control')[0];
-        operations_bar_element.append(share_element);
-
-        if (!video_data.params.listen && video_data.params.quality === 'dash') {
-            var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0];
-            operations_bar_element.append(http_source_selector);
-        }
+        var buttons = [
+            'playToggle',
+            'volumePanel',
+            'captionsButton',
+            'audioTrackButton',
+            'qualityMenuButton',
+            'playbackRateMenuButton',
+        ];
+
+        // Create new control bar object for operation buttons
+        const ControlBar = videojs.getComponent('controlBar');
+        let operations_bar = new ControlBar(player, {
+            children: [],
+            name: "mobileOperationsBar",
+            playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
+        });
+        operations_bar.addClass("mobile-operations-bar");
+        player.addChild(operations_bar);
+
+        // Move operation buttons from to secondary control bar
+        var primary_control_bar = player.getChild('controlBar');
+        buttons.forEach(function (child) {
+            const elt = primary_control_bar.getChild(child);
+            primary_control_bar.removeChild(elt);
+            if (child !== "playToggle") {
+                operations_bar.addChild(elt);
+            }
+        });
     });
 }
 
@@ -386,7 +436,7 @@ if (video_data.params.autoplay) {
 }
 
 if (!video_data.params.listen && video_data.params.quality === 'dash') {
-    player.httpSourceSelector();
+    var qualityMenuOptions = {}
 
     if (video_data.params.quality_dash !== 'auto') {
         player.ready(function () {
@@ -409,12 +459,13 @@ if (!video_data.params.listen && video_data.params.quality === 'dash') {
                                 break;
                         }
                 }
-                qualityLevels.forEach(function (level, index) {
-                    level.enabled = (index === targetQualityLevel);
-                });
+                qualityMenuOptions.defaultResolution = (qualityLevels[targetQualityLevel].height + "p");
             });
         });
     }
+
+    console.log(qualityMenuOptions)
+    player.qualityMenu(qualityMenuOptions);
 }
 
 player.vttThumbnails({

It gives me a more navigable user interface where only the fullscreen button is in the bottom bar, and space is saved by moving all the other controls to the mobile operations bar. I found that I was getting some errors with the video.js 8 upgrade before making these changes. It's not a complete solution, however, and I think the quality selector is still a bit broken even with this implementation.

May be helpful.

@unixfox
Copy link
Member Author

unixfox commented May 10, 2024

I was getting some errors with the video.js 8 upgrade before making these changes

What errors? Can you tell us, it's quite important for achieving an ideal upgrade to video.js 8.

I think the quality selector is still a bit broken even with this implementation.

Apart from the Frame skipping bug., I have not found any other bug related to the quality selector. Do you have other ones?

@raxod502
Copy link

What errors? Can you tell us, it's quite important for achieving an ideal upgrade to video.js 8.

Yes, of course, sorry for being vague the first time. I have created a branch on my fork that matches your PR here, rolling back all of the video.js related changes that I had made. For reference, the exact diff from your PR to the branch I used for the following test case is unixfox/invidious@videojs8...raxod502:invidious:rr-without-videojs-hacks.

One problem that I notice almost immediately is that although the control bar renders fine on desktop, I see an unexpected undefined on mobile, and the gear icon does nothing when tapped (Firefox 126.0b6, Android 14, PWA):

image

Using Firefox remote debugger, the following stacktrace appears immediately on page load:

image

The other buttons on the mobile UI work okay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement of an existing feature
Projects
None yet
3 participants