aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2021-08-14 20:24:42 +0200
committerTeddy Wing2021-08-14 20:48:50 +0200
commit447ec71e51c3a3db3c756a1479323d9d19b6f259 (patch)
tree5bcb218262560f440dac8100b6075e2c03fa32b1
parent56662c5ea70bdffb8b779085c131a77b1e519a0f (diff)
downloadnetflix-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.js38
-rw-r--r--src/controls.ts4
-rw-r--r--src/fullscreen_credits.ts35
-rw-r--r--src/styles.ts3
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,