[Slim Video #1] Disque Plex saturé, usine à gaz Tdarr et le crash-test de Caméra Café

Tout a commencé par une jauge rouge dans le Finder de macOS.

Mon serveur domestique Plex tourne sur un Mac Mini Apple Silicon posé discrètement sur un meuble dans le salon. Dessus est branché un disque dur externe USB de plusieurs téraoctets, gavé de films d'animation, de séries cultes et de documentaires. Et un soir, le couperet tombe : 0 octet disponible.

Face à ce grand classique du dev amateur de self-hosting, deux options s'offrent à toi :

  1. La solution sage : ouvrir Amazon, lâcher 130 € pour un disque de 4 To et attendre le livreur en buvant un café.
  2. La solution têtu & passionné : refuser catégoriquement de dépenser un centime par pure fierté de dev, regarder la puce M-series du Mac Mini qui dort avec ses unités d'encodage matériel surpuissantes, et se dire : "Je vais diviser par deux la taille de toute ma bibliothèque en HEVC/H.265 à coups de vibe coding".

Option 2, évidemment.


🚫 L'usine à gaz Tdarr : pourquoi j'ai fui

Avant de coder quoi que ce soit, j'ai quand même fait un tour d'horizon de l'existant. Tout Reddit et les forums de sysadmins te chantent les louanges de Tdarr.

J'ai donc téléchargé Tdarr. Et là, c'est le choc culturel :

  • Une architecture distribuée avec serveur maître, worker nodes et files d'attente Redis.
  • Des configurations pensées à 90% pour des fermes de serveurs sous Linux avec GPU Nvidia (NVENC) ou des NUCs Intel (QuickSync).
  • Une bibliothèque de 400 plugins communautaires aux noms cryptiques où personne ne sait quel filtre écrase les pistes audio françaises ou supprime les sous-titres forcés.
  • Une interface WebUI qui ressemble au panneau de commande d'une centrale nucléaire soviétique en 1986.

Pour mon pauvre Mac Mini autonome, c'était l'équivalent de sortir un semi-remorque de 38 tonnes pour aller acheter une baguette de pain à 200 mètres.

flowchart TD
    A[Mon Besoin Réel] --> B[Un seul binaire CLI / TUI sur Mac Mini]
    B --> C[Exploiter VideoToolbox en natif]
    B --> D[Conserver 100% des sous-titres et langues]
    B --> E[Zéro dépendance réseau ni serveur lourd]

Je voulais un outil léger, autonome, écrit en Python, qui dialogue directement avec les encodeurs matériels Apple et qui s'exécute dans un simple terminal.


💥 Premier soir de Vibe Coding : Le désastre Caméra Café

Armé de mon prompt préféré, je lance une session de vibe coding pour prototyper un wrapper ffmpeg qui scanne un dossier, filtre les vidéos et lance un encodage HEVC.

En 30 minutes, le code tourne. Aucune erreur Python, la barre de progression défile, je me sens comme un génie du multimédia.

Pour mon premier test grandeur nature, je sélectionne un vieux dossier qui traîne : l'intégrale des rips DVD de Caméra Café encodés au début des années 2000 en bon vieux .avi (codec Xvid/DivX en 576p tout baveux).

Je lance le script sur 10 épisodes. Le Mac Mini ventile à peine, les fichiers sont réencodés en HEVC. Je vais voir le dossier de sortie pour admirer les gigas économisés...

Et là, c'est le drame : les fichiers H.265 générés étaient 35% plus LOURDS que les fichiers originaux !

 ── Crash-Test Caméra Café ──────────────────────────────────────────────────
 Fichier Source                 Codec Orig.   Taille Init.  HEVC Sortie  Résultat
 ────────────────────────────────────────────────────────────────────────────
 S01E01 - La Machine.avi        MPEG-4/Xvid   180 Mo        245 Mo       +36% 😱
 S01E02 - Le Café.avi           MPEG-4/Xvid   175 Mo        238 Mo       +36% 😱
 S01E03 - Délocalisation.avi   MPEG-4/Xvid   190 Mo        260 Mo       +37% 😱
 ────────────────────────────────────────────────────────────────────────────

Pourquoi ce fail magistral ?

Dans le monde de la compression vidéo, il n'y a pas de magie. Quand une vidéo source est déjà ultra-dégradée avec du bruit de compression, des macro-blocs et une résolution bâtarde, forcer un encodeur moderne à reconstruire une trame HEVC propre l'oblige à encoder du bruit comme si c'était de l'information utile. Résultat : le bitrate explose pour rien.


🧭 Le premier grand pivot d'architecture

Ce premier crash-test m'a appris la règle d'or que l'IA ne te dit pas quand elle génère du code : la physique et les maths de la compression s'imposent à tout le monde.

J'ai donc immédiatement acté trois principes non-négociables dans le moteur :

1. Cible exclusive : H.264 (AVC) vers H.265 (HEVC)

Le passage en HEVC ne produit des gains spectaculaires (entre 40% et 65% d'espace économisé à qualité visuelle identique) que sur des flux sources modernes en H.264 (1080p ou 4K). Tout le reste (MPEG-2, Xvid, VC-1) est ignoré par défaut pour éviter d'aggraver la situation.

2. Stream Copy absolu sur l'Audio et les Sous-Titres

Rien de pire que de réencoder un film en 5.1 Dolby Digital et de se retrouver avec une piste stéréo décalée de 200 ms ou des sous-titres désynchronisés. Slim Video force la copie bit-à-bit stricte de tous les flux audio et sous-titres existants :

# slim_video/transcoder.py
base_cmd = [
    "ffmpeg",
    "-y",
    "-i",
    str(src),
    "-map",
    "0",  # Préserver TOUS les flux sans exception
    "-map_metadata",
    "0",  # Préserver les tags et langues
    "-map_chapters",
    "0",  # Préserver les chapitres
    "-c:a",
    "copy",  # Audio 100% lossless (passthrough)
    "-c:s",
    "copy",  # Sous-titres 100% lossless
]

3. Zéro suppression destructrice automatique

Au départ, l'IA voulait simplement exécuter os.remove(source_path) une fois la conversion terminée. Mauvaise idée. Si le fichier généré est corrompu ou si la lecture échoue, ton média original est perdu à jamais. On a donc conçu un système de quarantaine sécurisé déplaçant les originaux dans _originals_to_delete/.


⏭️ Prochain épisode : Quand le disque USB fait planter la fête

Avec ces règles en place, le moteur d'encodage était prêt. Mais dès que j'ai voulu lancer un batch sur 50 films situés sur mon disque externe USB, un nouveau goulot d'étranglement matériel est apparu : la saturation totale de la tête de lecture mécanique du disque dur.

👉 Rendez-vous dans l'Épisode 2 pour découvrir comment le mode SSD Staging a permis de passer de 15 fps à plus de 300 fps constants sur Apple Silicon !


🔗 Liens & Ressources de la Série