Compare commits
No commits in common. "5dc61fa742f1f355bbecc85cd987f3b69bc056c8" and "8d2d3af4b072f238df47e05b9891c0f2f0a61f2a" have entirely different histories.
5dc61fa742
...
8d2d3af4b0
@ -1,9 +1,5 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// Load Extension
|
|
||||||
const script = document.createElement('SCRIPT');
|
const script = document.createElement('SCRIPT');
|
||||||
script.src = chrome.runtime.getURL('src/page.js');
|
script.src = chrome.runtime.getURL('page.js');
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.onload = function() {
|
script.onload = function() {
|
||||||
this.remove();
|
this.remove();
|
||||||
};
|
};
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
{
|
{
|
||||||
|
"description": "This browser extension forces DisneyNOW to use their higher-resolution video stream by imitating the Android app. (It also blocks DisneyNOW ads.)",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Force High-Resolution DisneyNOW",
|
"name": "Force High-Resolution DisneyNOW",
|
||||||
"author": "TheBrokenRail",
|
"version": "1.0",
|
||||||
"version": "1.1",
|
|
||||||
"description": "This browser extension forces DisneyNOW to use their higher-resolution video stream by imitating the Android app. (It also blocks DisneyNOW ads.)",
|
|
||||||
"homepage_url": "https://gitea.thebrokenrail.com/TheBrokenRail/force-high-resolution-disneynow",
|
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["*://disneynow.com/*"],
|
"matches": ["*://disneynow.com/*"],
|
||||||
"js": ["src/content.js"],
|
"js": ["content.js"],
|
||||||
"run_at": "document_start"
|
"run_at": "document_end"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
"src/page.js"
|
"page.js"
|
||||||
],
|
],
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
"gecko": {
|
"gecko": {
|
78
src/page.js
78
src/page.js
@ -1,22 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const DEVICE_ID = '031_04'; // Found in the APK as the resource @string/device_id. (Default: "001")
|
const DEVICE_ID = '031_04'; // Found in the APK as @string/device_id
|
||||||
const BRAND_ID = '011'; // Selected from the function mapBrandCode(), which is found in embed.min.js (a script loaded by the website). (Default: "004")
|
const BRAND_ID = '011'; // Selected from the function mapBrandCode(), which is found in embed.min.js (a script loaded by the website)
|
||||||
|
|
||||||
// Lock the reported app name and version to a known working value. (The reported app name and version can determine the video stream format.)
|
|
||||||
const APP_NAME = 'webplayer-dc';
|
|
||||||
const APP_VERSION = '1.2.7.49';
|
|
||||||
|
|
||||||
// Target File
|
|
||||||
const TARGET_FILE = 'playmanifest_secure.json';
|
|
||||||
|
|
||||||
// Patch XMLHttpRequest.open
|
// Patch XMLHttpRequest.open
|
||||||
const oldOpen = XMLHttpRequest.prototype.open;
|
const oldOpen = XMLHttpRequest.prototype.open;
|
||||||
Object.defineProperty(XMLHttpRequest.prototype, 'open', {
|
Object.defineProperty(XMLHttpRequest.prototype, 'open', {
|
||||||
value: function (method, url, ...args) {
|
value: function (method, url, ...args) {
|
||||||
// Flag
|
// Flag
|
||||||
this._isTargetUrl = (new URL(url)).pathname.endsWith('/' + TARGET_FILE);
|
this._isTargetUrl = (new URL(url)).pathname.endsWith('/playmanifest_secure.json');
|
||||||
|
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
oldOpen.call(this, method, url, ...args);
|
oldOpen.call(this, method, url, ...args);
|
||||||
@ -26,81 +19,34 @@ Object.defineProperty(XMLHttpRequest.prototype, 'open', {
|
|||||||
writable: false
|
writable: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// Patch XMLHttpRequest.setRequestHeader
|
|
||||||
const oldSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
||||||
Object.defineProperty(XMLHttpRequest.prototype, 'setRequestHeader', {
|
|
||||||
value: function (name, value) {
|
|
||||||
// Lock App Version
|
|
||||||
if (this._isTargetUrl && name.toLowerCase() === 'appversion') {
|
|
||||||
value = APP_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call Original Method
|
|
||||||
oldSetRequestHeader.call(this, name, value);
|
|
||||||
},
|
|
||||||
enumerable: false,
|
|
||||||
configurable: false,
|
|
||||||
writable: false
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add resolution info to video player.
|
|
||||||
function addResolutionInfo(player) {
|
|
||||||
// Create (or find existing) <p> element.
|
|
||||||
const id = '__disneynow_resolution_info__';
|
|
||||||
let p = document.getElementById(id);
|
|
||||||
if (!p) {
|
|
||||||
// Create
|
|
||||||
const p = document.createElement('P');
|
|
||||||
p.id = id;
|
|
||||||
|
|
||||||
// Add <p> element to DOM.
|
|
||||||
player.parentElement.insertBefore(p, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set initial resolution text.
|
|
||||||
function setResolutionText(resolution) {
|
|
||||||
p.innerText = `Video Quality: ${resolution}`;
|
|
||||||
}
|
|
||||||
setResolutionText('N/A');
|
|
||||||
|
|
||||||
// Hook into <video> element.
|
|
||||||
const video = player.getElementsByTagName('VIDEO')[0];
|
|
||||||
video.addEventListener("resize", e => setResolutionText(`${e.target.videoWidth}x${e.target.videoHeight}`), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Patch XMLHttpRequest.send
|
// Patch XMLHttpRequest.send
|
||||||
const oldSend = XMLHttpRequest.prototype.send;
|
const oldSend = XMLHttpRequest.prototype.send;
|
||||||
Object.defineProperty(XMLHttpRequest.prototype, 'send', {
|
Object.defineProperty(XMLHttpRequest.prototype, 'send', {
|
||||||
value: function (body, ...args) {
|
value: function (body, ...args) {
|
||||||
// Check
|
// Check
|
||||||
if (this._isTargetUrl && body) {
|
if (body && this._isTargetUrl) {
|
||||||
// Parse Request Body
|
// Parse Request Body
|
||||||
const params = new URLSearchParams(body);
|
const params = new URLSearchParams(body);
|
||||||
|
|
||||||
// Pretend to be an Android device.
|
// Pretend to be an Android device
|
||||||
|
if (params.has('device')) {
|
||||||
params.set('device', DEVICE_ID);
|
params.set('device', DEVICE_ID);
|
||||||
// Switch brand ID to one without ads.
|
}
|
||||||
|
|
||||||
|
// Switch brand to one without ads
|
||||||
|
if (params.has('brand')) {
|
||||||
params.set('brand', BRAND_ID);
|
params.set('brand', BRAND_ID);
|
||||||
// Set recommended video player size to current screen resolution.
|
}
|
||||||
params.set('vps', `${window.screen.width * window.devicePixelRatio}x${window.screen.height * window.devicePixelRatio}`);
|
|
||||||
// Ensure other miscellaneous parameters are correct.
|
|
||||||
params.set('hdcp_level', '2.3');
|
|
||||||
params.set('hlsver', '6');
|
|
||||||
params.set('app_name', APP_NAME);
|
|
||||||
|
|
||||||
// Apply Patch
|
// Apply Patch
|
||||||
body = params.toString();
|
body = params.toString();
|
||||||
|
|
||||||
// Log Video Stream URL
|
// Verify
|
||||||
this.addEventListener("load", function () {
|
this.addEventListener("load", function () {
|
||||||
const obj = JSON.parse(this.responseText);
|
const obj = JSON.parse(this.responseText);
|
||||||
const assetUrl = new URL(obj.video.assets.asset[0].value);
|
const assetUrl = new URL(obj.video.assets.asset[0].value);
|
||||||
console.log('Video Stream URL: ' + assetUrl);
|
console.log('Video Stream URL: ' + assetUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find video player and add resolution info.
|
|
||||||
const player = document.getElementsByClassName('VideoPlayer')[0];
|
|
||||||
addResolutionInfo(player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call Original Method
|
// Call Original Method
|
||||||
|
Loading…
Reference in New Issue
Block a user