// ==UserScript== // @name Netflix Plus // @name:ja Netflix Plus // @name:zh-CN Netflix Plus // @name:zh-TW Netflix Plus // @namespace http://tampermonkey.net/ // @version 1.15 // @description Enable best audio and video and more features on Netflix // @description:ja Netflixで最高の音質と画質、そしてもっと多くの機能を体験しましょう // @description:zh-CN 在 Netflix 上开启最佳音视频质量和更多功能 // @description:zh-TW 在 Netflix 上啓用最佳影音品質和更多功能 // @author TGSAN // @match https://www.netflix.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=netflix.com // @run-at document-start // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @downloadURL none // ==/UserScript== (async () => { "use strict"; let windowCtx = self.window; if (self.unsafeWindow) { console.log("[Netflix Plus] use unsafeWindow mode"); windowCtx = self.unsafeWindow; } else { console.log("[Netflix Plus] use window mode (your userscript extensions not support unsafeWindow)"); } const Event = class { constructor(script, target) { this.script = script; this.target = target; this._cancel = false; this._replace = null; this._stop = false; } preventDefault() { this._cancel = true; } stopPropagation() { this._stop = true; } replacePayload(payload) { this._replace = payload; } }; let callbacks = []; windowCtx.addBeforeScriptExecuteListener = (f) => { if (typeof f !== "function") { throw new Error("Event handler must be a function."); } callbacks.push(f); }; windowCtx.removeBeforeScriptExecuteListener = (f) => { let i = callbacks.length; while (i--) { if (callbacks[i] === f) { callbacks.splice(i, 1); } } }; const dispatch = (script, target) => { if (script.tagName !== "SCRIPT") { return; } const e = new Event(script, target); if (typeof windowCtx.onbeforescriptexecute === "function") { try { windowCtx.onbeforescriptexecute(e); } catch (err) { console.error(err); } } for (const func of callbacks) { if (e._stop) { break; } try { func(e); } catch (err) { console.error(err); } } if (e._cancel) { script.textContent = ""; script.remove(); } else if (typeof e._replace === "string") { script.textContent = e._replace; } }; const observer = new MutationObserver((mutations) => { for (const m of mutations) { for (const n of m.addedNodes) { dispatch(n, m.target); } } }); observer.observe(document, { childList: true, subtree: true, }); const menuItems = [ ["setMaxBitrate", "Automatically select best bitrate available"], ["useallSub", "Show all audio-tracks and subs"], ["closeimsc", "Use SUP subtitle replace IMSC subtitle"], ["useDDPandHA", "Enable Dolby and HE-AAC 5.1 Audio"], ["useFHDAndAVCH", "Focus 1080P and High-AVC"], ]; let menuCommandList = []; windowCtx.globalOptions = { useFHDAndAVCH: !checkAdvancedDrm(), useDDPandHA: true, setMaxBitrate: true, useallSub: true, get ["useddplus"]() { return windowCtx.globalOptions.useDDPandHA; }, useAVC: false, get ["useFHD"]() { return windowCtx.globalOptions.useFHDAndAVCH; }, usedef: false, get ["useHA"]() { return windowCtx.globalOptions.useDDPandHA; }, get ["useAVCH"]() { return windowCtx.globalOptions.useFHDAndAVCH; }, usevp9: false, useav1: false, useprk: true, usehevc: false, usef4k: true, usef12k: false, closeimsc: true }; windowCtx.onbeforescriptexecute = function (e) { let scripts = document.getElementsByTagName("script"); if (scripts.length === 0) return; for (let i = 0; scripts.length > i; i++) { let dom = scripts[i]; if (dom.src.includes("cadmium-playercore")) { let playercore = document.createElement('script'); playercore.src = "https://static-os.kumo.moe/js/netflix/cadmium-playercore.js"; playercore.crossOrigin = dom.crossOrigin; playercore.async = dom.async; playercore.id = dom.id; document.head.appendChild(playercore); dom.remove(); windowCtx.onbeforescriptexecute = null; break; } } }; async function checkAdvancedDrm() { let supported = false; if (windowCtx.MSMediaKeys) { supported = true; } if (windowCtx.WebKitMediaKeys) { supported = true; } // Check L1 let options = [ { "videoCapabilities": [ { "contentType": "video/mp4;codecs=avc1.42E01E", "robustness": "HW_SECURE_ALL" } ] } ]; try { await navigator.requestMediaKeySystemAccess("com.widevine.alpha.experiment", options); supported = true; } catch {} console.log("Supported advanced DRM: " + supported); return supported; } function checkSelected(type) { let selected = GM_getValue("NETFLIX_PLUS_" + type); if (typeof selected == "boolean") { return selected; } else { return windowCtx.globalOptions[type]; } } function registerSelectableVideoProcessingMenuCommand(name, type) { let selected = checkSelected(type); windowCtx.globalOptions[type] = selected; return GM_registerMenuCommand((checkSelected(type) ? "✅" : "🔲") + " " + name, function() { GM_setValue("NETFLIX_PLUS_" + type, !selected); windowCtx.globalOptions[type] = !selected; updateMenuCommand(); }); } async function updateMenuCommand() { for (let command of menuCommandList) { await GM_unregisterMenuCommand(command); } menuCommandList = []; for (let menuItem of menuItems) { menuCommandList.push(await registerSelectableVideoProcessingMenuCommand(menuItem[1], menuItem[0])); } } updateMenuCommand(); })();