MultiPOV après la PWA : un cœur Rust partagé entre web et Android
MultiPOV après la PWA
La première version de MultiPOV avait un objectif simple : permettre à des spectateurs de regarder plusieurs points de vue d'une même session Discord ou d'un event, alignés dans le temps, sans compte et sans setup lourd.
Cette PWA est en production sur watchmultipov.app. Elle réunit YouTube, Twitch et Kick dans une même régie, avec des sessions partageables, des dispositions configurables et une synchronisation VOD dans le navigateur.
L’étape suivante consistait à prendre en charge la VOD, le live et plusieurs fournisseurs, puis à partager cette logique avec une app Android et à préparer ses releases.
1. Le point de départ : une PWA déjà en production
La V1 était volontairement pragmatique. Solid, TypeScript, Vite, PWA, hls.js et une configuration de session encodée dans l'URL.
Ce choix a permis de livrer vite sans construire une plateforme trop lourde. Les vidéos et les chats restent fournis par les plateformes. MultiPOV orchestre la régie, la disposition, la timeline et la synchronisation.
L’utilisation de cette première version publique a fait apparaître des limites de synchronisation.
2. La limite du navigateur
Le navigateur suffit pour beaucoup de choses, mais la sync live multi-provider met vite en évidence ses frontières : players iframe, HLS, états de lecture qui ne se comportent pas toujours pareil, latence variable, drift, capacités différentes selon les sources, erreurs qui doivent être normalisées.
En VOD, on peut mesurer un décalage, piloter une horloge et recaler. En live, on dépend davantage du comportement de chaque source et du player qui l'expose. Le produit doit donc séparer deux sujets : mesurer ou initialiser un alignement, puis maintenir une expérience stable avec une clock et des offsets.
C'est là que la PWA seule devenait trop étroite. Il fallait une source de vérité média qui ne soit pas réécrite différemment dans chaque front.
3. Le cœur Rust commun
La première version TypeScript utilisait FFT.js côté client pour la mesure GCC-PHAT. Elle a été utile : elle a prouvé le principe produit et l'expérience utilisateur.
Le cœur actuel est différent. La logique média est remontée dans un moteur Rust commun, exposé en WASM côté web et compilé en natif côté app. Le moteur centralise les règles média : timing, offsets, états provider, liveness, erreurs et fallbacks.
Cette décision réduit les divergences. Quand une règle de sync change, elle ne doit pas exister en deux variantes incompatibles entre web et Android.
4. La sync : mesurer, maintenir, recoller
Je distingue trois opérations de synchronisation.
D'abord, mesurer. GCC-PHAT permet d'estimer le décalage entre un flux et une référence audio commune. C'est utile pour initialiser une session VOD ou recaler un point de vue.
Ensuite, maintenir. Une clock partagée et des offsets par POV pilotent la lecture : pause, seek, reprise, changement de layout, correction de drift. Cette logique maintient l’alignement après les interactions.
Enfin, recoller. Certains événements imposent de reprendre une mesure ou d'appliquer une correction : changement d'état player, source qui repart, live qui dérive, ou interaction utilisateur. Ces événements demandent une nouvelle mesure ou un recalage.
5. Une couche commune pour les fournisseurs
MultiPOV intègre YouTube, Twitch et Kick avec une couche provider unifiée. Les détails d’intégration propres à chaque fournisseur restent derrière cette couche.
Chaque provider expose des capacités, des états de liveness, des erreurs et des fallbacks. Ces notions sont centralisées pour que le web et le natif raisonnent avec le même vocabulaire.
6. Tester la synchronisation sur Android
L’app Android utilise Tauri 2, la régie web embarquée, le cœur Rust commun et des players natifs Media3/ExoPlayer.
Ce choix répond à une contrainte très concrète : pour vérifier la synchronisation live, il faut sortir du seul navigateur desktop et mesurer sur device. L'app Android a servi de surface de validation : installation, comportement réel, players natifs, logs, drift, corrections, et stabilité sur une session vivante.
7. Valider sur le web et sur appareil
Le produit web est en production et l'app Android sert de surface de validation complémentaire. Des checks automatisés vérifient les points qui cassent vraiment une version : parcours principaux, assets, liens, configuration et comportement sur appareil. Les contrôles portent sur les parcours exécutés dans chaque environnement.
8. Le travail avec les agents : complément du 8 octobre 2026
Depuis la rédaction de cet article, j’ai précisé les moyens donnés à Codex et Claude Code pour travailler sur Android. Je prépare le contexte, les tâches, les critères et les accès avant l’implémentation. Le MCP connecté via CDP permet de piloter la WebView ; ADB complète le diagnostic avec l’identification de l’APK installé et les logs natifs.
La boucle actuelle est : implémenter → tester la WebView via MCP/CDP sur un build identifié → consulter les logs natifs via ADB si nécessaire → corriger → retester. Un état correct dans le DOM ne prouve pas le bon rendu de la vidéo native. La revue doit aussi vérifier que le banc a réellement observé le phénomène testé avant d’accepter son verdict.
Je garde les arbitrages et l’acceptation des résultats. Le cadrage conversationnel, la préparation des agents et les boucles propres à MultiPOV, Aidventures et Nomad sont détaillés dans Développer avec des agents IA.
9. Ce que j’en retiens
MultiPOV montre ma progression : partir d’un usage précis, publier une V1, puis adapter l’architecture aux limites rencontrées. Le cœur Rust partagé et les lecteurs Android répondent au même besoin que la première PWA : regarder plusieurs POV ensemble, synchronisés. Mon rôle comprend le cadrage, les décisions d’intégration et la validation des résultats des agents.