No description
Find a file
Movix 4bba4cab40 chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway
Nettoyage massif côté frontend, grosse passe perf, app mobile v2.5.3
(écran qui ne s'éteint plus + fix build), extracteur Uqload HLS sur
extensions/userscript, redirection réseau-bloqué via passerelle
explicative et cast cross-receiver/cross-browser.

Nettoyage Firebase & code mort
- Drop firebase + @firebase/firestore (package.json + vite.config
  optimizeDeps + alias)
- Suppression src/config/firebase.ts (jamais utilisé)
- Suppression services morts : adminService, commentService, logService,
  notificationService + composants liés (AdminLogin, CommentSection,
  CommentItem, ReactionBar) + types/Comment.ts
- Suppression scripts non-utilisés : bundle-report.mjs, publish-app.mjs
- Net : -3 449 lignes

Perf carrousels & TMDB images
- useTmdbImages : 1 seul fetch TMDB pour logo + poster (au lieu de 2),
  prefetch idle au mount du carousel + dedup via inflight map (0 doublon
  entre prefetch et hooks), include_image_language=fr,en,null pour
  récupérer les versions FR-prioritisées
- EmblaCarousel : pré-décode des posters off-DOM (img.decode) en idle
  pour éliminer le coût de décode pendant le scroll horizontal, priority
  cap statique (eager + fetchpriority=high pour les N premières cards
  selon viewport), suppression du tracking visibleSlides (state churn)
- content-visibility:auto sur slides hors viewport (skip layout/paint
  natif), exclu des slides Top 10 pour ne pas clipper le digit débordant
- will-change:transform pré-promotion compositing layer (PC only via
  hover:hover)
- Embla duration 25 → 15 (snap plus rapide, moins de frames composées)
- Boutons nav carousel : suppression backdrop-blur (cher), bg opaque
- LazyImage : width/height attrs pour éviter CLS + alléger placeholder

Top progress bar (style YouTube)
- TopProgressBar : asymptote vers 85% pendant chunk loads, fill 100%
  smooth + fade out à la fin, 120ms grace period pour suppress flash
  sur chunks cachés
- lazyWithRetry tracke les loads actifs + dispatch chunk:load:start /
  chunk:load:end events sur window
- Routes loaders supportent { silent: true } pour skip le tracking sur
  les prefetch (PrefetchLink hover + IDLE_PREFETCH au mount)

SW redirect → passerelle movix.health explicative
- buildMirrorUrl() factorise la construction d'URL miroir avec contexte
- handleNavigation passe ?from=&reason=unreachable&error=&via= à la
  gateway pour qu'elle affiche une popup explicative au user au lieu
  d'un redirect silencieux
- MOVIX_FORCE_REDIRECT message handler passe reason=api-errors
- blockDetection.ts transmet la dernière erreur axios au SW
- index.html : cache-bust du Cast SDK URL (cb=Date.now()) pour éviter
  qu'un SDK stale ne reste coincé en cache navigateur/SW

Cast (Chromecast + AirPlay + Remote Playback API)
- loadMediaOnCastWithFallback : retry sur 3 MIME HLS différents
  (application/vnd.apple.mpegurl, x-mpegurl, x-mpegURL) — certains
  receivers rejettent le premier choix selon firmware
- Subtitles externes attachés au cast (CastSubtitleTrack) via
  chrome.cast.media.Track + TextTrackStyle par défaut (50% black
  background, edge outline) lisible sur la majorité des TV
- isRemotePlaybackSupported : fallback W3C Remote Playback API pour
  Firefox / Edge avec cast extension bloquée / Brave avec shields →
  device discovery + picker via video.remote.prompt()
- initializeAirPlay supporte désormais les deux paths (WebKit AirPlay
  pour Safari + Remote Playback pour les autres)
- Détection castSdkBlocked : si le SDK Cast ne charge pas en 5s
  (adblock, FAI, shield), affiche un message d'erreur explicite au
  lieu du générique "aucun device trouvé"
- 7 nouvelles strings i18n FR + EN pour les états cast :
  castUnavailable, castUnavailableNoDevices,
  castUnavailableUnsupportedBrowser, castUnavailableSdkBlocked,
  castUnavailableHelpChromecast, castUnavailableHelpAirPlay,
  castUnavailableSeeHelp

App mobile Android v2.5.3 (versionCode 12)
- AndroidManifest : android:keepScreenOn="true" sur MainActivity →
  l'écran ne s'éteint plus pendant le visionnage (avant le user devait
  toucher l'écran toutes les 30s pour pas que le téléphone se lock en
  plein film)
- build.gradle : exclude androidx.legacy:legacy-support-core-utils
  (tiré transitivement par mediarouter → palette) qui embarquait ses
  propres androidx.autofill.R$attr → "duplicate class" au mergeDexRelease
  contre le module androidx.autofill:autofill:1.1.0 d'appcompat
- gradle.properties : android.nonTransitiveRClass=true pour empêcher
  chaque lib de regénérer ses R classes transitivement (même cause
  racine du duplicate class)
- version.json bumped 2.5.2 → 2.5.3, nouvel APK (-17KB), release notes
  FR : "Correction extraction du lecteur Uqload" + "L'écran ne s'éteint
  plus lors de l'utilisation de l'app"
- apkUrl repointé sur le repo Movix-STMG (au lieu de movixcorp)

Userscript + Extensions Chrome/Firefox — Uqload HLS
- extractUqload : préfère désormais le master.m3u8 multi-bitrate (qualité
  adaptative) au v.mp4 single-quality. Regex tente d'abord
  /master\.m3u8/, sinon n'importe quel .m3u8, et fallback sur l'ancien
  pattern v.mp4 si rien trouvé. Les 3 cibles (Chrome MV3, Firefox MV2,
  Tampermonkey) sont synchronisées sur la même logique.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 13:28:51 +02:00
API Majs de urls + corrections scrapers + nouvelle source 2026-05-06 22:54:06 +02:00
app chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00
baddomain tird release 2026-04-28 17:55:00 +02:00
cloudflareproxy tird release 2026-04-28 17:55:00 +02:00
extension chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00
functions tird release 2026-04-28 17:55:00 +02:00
others tird release 2026-04-28 17:55:00 +02:00
PreMid tird release 2026-04-28 17:55:00 +02:00
public chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00
RivestreamCloudflareProxy tird release 2026-04-28 17:55:00 +02:00
scripts tird release 2026-04-28 17:55:00 +02:00
server tird release 2026-04-28 17:55:00 +02:00
src chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00
userscript Majs de urls + corrections scrapers + nouvelle source 2026-05-06 22:54:06 +02:00
wasm/watchparty-sync tird release 2026-04-28 17:55:00 +02:00
.dockerignore tird release 2026-04-28 17:55:00 +02:00
.env.example tird release 2026-04-28 17:55:00 +02:00
.gitattributes tird release 2026-04-28 17:55:00 +02:00
.gitignore tird release 2026-04-28 17:55:00 +02:00
AGENTS.md tird release 2026-04-28 17:55:00 +02:00
CLAUDE.md tird release 2026-04-28 17:55:00 +02:00
Dockerfile tird release 2026-04-28 17:55:00 +02:00
eslint.config.js tird release 2026-04-28 17:55:00 +02:00
index.html chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00
LICENSE tird release 2026-04-28 17:55:00 +02:00
manifest.json tird release 2026-04-28 17:55:00 +02:00
movix.png tird release 2026-04-28 17:55:00 +02:00
next.config.js tird release 2026-04-28 17:55:00 +02:00
package-lock.json chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00
package.json chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00
postcss.config.js tird release 2026-04-28 17:55:00 +02:00
README.md tird release 2026-04-28 17:55:00 +02:00
tailwind.config.js tird release 2026-04-28 17:55:00 +02:00
tsconfig.app.json tird release 2026-04-28 17:55:00 +02:00
tsconfig.json tird release 2026-04-28 17:55:00 +02:00
tsconfig.node.json tird release 2026-04-28 17:55:00 +02:00
vite.config.ts chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway 2026-05-10 13:28:51 +02:00

Movix

Movix

Le 1er site de streaming open source made in France et 100% vibecodé.

React | Vite | TypeScript | Node.js | MySQL | Redis | Socket.IO | Python | Rust

React Vite TypeScript Node.js MySQL Redis Socket.IO Python Rust

Licence : Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) · LICENSE

