Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 170 additions & 52 deletions Apps/SegmentStremioAddon/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ services:
ssa-proxy:
image: ghcr.io/yundera/appshield:2.0.3
container_name: ssa
# OIDC identity: the AppShield auth-service builds its OIDC redirect URIs from
# os.hostname(), and the auth-registrar independently attests this app's name via the
# container's PTR record, rejecting any redirect URI that doesn't match. Must equal the
# app name, or Docker defaults the hostname to the random container ID and OIDC registration fails.
hostname: ssa
restart: unless-stopped
user: "0:0"
Expand Down Expand Up @@ -58,9 +54,62 @@ services:
networks:
- ssa-internal

mp4filter-proxy:
image: ghcr.io/yundera/appshield:2.0.3
container_name: mp4filter
hostname: mp4filter
restart: unless-stopped
user: "0:0"
expose:
- "80"
labels:
caddy_0: mp4filter-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: mp4filter-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: mp4filter-${APP_PUBLIC_IP_DASH}.sslip.io
caddy_2.reverse_proxy: "{{upstreams 80}}"
environment:
BACKEND_HOST: "mp4filter-backend"
BACKEND_PORT: "80"
LISTEN_PORT: "80"
ALLOWED_PATHS: "/manifest.json,/stream/"
depends_on:
- mp4filter-backend
networks:
- mp4filter-internal
- pcs
cpu_shares: 30

mp4filter-backend:
image: node:20-alpine
container_name: mp4filter-backend
working_dir: /app
command: sh -c "npm install express node-fetch@2 --silent && node index.js"
restart: unless-stopped
cpu_shares: 30
deploy:
resources:
limits:
memory: 134217728
volumes:
- type: bind
source: /DATA/AppData/ssa/mp4filter
target: /app
bind:
create_host_path: true
environment:
PORT: "80"
networks:
- mp4filter-internal

networks:
ssa-internal:
driver: bridge
mp4filter-internal:
driver: bridge
pcs:
name: pcs
external: true
Expand All @@ -69,8 +118,115 @@ x-casaos:
index: /?hash=$AUTH_HASH
webui_port: 80
main: ssa-backend
store_app_id: ssa
access_domain: ssa-username.nsl.sh
pre-install-cmd: |
mkdir -p /DATA/AppData/ssa/mp4filter
if [ ! -f /DATA/AppData/ssa/mp4filter/index.js ]; then
cat > /DATA/AppData/ssa/mp4filter/index.js << 'JSEOF'
const express = require('express');
const fetch = require('node-fetch');

const app = express();
const PORT = process.env.PORT || 80;

const DEFAULT_UPSTREAMS = [
'https://torrentio.strem.fun/sort=seeders|qualityfilter=scr,cam',
'https://torrentsdb.com/sort=seeders|qualityfilter=scr,cam',
'https://peerflix.mov',
];

const UPSTREAMS = (process.env.UPSTREAM_ADDONS
? process.env.UPSTREAM_ADDONS.split(',').map(s => s.trim()).filter(Boolean)
: DEFAULT_UPSTREAMS);

function isMp4(stream) {
const candidates = [
stream?.behaviorHints?.filename,
stream?.title,
stream?.name,
].filter(Boolean).join(' ').toLowerCase();

if (!candidates) return false;
if (/\.(mkv|avi|ts|webm|wmv|mov|flv)\b/.test(candidates)) return false;
return /\.mp4\b/.test(candidates);
}

const TIMEOUT_MS = 8000;

async function fetchWithTimeout(url, ms) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), ms);
try {
const res = await fetch(url, { signal: controller.signal });
if (!res.ok) return null;
return await res.json();
} catch (e) {
return null;
} finally {
clearTimeout(timer);
}
}

const manifest = {
id: 'community.mp4filter',
version: '1.0.0',
name: 'MP4 Stream Filter',
description: 'Merges Torrentio, TorrentsDB and Peerflix, keeping only MP4 streams for reliable browser playback.',
logo: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/stremio.png',
resources: ['stream'],
types: ['movie', 'series'],
catalogs: [],
idPrefixes: ['tt'],
};

app.get('/manifest.json', (req, res) => {
res.setHeader('Cache-Control', 'no-cache');
res.json(manifest);
});

app.get('/stream/:type/:id.json', async (req, res) => {
const { type, id } = req.params;
const requests = UPSTREAMS.map(base =>
fetchWithTimeout(`$${base}/stream/$${type}/$${encodeURIComponent(id)}.json`, TIMEOUT_MS)
);
const results = await Promise.all(requests);
const allStreams = results
.filter(Boolean)
.flatMap(r => Array.isArray(r.streams) ? r.streams : []);
const mp4Streams = allStreams.filter(isMp4);
res.setHeader('Cache-Control', 'max-age=3600');
res.json({ streams: mp4Streams });
});

