diff options
author | Teddy Wing | 2021-08-14 20:24:42 +0200 |
---|---|---|
committer | Teddy Wing | 2021-08-14 20:48:50 +0200 |
commit | 447ec71e51c3a3db3c756a1479323d9d19b6f259 (patch) | |
tree | 5bcb218262560f440dac8100b6075e2c03fa32b1 | |
parent | 56662c5ea70bdffb8b779085c131a77b1e519a0f (diff) | |
download | netflix-immersive-447ec71e51c3a3db3c756a1479323d9d19b6f259.tar.bz2 |
fullscreen_credits.ts: Start getting credits working again after update
Netflix updater their player UI in early August 2021. This caused my
credits handling to stop working. Haven't tested it for series episodes,
only movies so far.
This gets fullscreen credits mostly working again. The only thing wrong
now is that the player controls appear for a few seconds when the
credits are re-maximised.
* Since the player element changed, we have to watch a different element
now. We can still use class names to partially revert the
minimisation.
* The `<video>` element has inline styles that minimise it. We need to
override these now to make it fullscreen.
* Promos are now in `.OriginalsPostPlay-BackgroundTrailer`, which is
rendered in front of the video, so this element must be hidden.
* In order to click the minimised video, we have to click the `<div>`
inside it which the click event is now bound to.
* Added some ideas for hiding the player when the minimised video is
clicked, but haven't solved that part yet. The problem there is that
previously, the controls were always present in the DOM, and hidden
with a class. Now, they're added to and removed from the DOM when
shown and hidden.
-rw-r--r-- | netflix-immersive.user.js | 38 | ||||
-rw-r--r-- | src/controls.ts | 4 | ||||
-rw-r--r-- | src/fullscreen_credits.ts | 35 | ||||
-rw-r--r-- | src/styles.ts | 3 |
4 files changed, 63 insertions, 17 deletions
diff --git a/netflix-immersive.user.js b/netflix-immersive.user.js index 925088b..b55a537 100644 --- a/netflix-immersive.user.js +++ b/netflix-immersive.user.js @@ -32,7 +32,7 @@ var controls = { logger_1.default.debug('hide():', 'Hiding controls'); // When the player is activated, the mouse cursor is shown. hide_cursor(); - var controls_el = document.querySelector('.PlayerControlsNeo__layout.PlayerControlsNeo__layout--active'); + var controls_el = document.querySelector('.watch-video--bottom-controls-container'); logger_1.default.debug('hide():', 'Controls:', controls_el); controls_el .classList @@ -75,24 +75,44 @@ function hide_cursor() { },{"./logger":4}],2:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var controls_1 = require("./controls"); var wait_element_1 = require("./wait_element"); // Prevent credits from being minimised. function init_mutation_observer(player) { + // const controls_observer = new MutationObserver(function(mutation_list) { + // for (var i = 0; i < mutation_list.length; i++) { + // const mutation = mutation_list[i]; + // const player = mutation.target as HTMLElement; + // const controls_el = player.querySelector( + // '.watch-video--bottom-controls-container' + // ) as HTMLElement; + // + // controls_el.parentNode.removeChild(controls_el); + // + // return; + // } + // }); var observer = new MutationObserver(function (mutation_list) { for (var i = 0; i < mutation_list.length; i++) { var mutation = mutation_list[i]; var player_1 = mutation.target; + var video = player_1.querySelector('video'); // The `postplay` class minimises the movie. Remove it if it gets // added to remain in full frame. - if (player_1.classList.contains('postplay')) { - player_1.classList.remove('postplay'); + if (player_1.classList.contains('watch-video--player-view-minimized')) { + player_1.classList.remove('watch-video--player-view-minimized'); + // Resize the video to full frame. Otherwise it will shrink for + // a second until the click event kicks in. + video.style.height = null; + video.style.width = 'inherit'; // Playback controls are removed when postplay is activated. // Re-enable them. - player_1.click(); + var click_area = player_1.children[0]; + click_area.click(); // Activating playback controls makes them visible. Keep them // hidden. - controls_1.default.hide(); + // controls.hide(); + // controls_observer.observe(player, { subtree: true }); + // '.watch-video--bottom-controls-container' return; } } @@ -103,14 +123,14 @@ function init_mutation_observer(player) { } // Initialise the mutation observer when the video player becomes available. function init() { - wait_element_1.default('.NFPlayer.nf-player-container') + wait_element_1.default('.watch-video--player-view') .then(function (player) { init_mutation_observer(player); }); } exports.default = init; -},{"./controls":1,"./wait_element":6}],3:[function(require,module,exports){ +},{"./wait_element":6}],3:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var fullscreen_credits_1 = require("./fullscreen_credits"); @@ -157,7 +177,7 @@ function styles() { var stylesheet = style.sheet; // 2021.08.13: May want to remove `.player-view-childrens`, which is now // replaced by `.advisory-container`. - stylesheet.insertRule("\n\t\t/* \"Back to Browse\" button that appears when credits are minimised. */\n\t\t.OriginalsPostPlay-BackgroundTrailer .BackToBrowse,\n\n\t\t/* Age rating. */\n\t\t.player-view-childrens,\n\t\t.advisory-container,\n\n\t\t/* \"Watch Credits\" button. */\n\t\t[data-uia=\"watch-credits-seamless-button\"],\n\n\t\t/* Skip buttons. */\n\t\ta[aria-label=\"Skip Intro\"],\n\t\ta[aria-label=\"Skip Recap\"],\n\t\ta[aria-label=\"Next Episode\"],\n\t\t[data-uia=\"next-episode-seamless-button\"] {\n\t\t\tvisibility: hidden !important;\n\t\t}", stylesheet.cssRules.length); + stylesheet.insertRule("\n\t\t/* \"Back to Browse\" button that appears when credits are minimised. */\n\t\t.OriginalsPostPlay-BackgroundTrailer .BackToBrowse,\n\n\t\t/* Promo that appears during credis */\n\t\t.OriginalsPostPlay-BackgroundTrailer,\n\n\t\t/* Age rating. */\n\t\t.player-view-childrens,\n\t\t.advisory-container,\n\n\t\t/* \"Watch Credits\" button. */\n\t\t[data-uia=\"watch-credits-seamless-button\"],\n\n\t\t/* Skip buttons. */\n\t\ta[aria-label=\"Skip Intro\"],\n\t\ta[aria-label=\"Skip Recap\"],\n\t\ta[aria-label=\"Next Episode\"],\n\t\t[data-uia=\"next-episode-seamless-button\"] {\n\t\t\tvisibility: hidden !important;\n\t\t}", stylesheet.cssRules.length); stylesheet.insertRule("\n\t\t/* Remove white border around credits. */\n\t\t.NFPlayer.can-resume:hover {\n\t\t\tborder: none !important;\n\t\t}", stylesheet.cssRules.length); } exports.default = styles; diff --git a/src/controls.ts b/src/controls.ts index 4be1752..4e54c40 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Teddy Wing +// Copyright (c) 2020–2021 Teddy Wing // // This file is part of Immersive. // @@ -27,7 +27,7 @@ const controls = { hide_cursor(); const controls_el = document.querySelector( - '.PlayerControlsNeo__layout.PlayerControlsNeo__layout--active' + '.watch-video--bottom-controls-container' ); logger.debug('hide():', 'Controls:', controls_el); diff --git a/src/fullscreen_credits.ts b/src/fullscreen_credits.ts index f558221..f3cefcb 100644 --- a/src/fullscreen_credits.ts +++ b/src/fullscreen_credits.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Teddy Wing +// Copyright (c) 2020–2021 Teddy Wing // // This file is part of Immersive. // @@ -21,23 +21,46 @@ import wait_element from './wait_element'; // Prevent credits from being minimised. function init_mutation_observer (player) { + // const controls_observer = new MutationObserver(function(mutation_list) { + // for (var i = 0; i < mutation_list.length; i++) { + // const mutation = mutation_list[i]; + // const player = mutation.target as HTMLElement; + // const controls_el = player.querySelector( + // '.watch-video--bottom-controls-container' + // ) as HTMLElement; + // + // controls_el.parentNode.removeChild(controls_el); + // + // return; + // } + // }); + const observer = new MutationObserver(function(mutation_list) { for (var i = 0; i < mutation_list.length; i++) { const mutation = mutation_list[i]; const player = mutation.target as HTMLElement; + const video = player.querySelector('video') as HTMLElement; // The `postplay` class minimises the movie. Remove it if it gets // added to remain in full frame. - if (player.classList.contains('postplay')) { - player.classList.remove('postplay'); + if (player.classList.contains('watch-video--player-view-minimized')) { + player.classList.remove('watch-video--player-view-minimized'); + + // Resize the video to full frame. Otherwise it will shrink for + // a second until the click event kicks in. + video.style.height = null; + video.style.width = 'inherit'; // Playback controls are removed when postplay is activated. // Re-enable them. - player.click(); + const click_area = player.children[0] as HTMLElement; + click_area.click(); // Activating playback controls makes them visible. Keep them // hidden. - controls.hide(); + // controls.hide(); + // controls_observer.observe(player, { subtree: true }); + // '.watch-video--bottom-controls-container' return; } @@ -54,7 +77,7 @@ function init_mutation_observer (player) { // Initialise the mutation observer when the video player becomes available. export default function init () { - wait_element('.NFPlayer.nf-player-container') + wait_element('.watch-video--player-view') .then(function(player) { init_mutation_observer(player); }); diff --git a/src/styles.ts b/src/styles.ts index 5a16d6e..3661fff 100644 --- a/src/styles.ts +++ b/src/styles.ts @@ -29,6 +29,9 @@ export default function styles () { /* "Back to Browse" button that appears when credits are minimised. */ .OriginalsPostPlay-BackgroundTrailer .BackToBrowse, + /* Promo that appears during credis */ + .OriginalsPostPlay-BackgroundTrailer, + /* Age rating. */ .player-view-childrens, .advisory-container, |