Movix est un monorepo produit pour une plateforme de streaming communautaire. Le frontend, l'API principale, la WatchParty, les proxies, les outils navigateur et plusieurs briques d'infra vivent dans le même dépôt parce qu'ils évoluent ensemble.

Ce n'est pas un simple duo "frontend + backend". Une feature peut très vite traverser plusieurs couches à la fois : interface React, persistance locale, sync backend, extraction vidéo, proxy Python et parfois extension navigateur.

Ce que contient le repo

Zone Rôle Documentation
src/ Frontend Vite + React + TypeScript Frontend
API/Mainapi/ Backend principal clusterisé Main API
API/watchpartyAPI/ Service temps réel WatchParty WatchParty API
API/proxiesembed/ Proxy aiohttp pour embeds, flux et DRM Proxies Embed
API/miscs/ Micro-service Flask pour certains 403 bypass403
extension/ + userscript/ Outils navigateur Movix Movix OS
app/ App mobile React Native (Android OK, iOS non testé) App mobile
wasm/watchparty-sync/ Moteur Rust/WASM de la Sync Pro WatchParty Sync WASM
cloudflareproxy/ Worker Cloudflare CORS/proxy Cloudflare Proxy

Architecture du monorepo

movix-main/
|-- src/                        # Frontend principal
|-- public/                     # Assets statiques et artefacts WASM publiés
|-- API/
|   |-- Mainapi/                # Backend actif
|   |-- watchpartyAPI/          # Temps réel WatchParty
|   |-- proxiesembed/           # Proxy Python haute charge
|   `-- miscs/                  # Micro-services annexes
|-- extension/                  # Extension Chrome / Firefox
|-- userscript/                 # Variante Tampermonkey
|-- app/                        # App mobile React Native (Android/iOS)
|-- wasm/watchparty-sync/       # Sync Pro en Rust/WASM
|-- cloudflareproxy/            # Worker Cloudflare
|-- functions/                  # Handlers serverless annexes
|-- PreMid/                     # Présence PreMiD
`-- RivestreamCloudflareProxy/  # Variante de worker pour Rivestream