app.get('/', (req, res) => {
res.send(`
<html>
<head><title>MP4 Stream Filter</title></head>
<body style="font-family: sans-serif; max-width: 600px; margin: 60px auto;">
<h2>MP4 Stream Filter</h2>
<p>Merges Torrentio, TorrentsDB and Peerflix, keeping only MP4 streams so playback works without transcoding errors in Stremio's browser player.</p>
<p>Manifest URL:</p>
<code style="background:#eee; padding:8px; display:block; word-break:break-all;">$${req.protocol}://$${req.get('host')}/manifest.json</code>
<p><a href="stremio://$${req.get('host')}/manifest.json">Install in Stremio</a></p>
</body>
</html>
`);
});

app.listen(PORT, () => {
console.log(`MP4 Stream Filter addon listening on port $${PORT}`);
console.log(`Upstreams: $${UPSTREAMS.join(', ')}`);
});
JSEOF
cat > /DATA/AppData/ssa/mp4filter/package.json << 'PKGEOF'
{
"name": "mp4filter-backend",
"version": "1.0.0",
"main": "index.js"
}
PKGEOF
fi
architectures:
- amd64
- arm64
Expand All @@ -83,67 +239,29 @@ x-casaos:

Features:
- Browse your media files in Stremio's catalog
- Search and filter your library
- Multiple stream options per video:
- Direct Play (original codec)
- HLS Original (source resolution, transcoded)
- HLS Auto (adaptive bitrate)
- Quality-specific streams (720p, 480p, 360p)
- Adaptive quality encoding based on CPU performance
- Series detection (S##E## pattern)
- Multi-audio track support
- Embedded subtitle extraction (WebVTT)
- API key protection via URL prefix
- Live transcoding metrics dashboard
- Multiple stream options per video
- Bundled MP4 Stream Filter addon: merges Torrentio, TorrentsDB and
Peerflix results and keeps only MP4 streams, avoiding "video not
supported" errors during playback

Install in Stremio or at https://web.strem.io/ using the manifest URL shown on the addon page.
fr_fr: |
Addon Stremio - Parcourez et diffusez votre bibliothèque multimédia locale directement dans Stremio avec transcodage HLS à la volée.

Fonctionnalités:
- Parcourez vos fichiers multimédia dans le catalogue Stremio
- Recherche et filtrage de votre bibliothèque
- Plusieurs options de stream par vidéo:
- Lecture directe (codec original)
- HLS Original (résolution source, transcodé)
- HLS Auto (débit adaptatif)
- Streams par qualité (720p, 480p, 360p)
- Qualité d'encodage adaptative selon les performances CPU
- Détection de séries (motif S##E##)
- Support multi-pistes audio
- Extraction des sous-titres embarqués (WebVTT)
- Protection par clé API via préfixe URL
- Tableau de bord des métriques de transcodage en direct

Installez dans Stremio ou sur https://web.strem.io/ en utilisant l'URL du manifest affichée sur la page de l'addon.
developer: Worph
icon: https://cdn.jsdelivr.net/gh/Yundera/AppStore@main/Apps/SegmentStremioAddon/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Yundera/AppStore@main/Apps/SegmentStremioAddon/screenshot-1.png
tagline:
en_us: Stremio addon to browse and stream your local media with built-in HLS transcoding
fr_fr: Addon Stremio pour parcourir et diffuser vos médias locaux avec transcodage HLS intégré
en_us: Stremio addon to browse and stream your local media, plus a bundled MP4-only filter for external sources
thumbnail: https://cdn.jsdelivr.net/gh/Yundera/AppStore@main/Apps/SegmentStremioAddon/icon.png
tips:
before_install:
en_us: |
After installation:
1. Open the addon page at https://ssa-username.nsl.sh
2. Copy the manifest URL or click "Install in Stremio"
3. You can also install from Stremio Web at https://web.strem.io/
4. Your media library will appear as "SSA" in Stremio's catalog

The addon scans /DATA/Downloads and /DATA/Media for video files.
API key protection is enabled by default using your app password.
fr_fr: |
Après l'installation:
1. Ouvrez la page de l'addon à https://ssa-username.nsl.sh
2. Copiez l'URL du manifest ou cliquez sur "Installer dans Stremio"
3. Vous pouvez aussi installer depuis Stremio Web à https://web.strem.io/
4. Votre bibliothèque multimédia apparaîtra comme "SSA" dans le catalogue Stremio

L'addon scanne /DATA/Downloads et /DATA/Media pour les fichiers vidéo.
La protection par clé API est activée par défaut avec votre mot de passe d'application.

Bundled MP4 Stream Filter:
3. Also open https://mp4filter-username.nsl.sh and install that manifest in Stremio
4. This second addon merges Torrentio, TorrentsDB and Peerflix, keeping only
MP4-format streams so playback never fails with "video not supported"
title:
en_us: Segment Stremio Addon
fr_fr: Addon Stremio Segment
Loading