Un script Custom JS Function pour Tdarr qui nettoie intelligemment les pistes avant FFmpeg : audio, sous-titres, covers, attachments et metadata parasites.
L'objectif principal n'est pas le flow fourni, mais le moteur de decision contenu dans Custom JS. Les flows JSON sont seulement des exemples adaptes a un setup AV1 personnel.
Fichier source MKV
β
ββ π₯ Video principale -> conservee pour encodage AV1
ββ π Audios multiples -> analyse, tri, nettoyage, AC3 propre
ββ π¬ Sous-titres valides -> conserves en copy
ββ β οΈ Sous-titres non fiables -> supprimes avant FFmpeg
ββ πΌοΈ Covers / attached pictures -> supprimees
ββ π Attachments utiles -> polices conservees, parasites retires
Le script agit sur args.variables.ffmpegCommand.streams juste avant ffmpegCommandExecute.
Il ne lance pas FFmpeg lui-meme. Il modifie la commande que Tdarr va construire :
Tdarr detecte les streams
β
Custom JS analyse chaque piste
β
Custom JS marque quoi garder / supprimer / encoder
β
Tdarr genere la commande FFmpeg finale
RΓ©sultat : FFmpeg recoit une commande plus propre, avec moins de risques de crash.
Garder une selection audio utile, lisible, ordonnee, puis encoder les pistes conservees en AC3 256k.
Audios source
ββ π«π· VFF fiable -> prioritaire
ββ π¨π¦ VFQ -> supprimee si VFF fiable existe
ββ π¬π§ VO anglaise -> conservee si pertinente
ββ π―π΅ japonais -> conserve si present
ββ π langue originale -> conservee si pertinente
ββ π audio-description -> supprimee
ββ ποΈ commentaire -> supprime
ββ πΌ music only -> supprime
Le script favorise :
- les pistes francaises fiables (
fr,fra,fre, marqueursVFF,VFI, etc.) - les pistes anglaises
- les pistes japonaises
- une langue originale pertinente si elle sort des langues principales
- les pistes non taguees protegees quand les metadata sont trop pauvres pour les supprimer sans risque
Le script supprime notamment :
- audio-description
- commentary / commentaire audio
- music only / isolated score
- doublons moins bons dans une meme langue
- VFQ si une VFF fiable existe
- langues hors cible quand une langue originale pertinente a deja ete choisie
Les pistes conservees sont renommees proprement :
VFF - AC3 5.1
VO - AC3 5.1
JA - AC3 2.0
Unknown - AC3 unknown
Chaque audio conservee recoit :
-c:{outputIndex} ac3 -b:{outputIndex} 256kLa piste par defaut est choisie en priorite :
VFF fiable standard
> francais fiable
> francais detecte
> anglais standard
> autre piste standard
Conserver les sous-titres utiles sans conversion, mais supprimer les pistes dangereuses qui peuvent faire planter FFmpeg.
Le script ne fait pas :
-c:s copyIl applique un copy piste par piste uniquement aux codecs valides.
Whitelist actuelle :
| Codec | Usage typique | Action |
|---|---|---|
subrip / srt |
SRT texte | β copy |
ass / ssa |
sous-titres styles | β copy |
hdmv_pgs_subtitle / pgssub |
PGS Blu-ray | β copy en passe normale |
dvd_subtitle |
DVD/VobSub | β copy |
dvb_subtitle |
DVB | β copy |
xsub |
DivX/XSUB | β copy |
Commande appliquee :
-c:{outputIndex} copyLe script supprime :
| Codec / etat | Pourquoi |
|---|---|
none |
FFmpeg ne sait pas quel codec ecrire |
unknown |
risque de mux impossible |
webvtt |
cas observe : S_TEXT/WEBVTT non supporte par le FFmpeg utilise |
hdmv_pgs_subtitle / pgssub |
supprime seulement en fallback si la premiere passe FFmpeg echoue |
| codec vide | piste incomplete ou mal detectee |
| codec absent de la whitelist | approche defensive anti-crash |
Les flows fournis utilisent une strategie conservatrice :
Passe 1 : garder les sous-titres valides, y compris PGS
ββ si FFmpeg reussit : fichier conserve au maximum
ββ si FFmpeg echoue : fallback automatique
Passe 2 : retirer les sous-titres image-based
ββ PGS / DVD / DVB / XSUB retires
ββ SRT / ASS / SSA conserves
Cela evite de supprimer inutilement un sous-titre PGS force sain, tout en empechant un PGS casse de faire echouer definitivement le job.
Le script vise directement ces erreurs :
Unknown/unsupported AVCodecID S_TEXT/WEBVTT
Could not find codec parameters for stream X (Subtitle: none)
Subtitle codec 0 is not supported
Multiple -codec options specified
Illustration :
Avant
-map 0:3 -c:2 copy β
SRT
-map 0:4 -c:3 copy β WebVTT detecte comme none
-c:s copy β double regle globale
=> crash possible
Apres
-map 0:3 -c:2 copy β
SRT seulement
0:4 supprime β
pas de crash codec 0
pas de -c:s copy β
pas de conflit
Les polices sont conservees pour ne pas casser les sous-titres ASS/SSA :
.ttf.otf.woff.woff2- mimetypes de police connus
Le script retire :
- covers image
- attachments
none - attachments
unknown - attachments sans nom et sans mimetype
- images integrees exposees comme attachments
π Fonts utiles -> conservees
πΌοΈ Cover.jpg -> supprimee
β Attachment none -> supprime
Certains MKV exposent les covers comme de faux streams video :
Stream #0:5: Video: mjpeg ... (attached pic)
Le script les detecte et les supprime :
π₯ vraie video HEVC/H264 -> conservee
πΌοΈ cover MJPEG/PNG -> supprimee
Cela evite qu'une image de jaquette soit mappee comme une piste video utile.
Le script log ses decisions principales :
Removed audio stream indexes: 2
Remaining audio stream indexes: 1
Preserved subtitle stream indexes unchanged: 3, 5
Removed unsupported subtitle stream indexes: 4
Removed attachment-like stream indexes: 9
Removed attached-picture video stream indexes: 6
Default audio stream index: 1 (VFF - AC3 5.1)
Audio display order: 1:fr
Lecture rapide :
| Log | Signification |
|---|---|
Removed audio stream indexes |
audios nettoyees |
Remaining audio stream indexes |
audios encodees en sortie |
Preserved subtitle... |
sous-titres copies tels quels |
Removed unsupported subtitle... |
sous-titres dangereux retires |
Removed attachment-like... |
covers/attachments parasites retires |
Default audio stream... |
piste audio par defaut |
Le script est volontairement defensif.
Pour les sous-titres, il prefere :
supprimer une piste douteuse
plutot que faire planter tout l'encodage
Pour l'audio, il prefere :
garder une piste non taguee si elle est impossible a classifier
plutot que supprimer une piste potentiellement importante
Pour les attachments, il prefere :
conserver les polices utiles
supprimer les images/covers parasites
| Fichier | Role |
|---|---|
Custom JS |
source principale du script |
Flow/FILMS - AV1.json |
exemple de flow Films adapte a mon setup |
Flow/SERIES - AV1.json |
exemple de flow Series adapte a mon setup |
Les flows sont secondaires : ils montrent une integration possible, mais le coeur du projet est le fichier Custom JS.
Le script ne repare pas un flux physiquement corrompu.
En passe normale, les PGS sont conserves. Dans les flows fournis, si FFmpeg echoue, une seconde passe retire les sous-titres image-based pour sauver le transcode. Si le fichier echoue encore apres cette seconde passe, il faut probablement remuxer/reparer le fichier source avec MKVToolNix avant Tdarr.
Pour obtenir plus de logs audio, passer :
const VERBOSE_AUDIO_LOGS = false;a :
const VERBOSE_AUDIO_LOGS = true;Puis remettre false apres analyse.
- Ouvrir ton flow Tdarr.
- Placer
Custom JS Functionjuste avantffmpegCommandExecute. - Coller tout le contenu de
Custom JS. - Dans tes
ffmpegCommandCustomArguments, retirer :
-c:s copy- Verifier que le chemin logique reste :
ffmpegCommandCustomArguments -> Custom JS Function -> Execute
Tu peux aussi importer :
Flow/FILMS - AV1.jsonFlow/SERIES - AV1.json
Mais ces flows sont adaptes a un setup personnel :
- sortie Radarr :
/mnt/media/tdarr/watch/radarr - sortie Sonarr :
/mnt/media/tdarr/watch/sonarr - profils AV1 NVENC personnels
Depuis ce dossier :
node --check "Custom JS"Verifier les JSON :
node -e "for (const f of ['Flow/FILMS - AV1.json','Flow/SERIES - AV1.json']) JSON.parse(require('fs').readFileSync(f,'utf8')); console.log('JSON OK')"Verifier que les flows n'ont plus -c:s copy :
node -e "for (const f of ['Flow/FILMS - AV1.json','Flow/SERIES - AV1.json']) console.log(f, !require('fs').readFileSync(f,'utf8').includes('-c:s copy'))"