Démarrage rapide

Prérequis

  • Node.js 18+ et npm
  • Python 3.10+ pour les services Python
  • MySQL et Redis pour API/Mainapi
  • Rust + wasm-bindgen seulement si tu touches la Sync Pro WASM
  • React Native CLI + Android Studio (et Xcode + CocoaPods sur Mac) seulement si tu touches l'app mobile app/ — iOS n'a pas été testé, voir app/README.md

Installer les dépendances utiles

npm install
cd API/Mainapi
npm install

API/watchpartyAPI/ n'a pas son propre package.json : il consomme les dépendances du node_modules racine.

Configurer les .env avant de lancer quoi que ce soit

Ne saute pas cette étape. Une bonne partie du monorepo dépend des variables d'environnement pour les URLs, la base de données, Redis, les proxys, TMDB, Turnstile et plusieurs intégrations de lecture.

# Frontend
cp .env.example .env

# API principale
cp API/Mainapi/.env.example API/Mainapi/.env

# WatchParty
cp API/watchpartyAPI/.env.example API/watchpartyAPI/.env

# Proxy embed
cp API/proxiesembed/.env.example API/proxiesembed/.env

# bypass403
cp API/miscs/.env.example API/miscs/.env

Lancer le minimum utile en local

# Frontend - http://localhost:3000
npm run dev
# Backend principal - http://localhost:25565
cd API/Mainapi
npm run dev
# WatchParty - http://localhost:25566
node API/watchpartyAPI/watchparty.js

Services optionnels selon la zone que tu touches :

# Proxy embed
cd API/proxiesembed
pip install -r requirements.txt
python server.py
# bypass403
cd API/miscs
pip install flask requests python-dotenv
python bypass403.py

Configuration

Les fichiers d'exemple ou de config existants sont déjà dans le repo :

  • Frontend : .env.example
  • API principale : API/Mainapi/.env.example
  • WatchParty : API/watchpartyAPI/.env.example
  • Proxy embed : API/proxiesembed/.env.example
  • bypass403 : API/miscs/.env.example

Les variables frontend les plus importantes sont VITE_MAIN_API, VITE_WATCHPARTY_API, VITE_PROXY_BASE_URL, VITE_API_PROXY_BASE_URL, VITE_PROXIES_EMBED_API et VITE_SITE_URL.

Pour un premier lancement local, configure au minimum :

  • /.env
  • API/Mainapi/.env
  • API/watchpartyAPI/.env

Comment s'orienter vite

  • Feature frontend : commence par src/App.tsx, puis la page cible dans src/pages/.
  • Auth, profils, persistance : regarde src/context/, src/App.tsx, API/Mainapi/routes/authRoutes.js et API/Mainapi/routes/sync.js.
  • Lecture vidéo et proxies : recoupe src/pages/Watch/, les composants player, API/Mainapi/liveTvRoutes.js, API/proxiesembed/ et parfois extension/.
  • WatchParty : vérifie à la fois API/watchpartyAPI/watchparty.js, src/pages/WatchParty*.tsx, src/hooks/useWatchParty.ts, src/utils/watchparty*.ts et src/workers/watchpartySync.worker.ts.
  • Browser tooling : si tu modifies l'extension, compare toujours extension/Chrome/ et extension/Firefox/, puis vérifie si le userscript doit suivre.
  • Sync Rust/WASM : modifie wasm/watchparty-sync/, puis rebuild public/wasm/watchparty-sync/.

Points importants avant de contribuer

  • Le backend actif est API/Mainapi/. Le vieux contenu directement sous API/ n'est plus la référence.
  • Ce monorepo n'utilise pas de workspace tooling : chaque sous-projet garde ses scripts.
  • Une partie importante de l'état produit vit dans localStorage et dans la sync backend. Ne raisonne pas "base de données only".
  • Le lint frontend se lance à la racine avec npm run lint.
  • Il n'y a pas de suite de tests globale fiable pour tout le repo. Vérifie au minimum les scripts touchés et le comportement manuel.

Documentation par module

Licence

Ce projet est distribué sous licence Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0). Le texte complet est disponible dans LICENSE.

Avertissement

Ce projet est fourni uniquement à des fins éducatives, de recherche et de démonstration. Il n'encourage ni ne cautionne une utilisation illégale, le contournement de droits, ou toute violation des lois applicables. Chaque utilisateur est seul responsable de l'usage qu'il en fait.