Skip to content

Instantly share code, notes, and snippets.

@SpaceSaver
Created April 19, 2025 16:36
Show Gist options
  • Save SpaceSaver/5e686a1f129ef456e6a94012f59991c3 to your computer and use it in GitHub Desktop.
Save SpaceSaver/5e686a1f129ef456e6a94012f59991c3 to your computer and use it in GitHub Desktop.
FHD Disney+ For Chromebooks
// ==UserScript==
// @name FHD Disney+
// @namespace @SpaceSaver2001
// @version 3.2
// @author SpaceSaver
// @match https://www.disneyplus.com/*
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
console.log("hi");
const videocodecmatch = /^#EXT-X-STREAM-INF:BANDWIDTH=(?<bandwidth>[\d]*)(,AVERAGE-BANDWIDTH=[\d]*)?,CODECS=\"(?<codecs>.*?)\",RESOLUTION=(?<resolution>[\d]+x[\d]+)(,FRAME-RATE=[\d.]+)?(,VIDEO-RANGE=.*?)?,HDCP-LEVEL=.*?(,CHARACTERISTICS=.*?)?(,AUDIO="(?<audio>.*?)",SUBTITLES=.*?)?(,URI=.*?)?$/;
//const videocodecmatch = /^#EXT-X(-I-FRAME)?-STREAM-INF:BANDWIDTH=[\d]*(,AVERAGE-BANDWIDTH=[\d]*)?,CODECS=\"(?<codecs>.*?)\",RESOLUTION=(?<resolution>[\d]+x[\d]+).*$/;
const audiocodecmatch = /^#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="(?<codec>[^"]+)"/;
// Modifica la resolución en las solicitudes
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
//console.log(this)
//console.log("INTERCEPTION");
if (url === "https://disney.playback.edge.bamgrid.com/v7/playback/ctr-regular") {
//arguments[1] = "https://disney.playback.edge.bamgrid.com/v7/playback/tv-drm-ctr-h265-hdr10-atmos";
arguments[1] = "https://disney.playback.edge.bamgrid.com/v7/playback/ctr-high";
const originalSend = XMLHttpRequest.prototype.send;
this.send = function(data) {
if (data.includes("1280x720")) {
data = data.replace("1280x720", "3840x2160");
}
originalSend.call(this, data);
};
}
/*else if (url === "https://bam-sdk-configs.bamgrid.com/bam-sdk/v5.0/disney-svod-3d9324fc/browser/v28.1/chromium/chrome/prod.json" && false) {
//arguments[1] = "https://disney.playback.edge.bamgrid.com/v7/playback/tv-drm-ctr-h265-hdr10-atmos";
arguments[1] = "https://bam-sdk-configs.bamgrid.com/bam-sdk/v5.0/disney-svod-3d9324fc/browser/v28.1/lg/webos/prod.json";
}*/
else if (url.includes("ctr-all-") && url.includes(".m3u8")) {
//console.log("INTERCEPTION");
console.log(this);
window.pinacle = this;
this.ogload = this.onreadystatechange;
this.myready = this.onreadystatechange =
function mylistener(...attribs) {
console.log("INTERJECTION", "https://www.disneyplus.com/play/5a7a03e6-d297-40ce-83e7-35cb2acf05cf");
console.log(this);
console.log(attribs);
console.log(this.readyState);
if (this.readyState == 4) {
let m3u8 = this.responseText;
console.log(m3u8);
m3u8 = m3u8.split("\n");
let maxBandwidth = 0;
let maxBandwidthAudio = "aac-64k";
for (let x = 0; x < m3u8.length; x += 1) {
const match = m3u8[x].match(videocodecmatch);
console.log(match);
if (match) {
if (!match.groups.audio) {
m3u8[x] = "";
if (m3u8[x+1].startsWith("r/")){
m3u8[x+1] = "";
}
continue;
}
else if (match.groups.audio?.includes("atmos") || match.groups.audio?.includes("eac-3")) {
//m3u8 = m3u8.splice(x,2);
//console.log(m3u8);
//x -= 2;
m3u8[x] = "";
m3u8[x+1] = "";
continue;
}
if (parseInt(match.groups.bandwidth) > maxBandwidth){
maxBandwidth = parseInt(match.groups.bandwidth);
maxBandwidthAudio = match.groups.audio;
}
}
}
for (let x = 0; x < m3u8.length; x += 1) {
const match = m3u8[x].match(videocodecmatch);
const audiomatch = m3u8[x].match(audiocodecmatch);
if (match) {
if (match.groups.audio != maxBandwidthAudio || match.groups.bandwidth != maxBandwidth) {
m3u8[x] = "";
m3u8[x+1] = "";
continue;
} else {
m3u8[x] = m3u8[x].replace("1920x1080", "1280x720");
}
}
else if (audiomatch){
if (audiomatch.groups.codec != maxBandwidthAudio) {
m3u8[x] = "";
continue;
}
}
}
m3u8 = m3u8.join("\n");
console.log(m3u8);
//my_res.stream.sources = [];
Object.defineProperty(this, "response", {
value: m3u8
});
Object.defineProperty(this, "responseText", {
value: m3u8
});
//console.log(this.responseText);
}
this.ogload.call(this, ...attribs);
if (this.onreadystatechange != this.myready) {
this.ogload = this.onreadystatechange
this.onreadystatechange = this.myready
}
}
//this.addEventListener("readystatechange", this.monreadystatechange);
}
//this.addEventListener("readystatechange", this.onload)
originalOpen.apply(this, arguments);
};
const oglistener = XMLHttpRequest.prototype.addEventListener;
XMLHttpRequest.prototype.addEventListener = (event, listener) => {
/*console.log(event);
const mylistener = (...attribs) => {
console.log(attribs);
Object.defineProperty(this, "responseText", {value: "balls"});
Object.defineProperty(this, "response", {value: "balls"});
console.log(this.response);
console.log(this.responseText);
//listener.call(this, ...attribs);
}*/
//console.log(oglistener)
//oglistener(event, mylistener);
}
window.fetch = console.log;
navigator._requestMediaKeySystemAccess = navigator.requestMediaKeySystemAccess;
navigator.requestMediaKeySystemAccess = async (type, opts) => {
console.log(type, opts);
opts[0]["videoCapabilities"][0]["robustness"] = "HW_SECURE_ALL";;
return await navigator._requestMediaKeySystemAccess(type, opts);
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment