Last active
October 3, 2023 18:07
-
-
Save n0bodysec/2896438d8578f13c4a9e30373f7200c1 to your computer and use it in GitHub Desktop.
Stremio Web client patches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* @name Stremio JavaScript Patcher | |
* @author n0bodysec | |
* @description A simple JS that is executed on document load. You can apply custom client patches with it. | |
* @example https://gist.github.com/n0bodysec/2896438d8578f13c4a9e30373f7200c1 | |
* This script can be loaded using nginx sub_filter | |
* sub_filter '</body>' '<script src="https://your.stremio.url/patches.js"></script></body>'; | |
* sub_filter_once on; | |
* | |
*/ | |
// see https://github.com/n0bodysec/docker-images/issues/5 | |
// prototypes | |
Storage.prototype.setObject = function (key, value) { this.setItem(key, JSON.stringify(value)); }; | |
Storage.prototype.getObject = function (key) | |
{ | |
const value = this.getItem(key); | |
return value && JSON.parse(value); | |
}; | |
const oConsoleLog = console.log; | |
console.log = function () | |
{ | |
Array.prototype.unshift.call(arguments, '[STREMIO PATCHER]'); | |
oConsoleLog.apply(this, arguments); | |
}; | |
const oConsoleError = console.error; | |
console.error = function () | |
{ | |
Array.prototype.unshift.call(arguments, '[STREMIO PATCHER]'); | |
oConsoleError.apply(this, arguments); | |
}; | |
// global vars | |
// references: https://github.com/Stremio/stremio-web/blob/HEAD/src/types/models/Ctx.d.ts | |
const defaultProfile = { | |
auth: null, | |
addons: [], | |
settings: { | |
interfaceLanguage: 'eng', | |
streamingServerUrl: 'http://127.0.0.1:11470/', | |
playerType: null, | |
bingeWatching: true, | |
playInBackground: true, | |
hardwareDecoding: true, | |
frameRateMatchingStrategy: 'FrameRateOnly', | |
nextVideoNotificationDuration: 35000, | |
audioPassthrough: false, | |
audioLanguage: 'eng', | |
secondaryAudioLanguage: null, | |
subtitlesLanguage: 'eng', | |
secondarySubtitlesLanguage: null, | |
subtitlesSize: 100, | |
subtitlesFont: 'Roboto', | |
subtitlesBold: false, | |
subtitlesOffset: 5, | |
subtitlesTextColor: '#FFFFFFFF', | |
subtitlesBackgroundColor: '#00000000', | |
subtitlesOutlineColor: '#000000', | |
seekTimeDuration: 10000, | |
streamingServerWarningDismissed: null, | |
}, | |
}; | |
let globalProfile = defaultProfile; | |
const OFFICIAL_ADDONS = [ | |
'https://v3-cinemeta.strem.io/manifest.json', | |
'https://v3-channels.strem.io/manifest.json', | |
'https://watchhub.strem.io/manifest.json', | |
'https://caching.stremio.net/publicdomainmovies.now.sh/manifest.json', | |
// TODO: fix below | |
// 'https://opensubtitles.strem.io/stremio/v1', | |
// 'http://127.0.0.1:11470/local-addon/manifest.json', | |
]; | |
const CUSTOM_ADDONS = [ | |
'https://torrentio.strem.fun/manifest.json', | |
]; | |
const isLegacy = () => localStorage.getItem('streamingServerUrl') != null; | |
async function fetchResponse(url) | |
{ | |
const res = await fetch(url); | |
if (!res.ok) throw new Error(`HTTP Error ${res.status}`); | |
return { res, json: await res.json() }; | |
} | |
function setStreamingServer(url) | |
{ | |
if (isLegacy()) localStorage.setItem('streamingServerUrl', url); | |
else | |
{ | |
globalProfile.settings.streamingServerUrl = url; | |
localStorage.setObject('profile', globalProfile); | |
} | |
} | |
async function installAddon(transportUrl, options) | |
{ | |
options = options ?? { flags: { official: false, protected: false } }; | |
if (globalProfile.addons.findIndex((addon) => addon.transportUrl === transportUrl) !== -1) return null; | |
const manifest = (await fetchResponse(transportUrl)).json; | |
const obj = { manifest, transportUrl, flags: options.flags }; | |
globalProfile.addons.push(obj); | |
console.log(`Addon '${manifest.name}' has been installed!`); | |
return obj; | |
} | |
window.addEventListener('DOMContentLoaded', async (event) => | |
{ | |
if (localStorage === undefined) return console.error('localStorage is not defined. Script execution has been paused.'); | |
if (localStorage.getItem('patchOnce')) return console.log('Skipping the patches because they are already applied.'); | |
const legacy = isLegacy(); | |
console.log(`Detected ${legacy ? 'Legacy' : 'Web'} UI`); | |
// localStorage safeguard | |
const lsProfile = localStorage.getObject('profile'); | |
if ((legacy && !localStorage.getObject('addons')) || (!legacy && !lsProfile)) | |
{ | |
console.log('Installing default addons...'); | |
for (const addon of OFFICIAL_ADDONS) await installAddon(addon, { flags: { official: true, protected: false } }); | |
} | |
else | |
{ | |
globalProfile = lsProfile; | |
console.log('Profile loaded!'); | |
} | |
// install addons | |
console.log('Installing custom addons...'); | |
for (const addon of CUSTOM_ADDONS) await installAddon(addon); | |
// save configs | |
console.log('Saving profile...'); | |
localStorage.setItem('patchOnce', true); | |
if (legacy) localStorage.setObject('addons', globalProfile.addons); | |
else localStorage.setObject('profile', globalProfile); | |
// set custom streaming server url (https://stremio.domain.tld -> https://stremio-server.domain.tld) | |
const serverUrl = location.protocol + '//' + location.host.replace('stremio', 'stremio-server'); | |
console.log(`Setting streaming server url to ${serverUrl}`); | |
setStreamingServer(serverUrl); | |
// reload after apply all patches | |
location.reload(); | |
return 1; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment