Deux causes distinctes au meme symptome (aucune ligne de liste n'affichait de miniature) : - ChannelDiscoveryService : en --flat-playlist, l'extracteur YouTube de yt-dlp ne renseigne quasiment jamais le champ singulier `thumbnail`, seulement `thumbnails` (tableau, trie par resolution croissante). Le parsing ne lisait que `thumbnail` -> thumbnailUrl toujours null. Passe inapercu en test car le mock ne reproduisait que la forme theorique, jamais la forme reelle observee en prod. extractThumbnailUrl() lit desormais aussi `thumbnails`, en repli. - QueuePanel (file d'attente) : aucun champ thumbnailUrl n'existait sur QueueItem/QueueItemDto - fonctionnalite jamais implementee, pas de regression. Ajoutee de bout en bout : POST /api/queue accepte thumbnailUrl (purement informatif, jamais transmis a yt-dlp), QueueService la conserve et l'expose, DownloadForm la transmet depuis les resultats de recherche, QueuePanel l'affiche (miniature 96x54 a gauche de chaque ligne). Verifie en navigateur reel (pas seulement les tests) : element ajoute via POST direct avec thumbnailUrl, image reellement chargee (naturalWidth 480) et positionnee dans le DOM rendu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| client | ||
| server | ||
| spec | ||
| .gitignore | ||
| biome.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
youtubeDownloader
Application web self-hosted pour parcourir, mettre en file d'attente et extraire des vidéos/audios YouTube, en s'appuyant sur yt-dlp et ffmpeg.
Ce projet reprend et remplace une série de scripts .cmd (téléchargement vidéo, récupération de miniatures, recherche de streams par chaîne) par une interface web unique.
Fonctionnalités prévues
- Parcourir une chaîne : recherche par chaîne (URL ou
@handle), liste de ses vidéos/streams avec filtre par mots-clés dans le titre. - Ajout par URL : ajout direct d'une ou plusieurs URLs YouTube.
- File d'attente : chaque élément ajouté est configurable individuellement :
- Vidéo : qualité, sous-titres (fr/en), miniature intégrée, métadonnées.
- Audio seul : extraction dans un format courant (mp3/m4a/opus).
- Miniature seule : récupération du poster uniquement.
- Exécution en parallèle : plusieurs téléchargements simultanés (concurrence configurable), avec suivi de progression en temps réel.
- Livraison au navigateur : les fichiers terminés sont téléchargés directement par l'utilisateur (pas de dépôt sur une bibliothèque partagée type Emby).
- Accès : aucune authentification, usage LAN uniquement.
Stack technique (prévue)
- Backend : TypeScript / Fastify, organisé en services modulaires (découverte de chaîne, gestion de la file d'attente, exécution des téléchargements, notifications temps réel).
- Frontend : TypeScript vanilla, vues séparées en
.ts/.html/.scss. - Moteur :
yt-dlp+ffmpeg(installés dans l'image Docker, non versionnés). - Déploiement : Docker / docker-compose.
- Linting : Biome.js.
Développement
Squelette actuel : serveur Fastify (server/) + client minimal (client/), sans encore la logique de découverte/file d'attente/téléchargement.
# Racine : lint (Biome) sur tout le repo
npm install && npm run lint
# Client : build (esbuild + sass) -> client/dist
cd client && npm install && npm run build
# Serveur : typecheck, tests, dev (sert client/dist)
cd server && npm install
npm run typecheck
npm test
npm run dev
Le serveur écoute par défaut sur http://localhost:3000 (/health pour la vérification de santé) et sert les fichiers statiques de client/dist (variable CLIENT_DIST_PATH).
Docker
docker build -f server/Dockerfile -t youtubedownloader .
docker run -p 3000:3000 youtubedownloader
CI/CD
.forgejo/workflows/publish-docker.yml teste (lint + typecheck + tests + build) puis publie l'image sur git.dev.kyuno.fr/kyuno/youtubedownloader (push sur main -> latest + sha court, tag vX.Y.Z -> version). Nécessite un secret REGISTRY_TOKEN sur le dépôt (voir l'en-tête du workflow).
Statut
Squelette d'infrastructure en place (serveur/client minimaux, Docker, CI). Fonctionnalités listées ci-dessus pas encore implémentées. Voir les issues et PR pour le suivi du développement.