Closed Pfuenzle closed 2 years ago
Hi @Pfuenzle! You are welcome! I'm glad to hear that you like this little docker image.
Actually I thought of this in the past. I tried to make a custom build of stremio-web with custom addons. Sadly it's a bit messy.
To do that, you need to edit and compile the stremio-official-addons repo, the result is used on stremio-core, and since stremio-web
depends on a bridge with stremio-core
, you need to recompile that too.
Essentially you need to recompile four projects to do that. I made a docker image in the past to automate this process, but I never published it because I never finished it (I have no experience with Rust Cargo, and I ran into some problems).
The old web-ui is not open source afaik, so we cannot easily edit it, although it's possible to edit the minimized files.
I don't know if the old web-ui has some sort of query component to install addons.
Addons are stored in the browser's local storage, so it's possible to write a simple js script/land page (and host it in combination with this image) to update the browser's local storage and include the desired addons.
Oh right, recompiling then sounds like way to much trouble. The local storage script sounds like a really good idea, I'll check it out how it's saved there and if I get something scripted together, this might also make it possible to change the streamingServer variable on the new Web-UI programmatically.
My best guess would be to inject the script with nginx and run it on site load, do have any other idea, or is it possible to add the script to the container itself?
My best guess would be to inject the script with nginx and run it on site load, do have any other idea, or is it possible to add the script to the container itself?
It can be added to the container. You can set your reverse proxy to load a custom html with this custom script, and then it redirects to stremio itself.
Basic idea of the JS script:
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() };
}
async function installAddon(transportUrl, options)
{
options = options ?? { legacy: false, flags: { official: false, protected: false } };
const key = options.legacy ? JSON.parse(localStorage.addons) : JSON.parse(localStorage.profile);
const addons = options.legacy ? key : key.addons;
if (addons.findIndex((addon) => addon.transportUrl === transportUrl) !== -1) throw new Error('addon already installed');
const manifest = (await fetchResponse(transportUrl)).json;
addons.push({ manifest, transportUrl, flags: options.flags });
if (options.legacy) localStorage.addons = JSON.stringify(addons);
else
{
key.addons = addons;
localStorage.profile = JSON.stringify(key);
}
return addons;
}
I'll think on a proper implementation of the script so I can add it to the repo.
Wow, that looks great already, was just in the process of finding out how to modify localStorage, as I have no experience there :D
With this implementation it should be possible to also remove pre-installed addons, right? Would you be interested in adding this functionality?
I'm working on the script here: https://gist.github.com/n0bodysec/2896438d8578f13c4a9e30373f7200c1
Official addons can be removed if you set their protected
flag to false. I can add it later.
I'm working on the script here: https://gist.github.com/n0bodysec/2896438d8578f13c4a9e30373f7200c1
Somehow it is working. However I will not add it to this repo yet, as it is not fully tested. Manual user actions are required.
For Legacy UI:
It relies on localStorage.addons
key that is undefined until the user installs or uninstalls an addon. You can create an empty array and pass the official addons to it, but it produces weird results.
For Web UI:
It relies on localStorage.profile
and localStorage.profile.addons
keys that are undefined until the user makes some changes to the config (e.g, changing the server url, subtitles settings, installing an addon...). You can recreate the whole localStorage.profile
if you want, but since the Web UI is an active project, that key will be constantly updated for sure.
My current workaround is as follows:
Add the patcher script to the both UIs using docker volumes.
volumes:
- ./data/:/root/.stremio-server
- ./files/patches.js:/srv/stremio/web/patches.js:ro
- ./files/patches.js:/srv/stremio/shell/patches.js:ro
Use sub_filter
in your reverse nginx proxy to inject the script.
sub_filter '</body>' '<script src="https://your.stremio.url/patches.js"></script></body>';
sub_filter_once on;
Wow thanks a lot :D
I will check it out tomorrow to test use cases I can think of, maybe I can find something to bypass the user actions.
Looks really great, thanks again for taking the time
You are welcome!
A minimal example script is currently being pushed to the Docker Hub.
The patch script is working as intended. I looked in the code a bit but could not find the place where the localstorage is filled (maybe the script could have called this method manually before patching in the addons).
I alos thought of setting a default value to put in the localstorage, but that would overwrite user settings, so I just resorted to an alert() call with instruction on how to delete the Watchhub Addon, which then allows the patcher to work.
Actually you can fill the localStorage manually, however you need to pass all keys to the profile object. If in a future update the Stremio team adds another key to the profile
object, then the patch will not longer work.
const profile = {
auth: null,
addons: [
// official addons
// https://github.com/Stremio/stremio-official-addons/blob/master/scripts/gen.js
],
settings: {
interfaceLanguage: 'eng',
streamingServerUrl: 'http://127.0.0.1:11470/',
bingeWatching: false,
playInBackground: true,
playInExternalPlayer: false,
hardwareDecoding: true,
audioPassthrough: false,
audioLanguage: 'eng',
secondaryAudioLanguage: null,
subtitlesLanguage: 'eng',
secondarySubtitlesLanguage: null,
subtitlesSize: 100,
subtitlesFont: 'Roboto',
subtitlesBold: false,
subtitlesOffset: 5,
subtitlesTextColor: '#FFFFFFFF',
subtitlesBackgroundColor: '#00000000',
subtitlesOutlineColor: '#00000000',
seekTimeDuration: 20000,
streamingServerWarningDismissed: null
},
};
It's an interesting workaround... (since you can also set the streaming server url)
@Pfuenzle, I updated the gist, the script creates the needed keys by default now (in case that they aren't already defined). Also auto-reloads the page so the installed addons will be shown. You can also set a default streaming server url too.
It's a hacky trick since it will probably stop working in future updates. But it's way better than trying to call WebAssembly functions.
Also please note that some of the default addons cannot be installed this way, so they are commented out in the script.
Hey, thanks again, the new version is working great. I will make sure to open an issue if the script stops working/the local storage is updated (if this is "officially" implemented in this repo and you want to be notified about updates, otherwise I will fix it myself).
I hope this is also useful to other people, as this current setup with your stremio script is really complementing my Jellyfin setup if a wanted movie is missing.
BTW if you have a way to donate to you for your help with this, let me know :)
You are welcome! Please let me know if it stops working in newer updates. I don't use stremio as daily basis so it would be great if you check it whenever you can!
Also, until those features are officially added, I'll work on a better way to do it (like a custom docker image to build custom stremio versions). This workaround is currently implemented in the repo. The example script has a reference to the gist url where users can find the script!
Also, if you want to donate, you can donate to my PayPal or crypto if you are more comfortable with them! Thanks 😃!
Regards.
Hi, first of, thanks for your Dockerfile for streamio, it made it really easy to setup both the Web-UI and the streaming server.
Thanks to the "streamingServer" it's really easy to set a default server, but is this also possible to use for add-ons? Like e.g. the YouTube addon, but for different add-ons.
I have some family members which I want to use some add-ons, and since they are very not technically savy, this would take a long time to install manually on each device.
Since Stremio also allows install links for add-ons, can these somehow be integrated? May be per Web-UI url, or if set in the docker-compose per ENV file or even at build time for the Web-UI.
Is this somehow possible? Thanks a lot