- Android PiP : boutons lecture/pause + plein écran dans la fenêtre flottante
(RemoteAction via BroadcastReceiver, icône play/pause synchronisée à l'état).
- Android PiP : masque la barre de paramètres (MiniPill/toolbar) et le padding
status bar pendant le mode PiP via onPictureInPictureModeChanged → JS.
- iOS auto-PiP : commentaire clarifiant la limitation WebKit (inline/MSE non
supporté, seul fullscreen→background déclenche l'auto-PiP).
Symptôme : le picker Cast s'ouvre et « cherche » mais ne trouve aucun
Chromecast, et l'app n'apparaît même pas dans Réglages → Réseau local
(la popup de permission iOS ne s'affiche jamais).
Cause : le SDK Google Cast ne lance la découverte réseau automatiquement
QUE lorsqu'un GCKUICastButton est affiché pour la première fois. Movix
ouvre le picker programmatiquement (presentCastDialog) sans jamais
instancier de cast button → la découverte ne démarre jamais → aucun scan
Bonjour → iOS ne déclenche jamais la popup « Réseau local » → aucun
appareil trouvé. Les clés Info.plist (NSLocalNetworkUsageDescription,
NSBonjourServices) sont nécessaires mais ne suffisent pas : il faut
réellement tenter un accès réseau local pour que la popup apparaisse.
Correctif : startDiscoveryIfNeeded() lance explicitement
discoveryManager.startDiscovery() (passiveScan = false, idempotent),
appelé depuis isSupported() (au chargement de la page en mode Chromecast),
showPicker() et loadMedia(). Le scan Bonjour fait alors apparaître la
popup de permission et pré-remplit la liste d'appareils.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
iOS — auto-PiP & gel du tactile :
Le bouton PiP du lecteur fonctionne parfaitement (la lecture continue en
arrière-plan). Le problème n'était QUE l'auto-entrée en quittant l'app.
Mon injection webkitSetPresentationMode sur applicationWillResignActive:
échouait (pas de user-gesture) ET laissait une présentation PiP à moitié
engagée → plus aucun tactile au retour dans l'app.
Solution : attribut WebKit natif video.autoPictureInPicture = true (posé
dans media-session.ts). WebKit bascule la vidéo en PiP tout seul au
passage en arrière-plan, par le même chemin que le bouton (qui marche).
Suppression de toute l'injection manuelle :
- AppDelegate.mm : retrait des overrides applicationWillResignActive: /
applicationDidBecomeActive: et du helper findWKWebViewIn:
- BrowserScreen.tsx : retrait du handler AppState 'inactive' + imports
AppState / isVideoPlayingRef devenus inutiles
Android — overlay PiP au lieu du film :
android-pip-shim : requestPictureInPicture() ne résout PLUS sa promesse.
En PiP Web le lecteur détache la vidéo et affiche un overlay "lecture en
PiP". Sur Android le PiP capture la WebView entière, donc cet overlay
masquait le film. En laissant la promesse en suspens, le lecteur garde la
vidéo inline → le PiP de l'Activity capture bien le film.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
RCTAppDelegate hérite de UIResponder et n'implémente NI
applicationWillResignActive: NI applicationDidBecomeActive: (ce sont
des méthodes optionnelles du protocole UIApplicationDelegate).
Mes overrides appelaient [super ...] aveuglément, ce qui envoyait un
sélecteur non reconnu dans la chaîne RCTAppDelegate → UIResponder →
NSObject → "unrecognized selector sent to instance" → crash.
applicationDidBecomeActive: étant appelé à CHAQUE lancement, l'app
crashait systématiquement au démarrage, avant même l'init de React
Native (donc avant la popup DNS).
Correctif : n'appeler [super ...] que si la super-classe répond
réellement au sélecteur (instancesRespondToSelector:_cmd), pour rester
compatible si une future version de RN ajoute ces méthodes.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Le SDK Google Cast déclenche un dialogue de permission réseau local
dès le lancement, ce qui provoque applicationWillResignActive: et
applicationDidBecomeActive: avant que React Native ait fini son init.
Corrections :
- applicationWillResignActive: : vérifier isViewLoaded avant d'accéder
à rootViewController.view (évite de forcer viewDidLoad sur un VC
non initialisé) ; vérifier webView.URL != nil (évite evaluateJavaScript
sur un WKWebView sans page chargée)
- Passer un bloc non-nil à evaluateJavaScript:completionHandler: (évite
un bug connu sur certaines versions d'iOS avec handler nil)
- applicationDidBecomeActive: : sauter la réinitialisation des gestes
lors du premier appel au démarrage (_gestureResetSkipFirstActivation)
pour ne l'exécuter que lors des retours depuis l'arrière-plan
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Quatre correctifs iOS demandés :
1. Mode immersif pendant la lecture vidéo
- Barre de statut masquée (StatusBar.setHidden) quand une vidéo joue,
restaurée à la pause / ouverture des paramètres.
- BrowserToolbar et MiniPill masqués pendant la lecture (paddingTop = 0
pour que la vidéo couvre tout l'écran, notch compris).
- UIViewControllerBasedStatusBarAppearance = false garantit que le
masquage s'applique aussi en mode plein-écran WebView (fix bouton FS).
2. PiP — injection native avant la suspension JS
- applicationWillResignActive: trouve le WKWebView via findWKWebViewIn:
et appelle directement evaluateJavaScript:, sans passer par le bridge
React Native. Plus rapide et plus fiable que le chemin AppState/inactive.
- Script PiP corrigé : webkitSetPresentationMode (synchrone) en premier,
requestPictureInPicture (async Promise) uniquement en fallback.
3. Touch freeze après notification center
- applicationDidBecomeActive: toggle userInteractionEnabled NO→YES avec
50 ms de délai pour réinitialiser les gesture recognizers WKWebView
bloqués après le glissement du centre de notifications.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
CocoaPods rejected google-cast-sdk 4.8.4 because it requires iOS 15.0 while
the Podfile platform resolved to RN's default min_ios_version_supported (13.4).
The app target already deploys to iOS 15.6, so pinning the pod platform to
15.1 satisfies the Cast SDK requirement without reducing real device support.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Android PiP button fix:
- The Android System WebView does not implement the Web Picture-in-Picture
API, so the Movix player's PiP button showed "browser doesn't support PiP".
- New android-pip-shim.ts injects a PiP Web API shim (Android only):
document.pictureInPictureEnabled = true + HTMLVideoElement.requestPictureInPicture
override that routes to native Activity PiP via an ENTER_PIP bridge message.
- bridge.ts handles ENTER_PIP → PipModule.enterPipNow()
- PipModule.enterPipNow() + MainActivity.enterPipNow() trigger enterPictureInPictureMode
- iOS keeps native WebKit PiP (shim is Android-only)
Chromecast on iOS (now actually wired into the build):
- Podfile: pod 'google-cast-sdk', '~> 4.8.4' — since 4.8.4 the SDK ships as a
static framework bundling Protobuf, so NO use_frameworks! is needed (compatible
with the default RN static-library setup). Previous attempt used a non-existent
pod name (google-cast-sdk-no-arc) which broke `pod install`.
- CastModule.swift rewritten to mirror the Android CastModule exactly: pending-load
+ presentCastDialog picker flow, GCKSessionManagerListener emitting
CAST_SESSION_STARTED/RESUMED/ENDED/FAILED with {deviceName, durationSec, error},
loadMedia/stop/getCurrentDeviceName/getCurrentPositionSec/getSessionState.
All Cast API guarded by #if canImport(GoogleCast) so it compiles with or
without the pod (degrades to isSupported=false).
- project.pbxproj: registered CastModule.swift + CastModule.m in the MovixApp
target's Sources phase and wired SWIFT_OBJC_BRIDGING_HEADER (first Swift in the
app target) — done via the xcodeproj gem so the project graph stays valid.
- Bridging header now imports RCTEventEmitter.h.
- AppDelegate.mm: GCKCastContext initialized via setSharedInstanceWithOptions:
(correct ObjC selector) with the Default Media Receiver app ID.
- Info.plist: NSLocalNetworkUsageDescription + NSBonjourServices
(_googlecast._tcp, _CC1AD845._googlecast._tcp) required for device discovery
on iOS 14+.
The existing iOS-settings cast toggle (AirPlay vs Chromecast) now drives a real
Chromecast path: in Chromecast mode the cast shim is injected and the native iOS
CastModule responds supported=true.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
The pod `google-cast-sdk-no-arc` does not exist on CocoaPods. The real
variant is `google-cast-sdk-no-bluetooth`. Replaced with a commented-out
line for manual opt-in, since the SDK also requires `use_frameworks!
:linkage => :static` which conflicts with the default RN static library
setup. CastModule.swift already compiles cleanly without the pod via
`#if canImport(GoogleCast)` guards (isSupported returns false).
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Group A — PiP (iOS + Android):
- iOS: AppState 'inactive' injects requestPictureInPicture() from native side
while WKWebView is still alive (fixes visibilitychange race with JS suspension)
- Expose isVideoPlayingRef + onMediaPlayback callback from BrowserScreen → bridge
- BridgeMessageOptions added to bridge.ts for cross-platform onMediaPlayback hook
- Android 12+ (API 31): setAutoEnterEnabled(true) via updatePipParams() called
reactively from PipModule.setVideoPlaying() → covers all backgrounding scenarios
(home button, swipe, screen timeout, power button), not just onUserLeaveHint
Group B — Wake Lock:
- navigator.wakeLock.request('screen') acquired on play, released on pause
- Re-acquired on visibilitychange return if video still playing
- visibilitychange now manages timer + wake lock only (PiP handled natively)
- window.__movixActiveVideo exposed for AppState PiP injection script
Group C — Chromecast on iOS:
- useBrowserUIPrefs: castMode: 'airplay' | 'chromecast' (iOS only, default airplay)
- SettingsScreen: iOS-only "Casting" section with AirPlay/Chromecast toggle
- inject.ts: AirPlay mode skips cast shim → site shows native AirPlay button;
Chromecast mode injects shim → iOS CastModule handles Chromecast routing
- cast.ts: removed Platform.OS !== 'android' guard (iOS CastModule can respond)
- New ios/Movix/Cast/CastModule.swift + CastModule.m (mirrors Android CastModule)
with #if canImport(GoogleCast) guards — compiles with or without SDK
- Podfile: pod 'google-cast-sdk-no-arc' (~> 4.8)
- AppDelegate: GCKCastContext initialized with DEFAULT_MEDIA_RECEIVER_APP_ID
Group D — Address config cache:
- AddressContext loads AsyncStorage cache immediately → near-instant start
- Fresh fetch runs in background, updates cache on success
- Offline resilience: stays on cache silently if network fails
Group E — WebView quality:
- IconLock SVG added to ToolbarIcons (Material Design lock path)
- BrowserToolbar: 🔒 emoji replaced with <IconLock> SVG component
- WebViewBrowser: setSupportMultipleWindows={false} + onOpenWindow={() => {}}
to block window.open() popup ads
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
autoPictureInPicture only works with native <video src> playback — not
with MSE (HLS.js). Add a 'visibilitychange' listener that calls
requestPictureInPicture() when the document becomes hidden while a
video is playing. iOS 16+/iPadOS 16+ exempts this event from the
user-gesture requirement, and requestPictureInPicture() works fine with
MSE (same API the player's own PiP button uses).
Falls back to webkitSetPresentationMode('picture-in-picture') if the
Promise is rejected (iOS < 16) or if the standard API is absent.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Make playback feel native on iOS (and Android) by leveraging OS media
features instead of leaving everything to the WebView default.
Media Session (cross-platform, src/injection/media-session.ts):
- The Movix web player never populates navigator.mediaSession, so the
lock screen / Control Center / notification only showed a bare title.
- Inject a script that sets mediaSession.metadata with the movie title
and artwork (video poster → og:image → icon → /movix.png fallback),
wires play/pause/seek action handlers to the active <video>, and keeps
positionState in sync for the scrubber.
- Hooked on the capture-phase 'play' event so it follows SPA navigation
(episode/movie changes) without re-injection.
- Sets video.autoPictureInPicture / disablePictureInPicture=false to arm
iOS auto-PiP, and relays play/pause to native (MEDIA_PLAYBACK message).
iOS background audio + PiP:
- AppDelegate.mm: configure AVAudioSession (.playback / .moviePlayback)
so audio and Picture-in-Picture keep running when the app is
backgrounded or the screen locks. Without this WKWebView stops the
video on background.
- WebViewBrowser: allowsPictureInPictureMediaPlayback +
allowsAirPlayForMediaPlayback. Combined with autoPictureInPicture, the
video floats in PiP when leaving the app instead of stopping.
Android PiP:
- Manifest: supportsPictureInPicture + resizeableActivity on MainActivity.
- MainActivity.onUserLeaveHint() enters PiP (16:9) when a video is
playing; playing-state is tracked via the new PipModule, fed from the
Media Session script through the bridge.
- New PipModule/PipPackage registered in MainApplication.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
HLSPlayer's startAirPlay() destroys HLS.js (MSE is incompatible with
AirPlay), sets video.src to the native HLS URL, then awaits a
'loadedmetadata' event before calling webkitShowPlaybackTargetPicker().
Buffering the remote manifest takes several seconds, causing the picker
to appear with a noticeable delay.
webkitShowPlaybackTargetPicker() does not require the video to have
loaded metadata — it only needs a src and user-gesture context. We
inject a patch into the WebView that fires a synthetic 'loadedmetadata'
event via setTimeout(0) as soon as video.load() is called on an
AirPlay-configured element with a real (non-blob) source URL. This
resolves the web player's awaited Promise immediately, so the picker
appears without the multi-second buffering wait.
The patch is guarded by webkitShowPlaybackTargetPicker availability so
it only activates on iOS WKWebView, and is a no-op if real metadata
arrives first (readyState < 1 check).
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Disabling "Proxy intégré" still left the userscript injected, so it ran
exposePageApi() which sets __MOVIX_EXTENSION_INSTALLED / hasMovixUserscript
/ dataset.movixExtension and fires movix-extension-loaded. The site (e.g.
movix.golf/extension) kept reporting "extension détectée et active" and
routed its requests through the proxy bridge — which then failed.
Fix: when proxyEnabled is false, don't inject the userscript at all. The
site no longer detects the extension and falls back to its own network
path. Bridge runtime + cast shim stay injected (debug console capture +
Chromecast).
Removes the now-dead direct-XHR fallback and the __MOVIX_PROXY_ENABLED
flag from the bridge runtime. Updates the settings hint to match.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Three settings/UX improvements for the mobile WebView app:
1. Console de debug (Réglages → Débogage)
- New in-memory log buffer (services/debugLog.ts, 500-entry rotation)
- installConsoleCapture() patches console.* on the RN side at startup
- bridge-runtime forwards WebView console.* via new CONSOLE_LOG message
- bridge.ts routes CONSOLE_LOG → pushLog(source: 'web')
- DebugConsole.tsx: full-screen modal, level filters, auto-scroll,
share-as-text. Opened from a new "Débogage" settings section.
2. MiniPill flush to screen edge
- Was floating at insets.bottom + 8 (~1cm gap on devices with a home
indicator). Now pinned to bottom: 0, thinner, with hitSlop to keep
the tap target generous.
3. Toggle "Proxy intégré"
- New proxyEnabled pref (useBrowserUIPrefs, default true, persisted)
- Switch replaces the static "Actif" badge in the Extension section
- When off, GM_xmlhttpRequest runs directly in the WebView (in-page
XMLHttpRequest, page cookies, subject to CORS) instead of routing
through the native fetch bridge — helps sources the proxy breaks
- inject.ts injects window.__MOVIX_PROXY_ENABLED; WebView remounts on
toggle via key change so the new mode applies on reload
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
TARGETED_DEVICE_FAMILY was set to 1 (iPhone only), causing the app to
run in iPhone compatibility mode on iPad (small centered window).
Set to "1,2" (Universal) in both Debug and Release build configs.
Also add UISupportedInterfaceOrientations~ipad in Info.plist to declare
all four orientations for iPad (including PortraitUpsideDown which is
supported on iPad but not on modern iPhones).
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
New build_android job running on ubuntu-latest:
- setup-java@v4 with JDK 17 (Temurin) matching compileOptions
- npm ci + build:userscript (same as iOS job)
- Gradle cache keyed on wrapper + root/app build.gradle hashes
- ./gradlew assembleRelease --no-daemon
- Artifact: Movix-Android-<version>, retention 30 days
Both jobs now triggered independently via workflow_dispatch booleans
(build_ios / build_android, both default true).
APK is debug-signed (falls back to signingConfigs.debug when no
keystore.properties) — suitable for sideloading.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
src/injection/userscript-source.ts is .gitignored (generated from
userscript/movix.user.js). Metro bundler fails at bundle phase with
UnableToResolveError when it tries to import ./userscript-source.
Add `npm run build:userscript` step after npm ci to generate the file.
Also: pipe xcodebuild through tee to save raw log + use ${PIPESTATUS[0]}
for correct exit code propagation. Upload raw log as artifact on failure
to expose the full error without xcpretty truncation.
https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
Modification du Oauth :
Pouvoir manager les apps depuis le panel admin
Correction de l'affichage des images des admins
Majs des urls extension, userscript et premid
Correction d'un crash sur les commentaires
Ajout d'un light mode sur le frontend
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>
Maj url dans l'app mobile, extension et userscript et backend : streamonsport, livetv.
Amélioration du scraper darkiworld/hydracker
Nouvelle source vo/vostfr qui est plutôt pas mal
Renommages des sources vo/vostfr avec le nom du doamine pour mieux se repérer
Correction de la synchronisation des données qui étais buggé sur certains navigateurs autre que chrome sur certaines versions
Amélioration de la détection du blocage dns
Corrections de vulnérabilités sur les commentaires (IDOR)
Rajouts de ratelimit sur les commentaires
Correction de pas de son sur hlsplayer
Livetvplayer détecte le type du flux automatiquement
Amélioration du scraper darkiworld (très chiant)
Correction du détection de l'extension
Correction de la vérification du VIP sur server.py (proxy)
Correction du scraper seekstreaming proxy
Nouvelle url streamonsport et coflix
Correction du scraper fstream (get seasons) car la route fonctionne plus sur leur site
Correction du scraper francetv
Ajout de hydrackerBatch (c'étais pour des tests)