Cœur du pipeline : ajoute une file d'attente exécutant les téléchargements yt-dlp avec une concurrence bornée, et livre le fichier produit au navigateur (pas de dépôt durable côté serveur). - downloadPlan.ts : construction des arguments yt-dlp par mode (vidéo avec sous-titres/miniature en option, audio dans un format courant, miniature seule), toujours avec séparateur `--` avant l'URL. Parsing de la progression depuis stdout (`[download] NN.N%`). - videoUrl.ts : valide qu'une URL cible bien youtube.com/youtu.be avant de la passer à yt-dlp - ferme le risque de relais SSRF via l'extracteur générique de yt-dlp (des centaines de sites supportés) si une URL arbitraire était acceptée. - QueueService.ts : file en mémoire, N téléchargements simultanés (MAX_CONCURRENT_DOWNLOADS), annulation via AbortSignal, nettoyage du dossier de sortie après échec/annulation ou après livraison du fichier. - ytDlpRunner.ts : étendu pour le suivi ligne par ligne de stdout (progression) et l'annulation (AbortSignal passé à child_process.spawn). - routes/queue.ts : POST/GET /api/queue, DELETE /api/queue/:id, GET /api/queue/:id/file (streaming + nettoyage après envoi). 45 nouveaux tests (59 au total) : fonctions pures, services (vrai système de fichiers temporaire, yt-dlp mocké), routes. Vérifié aussi en conditions réelles (serveur démarré localement) : validation d'URL, ajout en file, et passage correct à l'état "failed" + nettoyage quand le binaire yt-dlp est absent (ENOENT). Empilée sur feature/channel-discovery (réutilise ytDlpRunner.ts). 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.