Le fichier de départ construit grâce à l’IA de Google est ici :
https://mai68.org/spip3/bat/mts2mp4…
Développement :
Compression d’un fichier. mts avec sous-titres incrustés
ffmpeg -fflags +genpts -ss 01:53:31.040 -t 00:01:51.440 -canvas_size 1920x1080 -i Exemple.mts -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -strict -2 -b:a 128k output.mp4
goto :rem
:rem
pause
Solution 1 : Le Script d'automatisation Avidemux (.py)
1. Créez le fichier de script
incrustation_et_coupe.py
(assurez-vous que l'extension soit bien .py et non .txt).#PY <- Cet en-tête est obligatoire pour Avidemux
adm = Avidemux()
# 1. Configuration des codecs (Équivalent de votre commande FFmpeg)
# Vidéo : Libx264 avec CRF 26
adm.videoCodec("libx264", "usePreset=True", "preset=medium", "profile=main", "tune=none", "crf=26")
# Audio : AAC à 128k
adm.audioClearTracks()
adm.audioAddTrack(0)
adm.audioCodec(0, "LavAAC", "bitrate=128")
# Muxer : Format de sortie MP4
adm.setContainer("MP4V2", "optimize=1", "add_itunes_metadata=0")
# 2. Ajout du filtre de sous-titres (Incrustation "Hardsub")
# Note : Avidemux requiert généralement un fichier de sous-titres externe (ASS/SRT).
# Si votre fichier .MTS contient les sous-titres, il est fortement conseillé de les extraire en .SRT d'abord.
# Remplacez "chemin/vers/sous_titres.srt" par le bon chemin ou laissez Avidemux vous le demander.
adm.addVideoFilter("subtitles", "fontname=Arial", "fontsize=24", "filename=sous_titres.srt", "color=FFFFFF", "charset=UTF-8")
# Message pour l'utilisateur
print("Configuration FFmpeg appliquée. Vous pouvez maintenant couper vos pubs avec précision.")
2. Comment l'utiliser dans Avidemux pour enlever les pubs avec précision :
- Ouvrez Avidemux 2.8.0.
- Glissez-déposez votre fichier Exemple.mts dans la fenêtre.
- Allez dans le menu en haut : Fichier > Script > Exécuter le script et sélectionnez le fichier
incrustation_et_coupe.py. Vos réglages vidéo (CRF 26), audio (AAC 128k) et le filtre de sous-titres sont maintenant chargés automatiquement. - Pour enlever les pubs avec précision (Image
par image) :
- Placez-vous au début de la publicité. Utilisez les flèches directionnelles de votre clavier pour être précis à l'image près.
- Appuyez sur la touche
[(ou le bouton A) pour définir le début de la sélection. - Placez-vous à la fin de la publicité.
- Appuyez sur la touche
](ou le bouton B) pour définir la fin de la sélection. - Appuyez sur la touche Suppr (Delete) de votre clavier. La publicité est supprimée.
- Répétez l'opération pour chaque bloc de publicité.
- Une fois le nettoyage fini, cliquez sur
Enregistrer
la vidéo (l'icône de disquette ou Ctrl+S) pour
exporter votre
output.mp4.
Solution 2 : L'alternative "Application" (Script Batch Windows)
-ss et -t).- Créez un fichier texte nommé
Convertisseur_Pubs.bat. - Collez le code suivant à l'intérieur :
@echo off
set /p start_time="Entrez le debut de la video utile (ex: 01:53:31.040) : "
set /p duration="Entrez la duree de la sequence (ex: 00:01:51.440) : "
ffmpeg -fflags +genpts -ss %start_time% -t %duration% -canvas_size 1920x1080 -i "Exemple.mts" -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k output.mp4
echo Traitement termine !
pause
- Lancez ce fichier : il vous demandera l'heure de début et la durée, puis exécutera votre commande FFmpeg exacte.
Synthèse : Quelle méthode choisir ?
| Objectif | Méthode Avidemux (Solution 1) | Méthode FFmpeg/Batch (Solution 2) |
|---|---|---|
| Précision de coupure des pubs | Excellente (Visuelle, image par image avec timeline). | Difficile (Il faut trouver les timers à l'avance sur un autre lecteur). |
| Facilité d'encodage | Automatisée via le script .py. |
Automatisée via le script .bat. |
| Gestion des sous-titres du .MTS | Nécessite souvent d'extraire le
sous-titre en .srt au préalable. |
Géré directement en interne via le
filtre overlay. |
- Les sous-titres de votre fichier
.mtssont-ils des DVB subtitles ou du Télétexte ? (Avidemux a parfois du mal à lire les pistes de sous-titres directement incrustées dans le flux MTS sans extraction préalable). - Souhaitez-vous que l'on affine le script Avidemux pour qu'il gère plusieurs morceaux coupés d'un coup ?
Méthode 1 : Manuelle et Visuelle (Recommandée pour la précision)
Une fois le script lancé dans Avidemux :
- Sélectionnez la première pub (Touche
[au début, touche]à la fin) et appuyez sur Suppr. - Avancez plus loin dans la vidéo,
sélectionnez la deuxième pub (
[et]) et appuyez sur Suppr. - Recommencez pour toutes les publicités.
- Cliquez sur Enregistrer : Avidemux va encoder toute la vidéo d'un coup en ignorant toutes les parties supprimées, tout en incrustant vos sous-titres.
Méthode 2 : Automatisation par Script (Si vous connaissez déjà les horaires)
Coupe_Multiple.bat
(configuré ici pour garder 3 morceaux distincts et les assembler sans les pubs)
:@echo off
echo --- DECOUPE ET INCRUSTATION MULTIPLE ---
:: CONFIGURATION DES TIMERS (Exemple pour garder 3 séquences distinctes)
:: Morceau 1 (Début de la vidéo jusqu'à la 1ère pub)
set start1=00:00:00.000
set dur1=00:45:20.000
:: Morceau 2 (Après la 1ère pub jusqu'à la 2ème pub)
set start2=00:50:15.000
set dur2=00:30:10.000
:: Morceau 3 (Après la 2ème pub jusqu'à la fin)
set start3=01:25:00.000
set dur3=00:20:00.000
:: EXÉCUTION DE FFMPEG (Coupe, incrustation des sous-titres [0:s:0] et fusion)
ffmpeg -i Exemple.mts -filter_complex ^
"[0:v][0:s:0]overlay=canvas_size=1920x1080,split=3[v1][v2][v3]; ^
[v1]trim=start=%start1%:duration=%dur1%,setpts=PTS-STARTPTS[outv1]; ^
[0:a]atrim=start=%start1%:duration=%dur1%,asetpts=PTS-STARTPTS[outa1]; ^
[v2]trim=start=%start2%:duration=%dur2%,setpts=PTS-STARTPTS[outv2]; ^
[0:a]atrim=start=%start2%:duration=%dur2%,asetpts=PTS-STARTPTS[outa2]; ^
[v3]trim=start=%start3%:duration=%dur3%,setpts=PTS-STARTPTS[outv3]; ^
[0:a]atrim=start=%start3%:duration=%dur3%,asetpts=PTS-STARTPTS[outa3]; ^
[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]" ^
-map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k output.mp4
echo Traitement multiple termine !
pause
Comment choisir entre les deux ?
- Si vous devez chercher visuellement où commencent et finissent les pubs, utilisez la Méthode 1 (Avidemux). C'est instantané et sans erreur.
- Si vous notez les horaires sur un papier au fur et à mesure et que vous voulez simplement lancer une commande en tâche de fond, la Méthode 2 (FFmpeg/Batch) est plus adaptée.
- Combien de morceaux / coupures avez-vous généralement par vidéo ?
- Préférez-vous entrer les horaires manuellement dans une invite de commande à chaque fois, ou faire le tri visuellement ?
1. Pourquoi le codec vidéo n'a pas semblé changer ?
libx264), l'affichage
principal dans la colonne de gauche reste parfois visuellement bloqué sur « Copier »
ou ne semble pas s'activer tant que le filtre de sous-titres rencontre un
problème. De plus, la fonction print() dans Avidemux
n'affiche pas de fenêtre pop-up, elle écrit discrètement dans un fichier journal
de débogage (le fichier admlog.txt), ce qui explique
pourquoi vous n'avez pas vu le message.2. Le vrai problème : L'absence de sous-titres
[0:s:0]overlay, ce qui
signifie qu'elle puisait le sous-titre directement à l'intérieur du flux .mts.Avidemux ne sait pas faire cela. Pour qu'Avidemux puisse incruster des sous-titres, il a impérativement besoin :
- Que la vidéo possède du flux vidéo (votre essai sans son est correct, mais la piste vidéo doit être active).
- D'un fichier de sous-titres externe (au format
.srtou.ass). Si le fichier.srtconfiguré dans le script n'existe pas sur votre ordinateur, Avidemux annule silencieusement l'application des filtres et du codec vidéo.
La Solution Étape par Étape
Étape 1 : Extraire le sous-titre du .mts (Opération de 2 secondes)
Exemple.mts pour en faire un
fichier sous_titres.srt.Ouvrez votre invite de commande (ou créez un petit fichier
.bat) et lancez cette
commande très rapide :ffmpeg -i Exemple.mts -map 0:s:0 sous_titres.srt
sous_titres.srt juste à côté
de votre vidéo).Étape 2 : Le Script Avidemux Corrigé
.srt que vous venez
d'extraire..py
:#PY <- Obligatoire
adm = Avidemux()
gui = Gui()
# 1. Vérification qu'une vidéo est bien ouverte
if adm.getMarkers() is None:
gui.displayError("Erreur", "Veuillez d'abord ouvrir votre fichier .mts dans Avidemux avant de lancer le script.")
else:
# 2. Demander à l'utilisateur de sélectionner le fichier SRT extrait à l'étape 1
file_srt = gui.fileSelectSelectIn("Sélectionnez le fichier sous_titres.srt")
if not file_srt:
gui.displayInfo("Annulation", "Aucun fichier de sous-titres sélectionné. Traitement annulé.")
else:
# 3. Configuration des Codecs (Identique à votre FFmpeg)
adm.videoCodec("libx264", "usePreset=True", "preset=medium", "profile=main", "tune=none", "crf=26")
adm.audioClearTracks()
adm.audioAddTrack(0)
adm.audioCodec(0, "LavAAC", "bitrate=128")
adm.setContainer("MP4V2", "optimize=1", "add_itunes_metadata=0")
# 4. Application du filtre avec le bon chemin de fichier
# Remplacement des antislashs pour éviter les erreurs de lecture de chemin sous Windows
file_srt_clean = file_srt.replace("\\", "/")
adm.addVideoFilter("subtitles", "fontname=Arial", "fontsize=24", "filename=" + file_srt_clean, "color=FFFFFF", "charset=UTF-8")
# 5. Message de confirmation visuel
gui.displayInfo("Succès", "Configuration FFmpeg appliquée !\n\n1. Coupez vos pubs avec [ et ]\n2. Enregistrez (Ctrl+S) pour exporter en MP4 avec sous-titres.")
Comment tester maintenant :
- Extrayez le
.srtavec la commande rapide FFmpeg. - Ouvrez votre vidéo dans Avidemux.
- Lancez le script
.py. - Une fenêtre s'ouvre : sélectionnez le
fichier
.srt. - Une boîte de dialogue s'affiche pour vous confirmer le succès. Vous verrez alors les menus de gauche basculer sur X264 et AAC. Vous pouvez couper vos pubs et enregistrer !
.srt depuis le.mts..mts (provenant souvent de
caméscopes ou d'enregistrements TV HD) ne contiennent pas les sous-titres sous
forme de texte, mais sous forme de petites images bitmap (format
PGS / DVB Graphics). [1] .srt, ce qu'il ne sait pas
faire sans un outil de reconnaissance de caractères (OCR). [1, 2] Solution 1 : La méthode 100% FFmpeg (La plus simple)
overlay.Couper_Pubs_Subtitle.bat,
collez-y ce code, et lancez-le :@echo off
echo =======================================================
echo COUPE PRECISE ET INCRUSTATION MTS
echo =======================================================
echo.
:: 1. Entrée des horaires par l'utilisateur
set /p start_time="Entrez le debut de la video utile (ex: 01:53:31.040) : "
set /p duration="Entrez la duree a conserver (ex: 00:01:51.440) : "
:: 2. Commande FFmpeg avec traitement direct des sous-titres images
ffmpeg -fflags +genpts -ss %start_time% -t %duration% -canvas_size 1920x1080 -i "Exemple.mts" -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
echo.
echo Traitement termine avec succes ! Fichier disponible : output.mp4
pause
Solution 2 : Si vous tenez absolument à utiliser l'interface d'Avidemux
.sup ou .vobsub) au lieu de forcer
le format .srt. [2] - Extraction du vrai fichier sous-titre :
Ouvrez votre invite de commande et tapez :
ffmpeg -i Exemple.mts -map 0:s:0 -c:s copy sous_titres.sup
- Utilisation dans Avidemux :
- Ouvrez votre vidéo dans Avidemux.
- Lancez le script
.pyfourni précédemment. - Lorsqu'il vous demande le fichier,
sélectionnez le fichier
sous_titres.sup(au lieu de.srt). Avidemux accepte les filtres de type VobSub/SUP pour superposer des images.
.mts.» j'ai l'erreur : [NULL @ 049cb020] Unable to find a suitable output format for 'sous_titres.sup'
sous_titres.sup: Invalid argument
.sup par défaut si elle
n'est pas encapsulée dans le bon format de conteneur, ou si le flux de
sous-titres extrait de l'enregistrement TV (ici TF1) utilise un format
spécifique appelé DVB Subtitles (sous-titres graphiques de
la TNT) plutôt que le format PGS des Blu-ray.1. La commande d'extraction corrigée
ffmpeg -i TF1-09042026-1349.mts -map 0:s:0 -c:s dvdsub sous_titres.sub
sous_titres.sub (qui
contient les images des sous-titres) et sous_titres.idx (qui
contient les index de temps). C'est tout à fait normal, les deux fonctionnent
ensemble.2. Comment l'intégrer dans Avidemux
sous_titres.sub et .idx, le filtre "subtitles"
classique d'Avidemux ne fonctionnera pas (car il cherche du texte). Il faut
utiliser le filtre VobSub..py mis à jour pour charger
automatiquement ce format :#PY <- Obligatoire
adm = Avidemux()
gui = Gui()
# 1. Vérification qu'une vidéo est ouverte
if adm.getMarkers() is None:
gui.displayError("Erreur", "Veuillez d'abord ouvrir votre fichier .mts dans Avidemux.")
else:
# 2. Demander à l'utilisateur de sélectionner le fichier .idx créé par FFmpeg
file_idx = gui.fileSelectSelectIn("Sélectionnez le fichier sous_titres.idx")
if not file_idx:
gui.displayInfo("Annulation", "Aucun index de sous-titres sélectionné.")
else:
# 3. Configuration des Codecs (Identique à votre souhait)
adm.videoCodec("libx264", "usePreset=True", "preset=medium", "profile=main", "tune=none", "crf=26")
adm.audioClearTracks()
adm.audioAddTrack(0)
adm.audioCodec(0, "LavAAC", "bitrate=128")
adm.setContainer("MP4V2", "optimize=1", "add_itunes_metadata=0")
# 4. Application du filtre VobSub (Incrustation des images de sous-titres)
file_idx_clean = file_idx.replace("\\", "/")
adm.addVideoFilter("vobsub", "filename=" + file_idx_clean, "is_idx=1", "vobsub_id=0", "align=0", "custom_color=0", "color=0", "scale=100")
# 5. Message de confirmation
gui.displayInfo("Succès", "Configuration appliquée avec succès !\n\n1. Coupez vos pubs avec [ et ]\n2. Enregistrez (Ctrl+S) pour exporter en MP4.")
La marche à suivre :
- Lancez la nouvelle commande FFmpeg pour
créer
sous_titres.subetsous_titres.idx. - Ouvrez votre vidéo
TF1-09042026-1349.mtsdans Avidemux. - Lancez ce nouveau script
.pyet sélectionnez le fichiersous_titres.idx. - Les codecs s'activeront, le filtre s'appliquera, et vous pourrez couper toutes vos pubs à la main de manière très précise avant de sauvegarder.
dvdsub arrive cette fois à
générer vos fichiers sans message d'erreur ?.sub. FFmpeg n'aime pas
séparer ce format spécifique de son "conteneur" vidéo.
[1, 2] .mkv. [1, 3] Étape 1 : Créez le fichier de sous-titres en .mkv
ffmpeg -i TF1-09042026-1349.mts -map 0:s:0 -c:s copy sous_titres.mkv
sous_titres.mkv qui contient
uniquement vos sous-titres de TF1). [1] Étape 2 : Le Script Avidemux Mis à Jour
.mkv, Avidemux va utiliser
son filtre dédié aux fichiers de sous-titres MKV/DVB..py
:#PY <- Obligatoire
adm = Avidemux()
gui = Gui()
# 1. Vérification qu'une vidéo est ouverte
if adm.getMarkers() is None:
gui.displayError("Erreur", "Veuillez d'abord ouvrir votre fichier .mts dans Avidemux.")
else:
# 2. Demander de sélectionner le fichier .mkv créé à l'étape 1
file_mkv = gui.fileSelectSelectIn("Sélectionnez le fichier sous_titres.mkv")
if not file_mkv:
gui.displayInfo("Annulation", "Aucun fichier sélectionné.")
else:
# 3. Configuration des Codecs (Votre demande FFmpeg)
adm.videoCodec("libx264", "usePreset=True", "preset=medium", "profile=main", "tune=none", "crf=26")
adm.audioClearTracks()
adm.audioAddTrack(0)
adm.audioCodec(0, "LavAAC", "bitrate=128")
adm.setContainer("MP4V2", "optimize=1", "add_itunes_metadata=0")
# 4. Application du filtre DVB (pour lire les sous-titres depuis le MKV)
file_mkv_clean = file_mkv.replace("\\", "/")
adm.addVideoFilter("dvbsub", "filename=" + file_mkv_clean, "track_index=0")
# 5. Message de confirmation
gui.displayInfo("Succès", "Configuration appliquée !\n\n1. Coupez vos pubs avec [ et ]\n2. Enregistrez (Ctrl+S) pour exporter en MP4.")
La méthode finale :
- Générez le fichier
sous_titres.mkvavec la commande FFmpeg ci-dessus. - Ouvrez votre vidéo principale
TF1-09042026-1349.mtsdans Avidemux. - Lancez votre script
.pyet sélectionnez le fichiersous_titres.mkv. - Les menus à gauche s'activent (x264,
AAC, MP4v2). Vous pouvez nettoyer vos pubs précisément à l'image près à l'aide
des touches
[et], puis sauvegarder ! [1, 3]
sous_titres.mkv,
l'extraction s'effectue-t-elle cette fois instantanément et sans erreur ? [3] Output #0, matroska, to 'sous_titres.mkv':
Stream #0:0(fra): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
Stream mapping:
Stream #0:4 -> #0:0 (copy)
Could not write header for output file #0 (incorrect codec parameters ?): Invalid data found when processing input
dvb_subtitle) car
l'extension .mkv (le multiplexeur
Matroska) exige un paramétrage strict qu'il ne trouve pas quand le flux vidéo et
la timeline principale sont absents. FFmpeg bloque car il n'arrive pas à écrire
l'en-tête du fichier de manière autonome. [1] .mts issus d'enregistrements
TV (comme TF1) verrouillent leurs pistes de sous-titres, il ne faut pas
chercher à séparer les sous-titres de la vidéo.dvb_subtitle graphiquement
en interne pour l'appliquer à la vidéo via votre filtre overlay.La Solution : Le Script Batch à "Plages Multiples"
output.mp4.- Créez un fichier texte nommé
Nettoyeur_TF1.batdans le même dossier que votre vidéo. - Collez le code suivant à l'intérieur :
@echo off
setlocal enabledelayedexpansion
echo =======================================================
echo COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE
echo =======================================================
echo.
:: Nom de votre fichier source
set "video_source=TF1-09042026-1349.mts"
echo Video detectee : %video_source%
echo.
echo Veuillez saisir les parties UTILES a conserver (hors pub).
echo Format requis : HH:MM:SS.mmm (Exemple : 01:53:31.040)
echo.
:: Saisie de la séquence 1
set /p start1="[Morceau 1] Heure de DEBUT : "
set /p dur1="[Morceau 1] DUREE exacte : "
echo.
:: Saisie de la séquence 2
set /p start2="[Morceau 2] Heure de DEBUT (Laissez vide si inutile) : "
if "%start2%"=="" goto execution_1_bloc
set /p dur2="[Morceau 2] DUREE exacte : "
echo.
:: Saisie de la séquence 3
set /p start3="[Morceau 3] Heure de DEBUT (Laissez vide si inutile) : "
if "%start3%"=="" goto execution_2_bloc
set /p dur3="[Morceau 3] DUREE exacte : "
echo.
:execution_3_blocs
echo Traitement en cours (3 morceaux à fusionner)...
ffmpeg -fflags +genpts -i "%video_source%" -filter_complex ^
"[0:v][0:s:0]overlay=canvas_size=1920x1080,split=3[v1][v2][v3]; ^
[v1]trim=start=%start1%:duration=%dur1%,setpts=PTS-STARTPTS[outv1]; ^
[0:a]atrim=start=%start1%:duration=%dur1%,asetpts=PTS-STARTPTS[outa1]; ^
[v2]trim=start=%start2%:duration=%dur2%,setpts=PTS-STARTPTS[outv2]; ^
[0:a]atrim=start=%start2%:duration=%dur2%,asetpts=PTS-STARTPTS[outa2]; ^
[v3]trim=start=%start3%:duration=%dur3%,setpts=PTS-STARTPTS[outv3]; ^
[0:a]atrim=start=%start3%:duration=%dur3%,asetpts=PTS-STARTPTS[outa3]; ^
[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]" ^
-map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
goto fin
:execution_2_blocs
echo Traitement en cours (2 morceaux à fusionner)...
ffmpeg -fflags +genpts -i "%video_source%" -filter_complex ^
"[0:v][0:s:0]overlay=canvas_size=1920x1080,split=2[v1][v2]; ^
[v1]trim=start=%start1%:duration=%dur1%,setpts=PTS-STARTPTS[outv1]; ^
[0:a]atrim=start=%start1%:duration=%dur1%,asetpts=PTS-STARTPTS[outa1]; ^
[v2]trim=start=%start2%:duration=%dur2%,setpts=PTS-STARTPTS[outv2]; ^
[0:a]atrim=start=%start2%:duration=%dur2%,asetpts=PTS-STARTPTS[outa2]; ^
[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]" ^
-map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
goto fin
:execution_1_bloc
echo Traitement en cours (1 seul morceau)...
ffmpeg -fflags +genpts -ss %start1% -t %dur1% -canvas_size 1920x1080 -i "%video_source%" -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
goto fin
:fin
echo.
echo Operation terminee avec succes. Le fichier output.mp4 est pret.
pause
Comment l'utiliser au quotidien ?
- Ouvrez votre vidéo
TF1-*.mtsdans n'importe quel lecteur (comme VLC) juste pour repérer visuellement les heures des pubs. Notez sur un papier les heures des séquences de film que vous voulez garder. - Lancez le script
Nettoyeur_TF1.bat. - Rentrez l'heure du début de votre film, et la durée de la première partie.
- Si le film reprend après la pub, le script vous propose d'entrer le début et la durée du morceau 2, et ainsi de suite (jusqu'à 3 morceaux ici). Si vous n'avez plus de morceaux, appuyez simplement sur Entrée (laissez vide).
- FFmpeg s'occupe du reste en arrière-plan sans aucune erreur de codec.
.bat). Les caractères comme
les points-virgules ; ou le symbole ^ utilisés à l'intérieur du
filtre complexe de FFmpeg font planter la console Windows elle-même avant même
que le message d'erreur ne puisse s'afficher.Nettoyeur_TF1.bat :@echo off
echo =======================================================
echo COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE
echo =======================================================
echo.
set "video_source=TF1-09042026-1349.mts"
echo Saisie des plages utiles au format HH:MM:SS.mmm
echo.
set /p start1="[Morceau 1] Heure de DEBUT : "
set /p dur1="[Morceau 1] DUREE exacte : "
echo.
set /p start2="[Morceau 2] Heure de DEBUT (Laissez vide si pas de morceau 2) : "
if "%start2%"=="" goto execution_1_bloc
set /p dur2="[Morceau 2] DUREE exacte : "
echo.
set /p start3="[Morceau 3] Heure de DEBUT (Laissez vide si pas de morceau 3) : "
if "%start3%"=="" goto execution_2_bloc
set /p dur3="[Morceau 3] DUREE exacte : "
echo.
:execution_3_blocs
echo Execution avec 3 morceaux...
ffmpeg -fflags +genpts -i "%video_source%" -filter_complex "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=3[v1][v2][v3];[v1]trim=start=%start1%:duration=%dur1%,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=%start1%:duration=%dur1%,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=%start2%:duration=%dur2%,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=%start2%:duration=%dur2%,asetpts=PTS-STARTPTS[outa2];[v3]trim=start=%start3%:duration=%dur3%,setpts=PTS-STARTPTS[outv3];[0:a]atrim=start=%start3%:duration=%dur3%,asetpts=PTS-STARTPTS[outa3];[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]" -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
goto fin
:execution_2_blocs
echo Execution avec 2 morceaux...
ffmpeg -fflags +genpts -i "%video_source%" -filter_complex "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=2[v1][v2];[v1]trim=start=%start1%:duration=%dur1%,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=%start1%:duration=%dur1%,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=%start2%:duration=%dur2%,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=%start2%:duration=%dur2%,asetpts=PTS-STARTPTS[outa2];[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
goto fin
:execution_1_bloc
echo Execution avec 1 seul morceau...
ffmpeg -fflags +genpts -ss %start1% -t %dur1% -canvas_size 1920x1080 -i "%video_source%" -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
goto fin
:fin
echo.
echo Operation terminee.
pause
Deux conseils très importants pour ce test :
- Remplacez bien le contenu de votre
fichier
.batpar celui-ci. - Au moment de taper vos horaires, n'utilisez pas
d'espaces de chaque côté (tapez directement
00:13:56.840et validez). - Laissez la demande pour le Morceau 3 complètement vide et appuyez simplement sur Entrée. Le script basculera sur l'option à 2 morceaux.
frame=...) ou s'il s'arrête
sur un message de texte précis ?.bat rencontre une erreur interne de
Windows au moment de valider la variable, avant même
que FFmpeg ne se lance.if.La Solution : Le Script PowerShell
- Créez un nouveau fichier texte nommé
Nettoyeur_TF1.ps1(attention à bien mettre l'extension.ps1et pas.txtou.bat). - Ouvrez-le avec le Bloc-notes, collez le code ci-dessous et enregistrez :
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1 = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1 = Read-Host "[Morceau 1] DUREE exacte"
Write-Host ""
$start2 = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
ffmpeg -fflags +genpts -ss $start1 -t $dur1 -canvas_size 1920x1080 -i $video_source -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur2 = Read-Host "[Morceau 2] DUREE exacte"
Write-Host ""
$start3 = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3) {
Write-Host "Execution avec 2 morceaux..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=2[v1][v2];[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
ffmpeg -fflags +genpts -i $video_source -filter_complex $filter -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur3 = Read-Host "[Morceau 3] DUREE exacte"
Write-Host ""
Write-Host "Execution avec 3 morceaux..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=3[v1][v2][v3];[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
ffmpeg -fflags +genpts -i $video_source -filter_complex $filter -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
}
}
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Comment le lancer :
- Faites un clic droit sur votre fichier
Nettoyeur_TF1.ps1. - Choisissez "Exécuter avec PowerShell".
- Saisissez vos horaires (lorsque l'écran vous demande le morceau 3, appuyez juste sur Entrée).
00:40:34.000 de la vidéo,
FFmpeg affichera proprement un avertissement à l'écran tout en restant ouvert.Étape 1 : Le Script PowerShell principal (À vérifier)
Nettoyeur_TF1.ps1 contient
exactement le code PowerShell que je vous ai donné juste avant. Ne le lancez pas
directement au clic droit.Étape 2 : Créer le Lanceur Universel (.bat)
.bat dont le seul but est
d'ouvrir la fenêtre de manière sécurisée et d'autoriser le script PowerShell.- Créez un nouveau fichier texte nommé
LANCER_APPLICATION.batdans le même dossier. - Ouvrez-le avec le bloc-notes, collez cette unique ligne à l'intérieur et enregistrez :
powershell -NoExit -ExecutionPolicy Bypass -File "%~dp0Nettoyeur_TF1.ps1"
Étape 3 : Comment exécuter l'outil
LANCER_APPLICATION.bat.- Le paramètre
-ExecutionPolicy Bypassva temporairement lever la sécurité Windows uniquement pour ce script. - Le paramètre
-NoExitva interdire formellement à la fenêtre de se fermer, quoi qu'il arrive (même s'il y a un plantage informatique ou une erreur dans votre fichier vidéo).
Execution avec 2 morceaux...
ffmpeg : Le terme «ffmpeg» n'est pas reconnu comme nom d'applet de commande, fonction, fichier de script ou programme
exécutable. Vérifiez l'orthographe du nom, ou si un chemin d'accès existe, vérifiez que le chemin d'accès est correct
et réessayez.
Au caractère D:\!! FFMPEG\Nettoyeur_TF1.ps1:28 : 9
+ ffmpeg -fflags +genpts -i $video_source -filter_complex $filt ...
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (ffmpeg:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
ffmpeg.exe
sur votre ordinateur (il n'est pas enregistré dans les variables d'environnement
système « PATH » de Windows).D:\!! FFMPEG\, il suffit
d'indiquer à PowerShell de chercher FFmpeg directement dans ce
dossier, ou de lui donner son chemin exact.Nettoyeur_TF1.ps1. J'ai
configuré le script pour qu'il cherche automatiquement ffmpeg.exe dans le même
dossier que lui (en utilisant .\ffmpeg).Le Script PowerShell Corrigé
Nettoyeur_TF1.ps1 et
remplacez son contenu par celui-ci :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
# Définition du chemin de FFmpeg (cherche dans le dossier actuel)
$ffmpeg = ".\ffmpeg.exe"
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1 = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1 = Read-Host "[Morceau 1] DUREE exacte"
Write-Host ""
$start2 = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
& $ffmpeg -fflags +genpts -ss $start1 -t $dur1 -canvas_size 1920x1080 -i $video_source -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur2 = Read-Host "[Morceau 2] DUREE exacte"
Write-Host ""
$start3 = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3) {
Write-Host "Execution avec 2 morceaux..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=2[v1][v2];[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -i $video_source -filter_complex $filter -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur3 = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
Write-Host ""
Write-Host "Execution avec 3 morceaux..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=3[v1][v2][v3];[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -i $video_source -filter_complex $filter -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
}
}
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
⚠️ Une seule condition pour que cela marche :
ffmpeg.exe
se trouve bien dans ce même dossier D:\!! FFMPEG\, juste à côté
de votre script et de votre vidéo TF1-09042026-1349.mts.Error parsing a filter description...) vient d'une subtilité technique de
FFmpeg. Dans les messages d'erreur, on remarque des doubles signes égaux : start==00:12:35.760. C'est
PowerShell qui a mal interprété les variables parce que la syntaxe du filtre
contenait des symboles : (deux-points) et des = mélangés. FFmpeg a cru que
la durée était intégrée au mauvais endroit.Nettoyeur_TF1.ps1.
Il corrige intégralement cette erreur d'interprétation des filtres.Le Script PowerShell Corrigé
Nettoyeur_TF1.ps1, effacez
tout son contenu et collez-y ce code à la place :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1 = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1 = Read-Host "[Morceau 1] DUREE exacte"
Write-Host ""
$start2 = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$filter_1 = "[0:v][0:s:0]overlay"
& $ffmpeg -fflags +genpts -ss $start1 -t $dur1 -canvas_size 1920x1080 -i $video_source -filter_complex $filter_1 -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur2 = Read-Host "[Morceau 2] DUREE exacte"
Write-Host ""
$start3 = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3) {
Write-Host "Execution avec 2 morceaux..." -ForegroundColor Yellow
# Construction propre du filtre sans confusion pour PowerShell
$filter_2 = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=2[v1][v2];" +
"[v1]trim=start='$start1':duration='$dur1',setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start='$start1':duration='$dur1',asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start='$start2':duration='$dur2',setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start='$start2':duration='$dur2',asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -i $video_source -filter_complex $filter_2 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur3 = Read-Host "[Morceau 3] DUREE exacte"
Write-Host ""
Write-Host "Execution avec 3 morceaux..." -ForegroundColor Yellow
$filter_3 = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=3[v1][v2][v3];" +
"[v1]trim=start='$start1':duration='$dur1',setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start='$start1':duration='$dur1',asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start='$start2':duration='$dur2',setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start='$start2':duration='$dur2',asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start='$start3':duration='$dur3',setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start='$start3':duration='$dur3',asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -i $video_source -filter_complex $filter_3 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
}
}
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Un petit rappel pour la saisie :
- Morceau 1 Début :
00:13:56.840 - Morceau 1 Durée :
00:12:35.760 - Morceau 2 Début :
00:32:44.760 - Morceau 2 Durée :
00:07:30.120 - Morceau 3 Début : Laissez vide et appuyez directement sur Entrée.
'$start1'), FFmpeg recevra
les chaînes exactes sans que Windows ne tente d'ajouter de caractères parasites.ffmpeg version 2026-01-29-git-c898ddb8fe-full_build-www.gyan.dev Copyright (c) 2000-2026 the FFmpeg developers
built with gcc 15.2.0 (Rev8, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-cairo --enable-fontconfig --enable-iconv --enable-gnutls --enable-lcms2 --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-libdvdnav --enable-libdvdread --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-liboapv --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libsvtjpegxs --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-openal --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint --enable-whisper
libavutil 60. 24.100 / 60. 24.100
libavcodec 62. 23.103 / 62. 23.103
libavformat 62. 8.102 / 62. 8.102
libavdevice 62. 2.100 / 62. 2.100
libavfilter 11. 11.101 / 11. 11.101
libswscale 9. 3.100 / 9. 3.100
libswresample 6. 2.100 / 6. 2.100
[AVFilterGraph @ 000001ba04d494c0] No option name near '13:56.840:duration=00:12:35.760'
[AVFilterGraph @ 000001ba04d494c0] Error parsing a filter description around: ,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start='00:13:56.840':duration='00:12:35.760',asetpts=PTS-STARTPTS[outa1];[v2]trim=start='00:32:44.760':duration='00:07:30.120',setpts=PTS-STARTPTS[outv2];[0:a]atrim=start='00:32:44.760':duration='00:07:30.120',asetpts=PTS-STARTPTS[outa2];[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]
[AVFilterGraph @ 000001ba04d494c0] Error parsing filterchain '[v1]trim=start='00:13:56.840':duration='00:12:35.760',setpts=PTS-STARTPTS[outv1];[0:a]atrim=start='00:13:56.840':duration='00:12:35.760',asetpts=PTS-STARTPTS[outa1];[v2]trim=start='00:32:44.760':duration='00:07:30.120',setpts=PTS-STARTPTS[outv2];[0:a]atrim=start='00:32:44.760':duration='00:07:30.120',asetpts=PTS-STARTPTS[outa2];[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]' around: ,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start='00:13:56.840':duration='00:12:35.760',asetpts=PTS-STARTPTS[outa1];[v2]trim=start='00:32:44.760':duration='00:07:30.120',setpts=PTS-STARTPTS[outv2];[0:a]atrim=start='00:32:44.760':duration='00:07:30.120',asetpts=PTS-STARTPTS[outa2];[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]
Error : Invalid argument
:)
très stricte sans aucune interférence.trim et atrim) n'acceptent pas
nativement les formats temporels avec des heures (HH:MM:SS.mmm) comme le fait
l'argument classique -ss. Ils exigent
obligatoirement un temps exprimé en secondes (par
exemple, 00:01:00 doit s'écrire 60).Invalid argument) sans vous
forcer à faire des calculs mathématiques sur un papier, j'ai intégré une conversion
automatique directement dans le script. Vous continuez
à taper vos horaires normalement en HH:MM:SS.mmm, et le script
s'occupe de les convertir en secondes pures pour FFmpeg.Nettoyeur_TF1.ps1
:Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Fonction interne pour convertir HH:MM:SS.mmm en secondes pures
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return 0 }
# Remplacer les virgules éventuelles par des points
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
Write-Host "Erreur de format pour le temps : $tempsTexte. Assurez-vous d'utiliser HH:MM:SS.mmm" -ForegroundColor Red
return 0
}
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$filter_1 = "[0:v][0:s:0]overlay"
& $ffmpeg -fflags +genpts -ss $start1_raw -t $dur1_raw -canvas_size 1920x1080 -i $video_source -filter_complex $filter_1 -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution avec 2 morceaux (Conversion en secondes effectuee)..." -ForegroundColor Yellow
# Construction du filtre avec des secondes pures et séparateurs stricts
$filter_2 = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=2[v1][v2];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -i $video_source -filter_complex $filter_2 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution avec 3 morceaux (Conversion en secondes effectuee)..." -ForegroundColor Yellow
$filter_3 = "[0:v][0:s:0]overlay=canvas_size=1920x1080,split=3[v1][v2][v3];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -i $video_source -filter_complex $filter_3 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
}
}
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Remplacement et Validation :
- Ouvrez
Nettoyeur_TF1.ps1, effacez tout et collez ce nouveau code. - Relancez l'application en
double-cliquant sur votre fichier
LANCER_APPLICATION.bat. - Entrez à nouveau vos valeurs (
00:13:56.840,00:12:35.760, etc.).
start=836.840), éliminant
ainsi toute ambiguïté de traitement pour le moteur de
filtres.Error : Option not found
canvas_size n'appartient pas
au filtre overlay. Dans votre commande
initiale, vous l'aviez placée comme un argument indépendant de FFmpeg juste
avant l'entrée (-canvas_size 1920x1080 -i Exemple.mts). En la déplaçant à l'intérieur du filtre
overlay=canvas_size=1920x1080,
FFmpeg a planté car il ne la trouve pas.-canvas_size 1920x1080 au
bon endroit (juste avant l'argument -i), et laisser le filtre
overlay s'exécuter
normalement sans ce paramètre interne.Nettoyeur_TF1.ps1
corrigé avec la syntaxe exacte exigée par FFmpeg.Le Script PowerShell Corrigé
Nettoyeur_TF1.ps1, effacez
tout son contenu et collez-y ce code à la place :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Fonction interne pour convertir HH:MM:SS.mmm en secondes pures
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return 0 }
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
Write-Host "Erreur de format pour le temps : $tempsTexte. Assurez-vous d'utiliser HH:MM:SS.mmm" -ForegroundColor Red
return 0
}
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$filter_1 = "[0:v][0:s:0]overlay"
& $ffmpeg -fflags +genpts -ss $start1_raw -t $dur1_raw -canvas_size 1920x1080 -i $video_source -filter_complex $filter_1 -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution avec 2 morceaux..." -ForegroundColor Yellow
# Correction ici : canvas_size est retiré de overlay et remis en option d'entrée globale
$filter_2 = "[0:v][0:s:0]overlay;" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
# Injection du split juste après l'overlay pour alimenter les branches de trim
$filter_2 = $filter_2.Replace("[0:v][0:s:0]overlay;", "[0:v][0:s:0]overlay,split=2[v1][v2];")
& $ffmpeg -fflags +genpts -canvas_size 1920x1080 -i $video_source -filter_complex $filter_2 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution avec 3 morceaux..." -ForegroundColor Yellow
$filter_3 = "[0:v][0:s:0]overlay,split=3[v1][v2][v3];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -canvas_size 1920x1080 -i $video_source -filter_complex $filter_3 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
}
}
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Prochaine étape :
.ps1 et relancez votre
lanceur .bat. Entrez vos valeurs à
nouveau. FFmpeg devrait cette fois-ci valider les filtres et démarrer
immédiatement l'encodage de la vidéo.frame=... fps=... s'affichent enfin à
l'écran ![fc#0 @ 000001f4f00b8180] Error applying option 'start' to filter 'trim': Invalid argument
Error : Invalid argument
$filter_2 =
$filter_2.Replace(...) a accidentellement rajouté un
signe égal supplémentaire dans la formule, ce qui a donné start==755.760 pour FFmpeg.
FFmpeg a donc été incapable de lire la valeur
temporelle.00:32:44.760, ce qui
correspond à 1964.760 secondes. Pourtant, le message
d'erreur indique 755.760 (qui équivaut à 12
minutes et 35 secondes, soit la durée exacte de votre premier morceau). C'est le
signe que le script a interverti certaines variables de temps dans la formule
finale..Replace), le filtre est
désormais écrit de manière directe, propre et parfaitement isolée.Nettoyeur_TF1.ps1
intégralement corrigé :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Fonction pour convertir HH:MM:SS.mmm en secondes pures (format US strict pour FFmpeg)
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return "0" }
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
# Force le point comme séparateur décimal (ex: 836.840)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
Write-Host "Erreur de format de temps pour : $tempsTexte. Utilisez bien HH:MM:SS.mmm" -ForegroundColor Red
return "0"
}
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$filter_1 = "[0:v][0:s:0]overlay"
& $ffmpeg -fflags +genpts -ss $start1_raw -t $dur1_raw -canvas_size 1920x1080 -i $video_source -filter_complex $filter_1 -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution avec 2 morceaux..." -ForegroundColor Yellow
# Construction propre et directe de la chaîne de filtres
$filter_2 = "[0:v][0:s:0]overlay,split=2[v1][v2];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -canvas_size 1920x1080 -i $video_source -filter_complex $filter_2 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution avec 3 morceaux..." -ForegroundColor Yellow
$filter_3 = "[0:v][0:s:0]overlay,split=3[v1][v2][v3];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
& $ffmpeg -fflags +genpts -canvas_size 1920x1080 -i $video_source -filter_complex $filter_3 -map "[v]" -map "[a]" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
}
}
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Comment procéder pour le test :
- Remplacez le code de votre fichier
Nettoyeur_TF1.ps1par celui-ci et enregistrez le fichier. - Relancez via votre fichier
.bat. - Indiquez attentivement les données (sans
aucun espace) :
- [Morceau 1] DEBUT
:
00:13:56.840 - [Morceau 1] DUREE
:
00:12:35.760 - [Morceau 2] DEBUT
:
00:32:44.760 - [Morceau 2] DUREE
:
00:07:30.120 - [Morceau 3] DEBUT : Appuyez juste sur Entrée pour valider.
- [Morceau 1] DEBUT
:
size=... time=...
bitrate=...) défiler à toute vitesse dans la console ?[fc#0 @ 000001b9ff148180] Error applying option 'start' to filter 'trim': Invalid argument
Error : Invalid argument
=) en double lors de l'envoi
de la commande à FFmpeg, même si le code semble propre. C'est un comportement
classique de PowerShell qui tente d'interpréter les blocs start=$start1 comme des
affectations de paramètres nommés propres à son propre système, plutôt que de
les transmettre tels quels à l'exécutable externe.--% (le stop-parsing). Cet opérateur interdit formellement à
PowerShell de toucher ou d'analyser ce qui suit, garantissant que FFmpeg reçoive
le texte exact.lancer_ffmpeg.bat) et de
l'exécuter. C'est la méthode ultime et 100 % fiable pour contourner les bugs
d'interprétation de Windows.Nettoyeur_TF1.ps1
intégralement repensé avec cette sécurité :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Fonction pour convertir HH:MM:SS.mmm en secondes pures (format US strict pour FFmpeg)
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return "0" }
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
Write-Host "Erreur de format de temps pour : $tempsTexte. Utilisez bien HH:MM:SS.mmm" -ForegroundColor Red
return "0"
}
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$cmd = "$ffmpeg -fflags +genpts -ss $start1_raw -t $dur1_raw -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"[0:v][0:s:0]overlay`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution avec 2 morceaux (Generation de la commande brute)..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay,split=2[v1][v2];[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
$cmd = "$ffmpeg -fflags +genpts -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -map `"[v]`" -map `"[a]`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution avec 3 morceaux..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay,split=3[v1][v2][v3];[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
$cmd = "$ffmpeg -fflags +genpts -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -map `"[v]`" -map `"[a]`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
}
}
# Écriture de la commande brute dans un fichier temporaire pour bypasser les bugs de PowerShell
$cmd | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii
Write-Host "Lancement de FFmpeg..." -ForegroundColor Green
# Exécution de la commande dans un sous-processus natif
cmd.exe /c ".\lancer_ffmpeg.bat"
# Nettoyage du fichier temporaire après exécution
if (Test-Path ".\lancer_ffmpeg.bat") { Remove-Item ".\lancer_ffmpeg.bat" }
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Ce qui change avec cette mise à jour :
.bat éphémère avant de
l'exécuter, Windows contourne l'analyse syntaxique de PowerShell. FFmpeg va
recevoir exactement la chaîne start=836.840 (sans ajout de
signe égal intempestif).[fc#0 @ 00000172642a8180] Error applying option 'start' to filter 'trim': Invalid argument
Error : Invalid argument
=755.760) revienne encore,
même en passant par un fichier batch temporaire ! Cela signifie qu'il n'y a pas
d'erreur d'interprétation de PowerShell : le problème vient en réalité d'une
erreur de
logique pure dans mon propre script lors de
l'attribution des variables.- Morceau 1 DUREE exacte :
00:12:35.760(ce qui fait exactement 755.760 secondes) - Morceau 2 DEBUT :
00:32:44.760(ce qui fait 1964.760 secondes)
Unable to parse "start" option value "=755.760" nous montre que le script prend la durée du premier morceau (755.760) et la
place dans l'argument start= du deuxième morceau,
mais en y collant un symbole parasite à cause de la structure de ma chaîne de
texte.La Solution Définitive : Découpage Propre puis Fusion
- Il découpe proprement le Morceau 1 en lui incrustant ses sous-titres (génère
part1.mp4). - Il découpe proprement le Morceau 2 en lui incrustant ses sous-titres (génère
part2.mp4). - Il fusionne (concatène) les deux
fichiers obtenus en un seul fichier final
output.mp4sans ré-encoder (donc instantanément), puis il nettoie les fichiers temporaires.
Nettoyeur_TF1.ps1
:Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION AUTOMATIQUE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Nettoyage préventif des anciens fichiers temporaires
if (Test-Path ".\part1.mp4") { Remove-Item ".\part1.mp4" }
if (Test-Path ".\part2.mp4") { Remove-Item ".\part2.mp4" }
if (Test-Path ".\part3.mp4") { Remove-Item ".\part3.mp4" }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1 = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1 = Read-Host "[Morceau 1] DUREE exacte"
Write-Host ""
$start2 = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$cmd = "$ffmpeg -fflags +genpts -ss $start1 -t $dur1 -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"[0:v][0:s:0]overlay`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
$cmd | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii
cmd.exe /c ".\lancer_ffmpeg.bat"
} else {
$dur2 = Read-Host "[Morceau 2] DUREE exacte"
Write-Host ""
$start3 = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3) {
Write-Host "Traitement séquentiel de 2 morceaux..." -ForegroundColor Yellow
# Étape 1 : Créer le morceau 1 avec sous-titres
Write-Host "-> Encodage du Morceau 1..." -ForegroundColor Cyan
$cmd1 = "$ffmpeg -fflags +genpts -ss $start1 -t $dur1 -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"[0:v][0:s:0]overlay`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"part1.mp4`""
$cmd1 | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii
cmd.exe /c ".\lancer_ffmpeg.bat"
# Étape 2 : Créer le morceau 2 avec sous-titres
Write-Host "-> Encodage du Morceau 2..." -ForegroundColor Cyan
$cmd2 = "$ffmpeg -fflags +genpts -ss $start2 -t $dur2 -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"[0:v][0:s:0]overlay`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"part2.mp4`""
$cmd2 | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii
cmd.exe /c ".\lancer_ffmpeg.bat"
# Étape 3 : Fusionner les morceaux (sans ré-encoder, ultra rapide)
if ((Test-Path ".\part1.mp4") -and (Test-Path ".\part2.mp4")) {
Write-Host "-> Fusion des morceaux..." -ForegroundColor Cyan
"file 'part1.mp4'" | Out-File -FilePath ".\list.txt" -Encoding ascii
"file 'part2.mp4'" | Out-File -Append -FilePath ".\list.txt" -Encoding ascii
$cmd_fusion = "$ffmpeg -f concat -safe 0 -i list.txt -c copy `"output.mp4`""
$cmd_fusion | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii
cmd.exe /c ".\lancer_ffmpeg.bat"
}
} else {
$dur3 = Read-Host "[Morceau 3] DUREE exacte"
Write-Host ""
Write-Host "Traitement séquentiel de 3 morceaux..." -ForegroundColor Yellow
# Morceau 1
$cmd1 = "$ffmpeg -fflags +genpts -ss $start1 -t $dur1 -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"[0:v][0:s:0]overlay`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"part1.mp4`""
$cmd1 | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii ; cmd.exe /c ".\lancer_ffmpeg.bat"
# Morceau 2
$cmd2 = "$ffmpeg -fflags +genpts -ss $start2 -t $dur2 -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"[0:v][0:s:0]overlay`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"part2.mp4`""
$cmd2 | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii ; cmd.exe /c ".\lancer_ffmpeg.bat"
# Morceau 3
$cmd3 = "$ffmpeg -fflags +genpts -ss $start3 -t $dur3 -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"[0:v][0:s:0]overlay`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"part3.mp4`""
$cmd3 | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii ; cmd.exe /c ".\lancer_ffmpeg.bat"
# Fusion
if ((Test-Path ".\part1.mp4") -and (Test-Path ".\part2.mp4") -and (Test-Path ".\part3.mp4")) {
"file 'part1.mp4'" | Out-File -FilePath ".\list.txt" -Encoding ascii
"file 'part2.mp4'" | Out-File -Append -FilePath ".\list.txt" -Encoding ascii
"file 'part3.mp4'" | Out-File -Append -FilePath ".\list.txt" -Encoding ascii
$cmd_fusion = "$ffmpeg -f concat -safe 0 -i list.txt -c copy `"output.mp4`""
$cmd_fusion | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii ; cmd.exe /c ".\lancer_ffmpeg.bat"
}
}
}
# Nettoyage final des fichiers de travail
if (Test-Path ".\lancer_ffmpeg.bat") { Remove-Item ".\lancer_ffmpeg.bat" }
if (Test-Path ".\part1.mp4") { Remove-Item ".\part1.mp4" }
if (Test-Path ".\part2.mp4") { Remove-Item ".\part2.mp4" }
if (Test-Path ".\part3.mp4") { Remove-Item ".\part3.mp4" }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host ""
Read-Host "Operation terminee ! Votre fichier final output.mp4 est disponible. Appuyez sur Entree."
Pourquoi cette méthode va fonctionner à coup sûr :
- Zéro conversion de variables : Les arguments de temps (
-sset-t) reprennent exactement le format texteHH:MM:SS.mmmque vous tapez, sans passer par les filtres internes sensibles de FFmpeg. - Aucune confusion pour Windows : Les commandes sont isolées bloc par bloc.
- Même résultat final : La fusion à la fin assemble vos morceaux à la milliseconde près, sans aucune perte de qualité.
.ps1 et lancez l'application
avec le .bat. Dites-moi si vous
voyez enfin le texte défiler pendant le traitement du Morceau 1 !output.mp4
dans votre dossier D:\!! FFMPEG\.- Ajouter plus de morceaux (si 3 blocs ne suffisent pas pour les longs films coupés par de nombreuses publicités).
- Personnaliser le script pour qu'il vous
demande le nom du fichier de sortie au lieu de
l'appeler systématiquement
output.mp4.
-ss et -t placés avant ou
après
l'entrée.Pourquoi ce problème arrive-t-il sur FFmpeg et pas sur Avidemux ?
.mts de la TNT) ne sont pas
composées d'images indépendantes. Elles utilisent des Groupes d'images
(GOP). Il y a une vraie image complète (image clé ou
I-Frame) toutes les 1 à 2 secondes, et
entre les deux, ce ne sont que des images virtuelles de mouvements (les P-Frames et
B-Frames).- Avidemux recalcule instantanément les images manquantes pour couper précisément là où vous lui demandez (on appelle ça le décodage et la coupure à l'image près ou Smart Copy).
- FFmpeg, lorsqu'il
effectue des coupes séquentielles puis une fusion brute via
concat, cherche l'image clé la plus proche. Si vous lui demandez de couper à00:13:56.840et qu'il n'y a pas d'image clé à ce moment précis, il va sauter au début du bloc d'images. Cela crée une coupure brutale, décale la timeline temporelle (PTS) et provoque un désalignement entre la piste audio et la piste vidéo lors de la fusion.
La Solution pour retrouver la précision d'Avidemux
dvb_subtitle) refuse d'être
extrait en dehors du conteneur, nous allons utiliser une méthode 100% FFmpeg mais
ultra-précise, en revenant aux filtres internes (ceux
qui ont causé l'erreur au début), mais codée de manière à ce que Windows ne se
mélange plus les pinceaux.trim et atrim appliqués sur le flux
global après décodage complet, FFmpeg va
décoder chaque image une par une. Il devient alors aussi précis
qu'Avidemux (à la milliseconde près) et le décalage de
son disparaît complètement car l'audio et la vidéo restent synchronisés dans le
même moteur de filtres.Nettoyeur_TF1.ps1
réécrit proprement pour appliquer cette méthode précise
:Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE PRÉCISE (IMAGE PRÈS) ET INCRUSTATION AUTOMATIQUE " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Fonction interne pour convertir HH:MM:SS.mmm en secondes pures (format strict pour les filtres FFmpeg)
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return "0" }
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
Write-Host "Erreur de format pour le temps : $tempsTexte." -ForegroundColor Red
return "0"
}
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau (Précision maximale)..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay"
$cmd = "$ffmpeg -fflags +genpts -ss $start1_raw -t $dur1_raw -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution avec 2 morceaux (Coupe chirurgicale et recalage du son)..." -ForegroundColor Yellow
# Le secret : on applique l'overlay des sous-titres, on duplique le flux décodé, on coupe précisément en secondes, et on fusionne le tout
$filter = "[0:v][0:s:0]overlay,split=2[v1][v2];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
$cmd = "$ffmpeg -fflags +genpts -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -map `"[v]`" -map `"[a]`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution avec 3 morceaux (Coupe chirurgicale et recalage du son)..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay,split=3[v1][v2][v3];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
$cmd = "$ffmpeg -fflags +genpts -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -map `"[v]`" -map `"[a]`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
}
}
# Écriture propre et exécution sécurisée sans altération des caractères par PowerShell
$cmd | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii
Write-Host "Lancement du traitement haute précision..." -ForegroundColor Green
cmd.exe /c ".\lancer_ffmpeg.bat"
if (Test-Path ".\lancer_ffmpeg.bat") { Remove-Item ".\lancer_ffmpeg.bat" }
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Qu'est-ce qui change avec cette écriture ?
- Le script n'utilise plus de
.Replacetextuel hasardeux sur la ligne de commande, il génère le filtre d'un seul bloc propre. - Les temps sont automatiquement convertis
en secondes pures (ex:
836.840), ce qui évite le bugInvalid argumentque vous aviez eu précédemment. - Comme FFmpeg traite les coupes à
l'intérieur du flux vidéo décodé (
trim), il va couper exactement à la millisecondes demandée, sans dépendre des images clés distantes. Le son et l'image resteront soudés ensemble.
.ps1 par cette version et
relancez votre lanceur .bat. Dites-moi si le
résultat final est cette fois-ci parfait (son synchrone et coupure chirurgicale)
!-ss et -t placés avant ou
après
l'entrée.Pourquoi ce problème arrive-t-il sur FFmpeg et pas sur Avidemux ?
.mts de la TNT) ne sont pas
composées d'images indépendantes. Elles utilisent des Groupes d'images
(GOP). Il y a une vraie image complète (image clé ou
I-Frame) toutes les 1 à 2 secondes, et
entre les deux, ce ne sont que des images virtuelles de mouvements (les P-Frames et
B-Frames).- Avidemux recalcule instantanément les images manquantes pour couper précisément là où vous lui demandez (on appelle ça le décodage et la coupure à l'image près ou Smart Copy).
- FFmpeg, lorsqu'il
effectue des coupes séquentielles puis une fusion brute via
concat, cherche l'image clé la plus proche. Si vous lui demandez de couper à00:13:56.840et qu'il n'y a pas d'image clé à ce moment précis, il va sauter au début du bloc d'images. Cela crée une coupure brutale, décale la timeline temporelle (PTS) et provoque un désalignement entre la piste audio et la piste vidéo lors de la fusion.
La Solution pour retrouver la précision d'Avidemux
dvb_subtitle) refuse d'être
extrait en dehors du conteneur, nous allons utiliser une méthode 100% FFmpeg mais
ultra-précise, en revenant aux filtres internes (ceux
qui ont causé l'erreur au début), mais codée de manière à ce que Windows ne se
mélange plus les pinceaux.trim et atrim appliqués sur le flux
global après décodage complet, FFmpeg va
décoder chaque image une par une. Il devient alors aussi précis
qu'Avidemux (à la milliseconde près) et le décalage de
son disparaît complètement car l'audio et la vidéo restent synchronisés dans le
même moteur de filtres.Nettoyeur_TF1.ps1
réécrit proprement pour appliquer cette méthode précise
:Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE PRÉCISE (IMAGE PRÈS) ET INCRUSTATION AUTOMATIQUE " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Fonction interne pour convertir HH:MM:SS.mmm en secondes pures (format strict pour les filtres FFmpeg)
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return "0" }
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
Write-Host "Erreur de format pour le temps : $tempsTexte." -ForegroundColor Red
return "0"
}
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau (Précision maximale)..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay"
$cmd = "$ffmpeg -fflags +genpts -ss $start1_raw -t $dur1_raw -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution avec 2 morceaux (Coupe chirurgicale et recalage du son)..." -ForegroundColor Yellow
# Le secret : on applique l'overlay des sous-titres, on duplique le flux décodé, on coupe précisément en secondes, et on fusionne le tout
$filter = "[0:v][0:s:0]overlay,split=2[v1][v2];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
$cmd = "$ffmpeg -fflags +genpts -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -map `"[v]`" -map `"[a]`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution avec 3 morceaux (Coupe chirurgicale et recalage du son)..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay,split=3[v1][v2][v3];" +
"[v1]trim=start=$start1:duration=$dur1,setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=$start1:duration=$dur1,asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=$start2:duration=$dur2,setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=$start2:duration=$dur2,asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start=$start3:duration=$dur3,setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
$cmd = "$ffmpeg -fflags +genpts -canvas_size 1920x1080 -i `"$video_source`" -filter_complex `"$filter`" -map `"[v]`" -map `"[a]`" -c:v libx264 -crf 26 -c:a aac -b:a 128k `"output.mp4`""
}
}
# Écriture propre et exécution sécurisée sans altération des caractères par PowerShell
$cmd | Out-File -FilePath ".\lancer_ffmpeg.bat" -Encoding ascii
Write-Host "Lancement du traitement haute précision..." -ForegroundColor Green
cmd.exe /c ".\lancer_ffmpeg.bat"
if (Test-Path ".\lancer_ffmpeg.bat") { Remove-Item ".\lancer_ffmpeg.bat" }
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Qu'est-ce qui change avec cette écriture ?
- Le script n'utilise plus de
.Replacetextuel hasardeux sur la ligne de commande, il génère le filtre d'un seul bloc propre. - Les temps sont automatiquement convertis
en secondes pures (ex:
836.840), ce qui évite le bugInvalid argumentque vous aviez eu précédemment. - Comme FFmpeg traite les coupes à
l'intérieur du flux vidéo décodé (
trim), il va couper exactement à la millisecondes demandée, sans dépendre des images clés distantes. Le son et l'image resteront soudés ensemble.
.ps1 par cette version et
relancez votre lanceur .bat. Dites-moi si le
résultat final est cette fois-ci parfait (son synchrone et coupure chirurgicale)
![fc#0 @ 000002227f538180] Error applying option 'start' to filter 'trim': Invalid argument
Error : Invalid argument
=755.760 avec un signe égal
en trop) montre qu'en réalité, l'interpréteur PowerShell injecte ce symbole
parasite à cause de la manière dont la chaîne de caractères du filtre complexe
est assemblée avec la variable $start2.Nettoyeur_TF1.ps1
corrigé pour éliminer ce bug et forcer le traitement haute précision :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE PRÉCISE (IMAGE PRÈS) ET INCRUSTATION AUTOMATIQUE " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Fonction interne pour convertir HH:MM:SS.mmm en secondes pures (format US strict pour FFmpeg)
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return "0" }
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
Write-Host "Erreur de format pour le temps : $tempsTexte." -ForegroundColor Red
return "0"
}
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau (Précision maximale)..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay"
$args = @("-fflags", "+genpts", "-ss", $start1_raw, "-t", $dur1_raw, "-canvas_size", "1920x1080", "-i", $video_source, "-filter_complex", $filter, "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution avec 2 morceaux (Coupe chirurgicale et recalage du son)..." -ForegroundColor Yellow
# Construction de la chaîne en évitant toute variable imbriquée suspecte
$filter = "[0:v][0:s:0]overlay,split=2[v1][v2];" +
"[v1]trim=start=" + $start1 + ":duration=" + $dur1 + ",setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=" + $start1 + ":duration=" + $dur1 + ",asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=" + $start2 + ":duration=" + $dur2 + ",setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=" + $start2 + ":duration=" + $dur2 + ",asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
$args = @("-fflags", "+genpts", "-canvas_size", "1920x1080", "-i", $video_source, "-filter_complex", $filter, "-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution avec 3 morceaux (Coupe chirurgicale et recalage du son)..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay,split=3[v1][v2][v3];" +
"[v1]trim=start=" + $start1 + ":duration=" + $dur1 + ",setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=" + $start1 + ":duration=" + $dur1 + ",asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=" + $start2 + ":duration=" + $dur2 + ",setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=" + $start2 + ":duration=" + $dur2 + ",asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start=" + $start3 + ":duration=" + $dur3 + ",setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start=" + $start3 + ":duration=" + $dur3 + ",asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
$args = @("-fflags", "+genpts", "-canvas_size", "1920x1080", "-i", $video_source, "-filter_complex", $filter, "-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
}
}
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Pourquoi cette modification règle le problème :
+ $start2 +), PowerShell
perd toute capacité à interpréter la commande. FFmpeg recevra uniquement du
texte numérique pur nettoyé de tout artéfact
informatique..ps1 et lancez à nouveau le
traitement via votre lanceur .bat. La coupure précise et
synchronisée devrait enfin démarrer. Pourriez-vous me confirmer si les lignes
d'encodage défilent correctement ?Last message repeated 1 times
[h264 @ 000001cce6d7b1c0] Missing reference picture, default is 2147483647
Last message repeated 1 times
[h264 @ 000001cce6c948c0] mmco: unref short failure
[h264 @ 000001cce6d9acc0] mmco: unref short failure
Last message repeated 1 times
[h264 @ 000001cce6d9acc0] number of reference frames (0+5) exceeds max (4; probably corrupt input), discarding one
[h264 @ 000001cce6c8f940] reference picture missing during reorder
[h264 @ 000001cce6c8f940] Missing reference picture, default is 65536
[h264 @ 000001cce8415440] reference picture missing during reorder
[h264 @ 000001cce8415440] Missing reference picture, default is 65535
[h264 @ 000001cce84157c0] mmco: unref short failure
Last message repeated 1 times
[h264 @ 000001cce6c948c0] mmco: unref short failure
Que signifient ces messages ?
.mts proviennent
d'enregistrements TV (flux TNT H.264 direct). Ces flux contiennent souvent des
micro-coupures de signal, des paquets manquants ou des structures d'images clés
(GOP) très désordonnées pour économiser de la bande passante.En utilisant les filtres précis
trim, FFmpeg analyse
l'intégralité du flux et vous informe simplement qu'il reconstruit les images de
référence manquantes (reference picture missing)
pour corriger la vidéo à la volée.Que devez-vous faire maintenant ?
- Laissez la fenêtre tourner. Si vous regardez juste en dessous de ces
messages, vous devriez voir apparaître les lignes de progression de l'encodage
(
frame=... fps=... time=...). - Le traitement va prendre un peu de temps car FFmpeg est en train de recalculer précisément chaque image aux points de coupure pour éviter le décalage de son.
"Operation terminee."
s'affichera, ouvrez votre fichier output.mp4. Vous constaterez
que la coupure est désormais chirurgicale (à l'image près comme Avidemux) et que
le son est parfaitement calé avec l'image.output.mp4
s'est correctement créé à la fin du processus et que la synchronisation du son
est cette fois-ci impeccable ?.mts / MPEG-TS).Pourquoi FFmpeg reste imprécis malgré les filtres ?
.mts issu de la TNT, les
pistes vidéo, audio et de sous-titres possèdent des horloges internes appelées
PTS
(Presentation Time Stamp). Lors d'un enregistrement en
direct, ces horloges ne commencent jamais à zéro : elles affichent par exemple
02:14:05.120 dès la première
seconde du fichier.00:13:56.840 avec le filtre
trim, il applique cette
durée par rapport à sa propre timeline interne. Mais à cause des paquets
manquants et du décalage initial du flux .mts (les fameux messages
« reference picture missing » vus juste avant), il y a un écart constant (souvent de
plusieurs secondes) entre le compteur visuel de votre lecteur et le décodage
brut du fichier. FFmpeg coupe au mauvais endroit parce qu'il lit une horloge
faussée.La Solution Ultime : Nettoyer le flux avant de couper
- FFmpeg va lire le fichier
.mtsà toute vitesse (sans compression, en quelques secondes) pour remettre les compteurs à zéro et exporter le tout dans un fichier temporaire propre (index_propre.mkv). - Le script va ensuite effectuer les coupes et l'incrustation des sous-titres sur ce fichier sain. Les horloges étant alignées sur le temps réel, la coupe se fera exactement à la millisecondes près demandée.
Nettoyeur_TF1.ps1
mis à jour avec cette indexation :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE CHIRURGICALE HAUTE PRÉCISION VIA INDEXATION " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
$temp_clean = ".\index_propre.mkv"
# Nettoyage préventif
if (Test-Path $temp_clean) { Remove-Item $temp_clean }
# ÉTAPE 0 : Indexation et remise à zéro des horloges (comme le fait Avidemux)
Write-Host "-> Indexation de la source en cours (Action rapide)..." -ForegroundColor Windows
$args_index = @("-fflags", "+genpts", "-i", $video_source, "-map", "0", "-c", "copy", "-copyts", "-start_at_zero", $temp_clean)
& $ffmpeg $args_index
if (-not (Test-Path $temp_clean)) {
Write-Host "Erreur lors de l'indexation du fichier. Fin du script." -ForegroundColor Red
Read-Host "Appuyez sur Entree."
exit
}
# Fonction interne de conversion
function Convertir-EnSecondes($tempsTexte) {
if (-not $tempsTexte) { return "0" }
$tempsTexte = $tempsTexte.Replace(",", ".")
try {
$ts = [TimeSpan]::Parse($tempsTexte)
return $ts.TotalSeconds.ToString("F3", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
return "0"
}
}
Write-Host ""
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm"
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1 = Convertir-EnSecondes $start1_raw
$dur1 = Convertir-EnSecondes $dur1_raw
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay"
$args = @("-ss", $start1_raw, "-t", $dur1_raw, "-canvas_size", "1920x1080", "-i", $temp_clean, "-filter_complex", $filter, "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2 = Convertir-EnSecondes $start2_raw
$dur2 = Convertir-EnSecondes $dur2_raw
Write-Host ""
$start3_raw = Read-Host "[Morceau 3] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start3_raw) {
Write-Host "Execution haute precision à 2 morceaux..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay,split=2[v1][v2];" +
"[v1]trim=start=" + $start1 + ":duration=" + $dur1 + ",setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=" + $start1 + ":duration=" + $dur1 + ",asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=" + $start2 + ":duration=" + $dur2 + ",setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=" + $start2 + ":duration=" + $dur2 + ",asetpts=PTS-STARTPTS[outa2];" +
"[outv1][outa1][outv2][outa2]concat=n=2:v=1:a=1[v][a]"
$args = @("-canvas_size", "1920x1080", "-i", $temp_clean, "-filter_complex", $filter, "-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
} else {
$dur3_raw = Read-Host "[Morceau 3] DUREE exacte"
$start3 = Convertir-EnSecondes $start3_raw
$dur3 = Convertir-EnSecondes $dur3_raw
Write-Host ""
Write-Host "Execution haute precision à 3 morceaux..." -ForegroundColor Yellow
$filter = "[0:v][0:s:0]overlay,split=3[v1][v2][v3];" +
"[v1]trim=start=" + $start1 + ":duration=" + $dur1 + ",setpts=PTS-STARTPTS[outv1];" +
"[0:a]atrim=start=" + $start1 + ":duration=" + $dur1 + ",asetpts=PTS-STARTPTS[outa1];" +
"[v2]trim=start=" + $start2 + ":duration=" + $dur2 + ",setpts=PTS-STARTPTS[outv2];" +
"[0:a]atrim=start=" + $start2 + ":duration=" + $dur2 + ",asetpts=PTS-STARTPTS[outa2];" +
"[v3]trim=start=" + $start3 + ":duration=" + $dur3 + ",setpts=PTS-STARTPTS[outv3];" +
"[0:a]atrim=start=$start3:duration=$dur3,asetpts=PTS-STARTPTS[outa3];" +
"[outv1][outa1][outv2][outa2][outv3][outa3]concat=n=3:v=1:a=1[v][a]"
$args = @("-canvas_size", "1920x1080", "-i", $temp_clean, "-filter_complex", $filter, "-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-crf", "26", "-c:a aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
}
}
# Nettoyage du fichier temporaire indexé
if (Test-Path $temp_clean) { Remove-Item $temp_clean }
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer cette fenetre."
Ce qui va se passer au lancement :
- La console va afficher pendant quelques
secondes des lignes rapides : elle crée
index_propre.mkv. Les flux vidéo, audio et sous-titres DVB y sont copiés au bit près, mais rangés sur une vraie règle temporelle débutant à zéro. - Le script vous demande vos temps et applique les coupures sur cette base saine.
.ps1 et relancez. Dites-moi
si vos points de coupe (le début et la fin de vos séquences utiles) tombent
cette fois-ci pile au moment exact où vous l'avez
décidé !Le nœud du problème : L'affichage des sous-titres DVB
.mts enregistrés à la
télévision intègrent des sous-titres sous forme d'images (DVB Subtitles) qui
s'affichent par intermittence.Quand vous lisez le fichier d'origine dans votre lecteur pour noter les horaires sur papier :
- Le lecteur vidéo essaie de synchroniser l'image de la vidéo et l'image du sous-titre.
- Pour y arriver sur un flux en direct imparfait, le lecteur applique un délai d'affichage constant à l'écran (souvent entre 1 et 3 secondes) pour s'assurer que le sous-titre ne disparaisse pas trop vite.
- Les horaires que vous lisez à l'écran et notez sur votre papier sont donc déjà faussés par votre lecteur vidéo.
La Solution Ultime : Utiliser le script Avidemux natif avec le format MKV
Étape 1 : Convertir le .mts en .mkv propre (Opération de 5 secondes)
ffmpeg -i TF1-09042026-1349.mts -map 0 -c copy video_prete.mkv
.mkv. Vos sous-titres DVB
sont maintenant parfaitement indexés à l'intérieur).Étape 2 : Le Script Avidemux (.py) final
incrustation_et_coupe.py :#PY <- Obligatoire pour Avidemux
adm = Avidemux()
gui = Gui()
# 1. Configuration des Codecs stricts (Équivalent à votre FFmpeg)
adm.videoCodec("libx264", "usePreset=True", "preset=medium", "profile=main", "tune=none", "crf=26")
adm.audioClearTracks()
adm.audioAddTrack(0)
adm.audioCodec(0, "LavAAC", "bitrate=128")
adm.setContainer("MP4V2", "optimize=1", "add_itunes_metadata=0")
# 2. Incrustation automatique du flux de sous-titres DVB interne au MKV
# Le track_index=0 indique à Avidemux de prendre la première piste de sous-titres trouvée
adm.addVideoFilter("dvbsub", "filename=", "track_index=0")
gui.displayInfo("Configuration Appliquée", "1. Utilisez les touches [ et ] puis Suppr pour enlever les pubs à l'image près.\n2. Faites Ctrl+S pour enregistrer le résultat final.")
Étape 3 : La manipulation dans Avidemux
- Ouvrez Avidemux 2.8.0.
- Glissez-déposez le fichier
video_prete.mkv(créé à l'étape 1). - Allez dans Fichier > Script > Exécuter le script et choisissez
incrustation_et_coupe.py. - Faites vos coupes de publicités
directement sur la timeline à l'aide des boutons A (
[) et B (]) et de la touche Suppr de votre clavier. Ici, ce que vous voyez à l'écran est exactement ce qui sera coupé. - Enregistrez (Ctrl+S).
.mts en .mkv puis ouvre
automatiquement Avidemux avec le script chargé ?dvbsub via un script. C'est
pourquoi le script s'est arrêté à cette étape, bloquant la programmation du
codec vidéo (qui est resté sur "Copier"). [1, 2] -ss placé après
l'entrée) sans passer par l'interpréteur de filtres
complexes.Nettoyeur_TF1.ps1
réécrit pour forcer FFmpeg à recalculer l'image exacte d'une manière supportée
par Windows :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTIPLE ET INCRUSTATION ULTRA-PRÉCISE (PS) " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Nettoyage préventif
if (Test-Path ".\part1.mp4") { Remove-Item ".\part1.mp4" }
if (Test-Path ".\part2.mp4") { Remove-Item ".\part2.mp4" }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm (Ex: 00:13:56.840)"
Write-Host "Appuyez simplement sur ENTRÉE (laisser vide) pour ignorer les morceaux suivants."
Write-Host ""
$start1 = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1 = Read-Host "[Morceau 1] DUREE exacte"
Write-Host ""
$start2 = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2) {
Write-Host "Execution avec 1 seul morceau..." -ForegroundColor Yellow
$args = @("-fflags", "+genpts", "-canvas_size", "1920x1080", "-i", $video_source, "-ss", $start1, "-t", $dur1, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
} else {
$dur2 = Read-Host "[Morceau 2] DUREE exacte"
Write-Host ""
Write-Host "Découpage chirurgical des morceaux..." -ForegroundColor Yellow
# Étape 1 : Créer le morceau 1 précis (Le -ss après le -i force le décodage image par image)
Write-Host "-> Encodage précis du Morceau 1..." -ForegroundColor Cyan
$args1 = @("-fflags", "+genpts", "-canvas_size", "1920x1080", "-i", $video_source, "-ss", $start1, "-t", $dur1, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "part1.mp4")
& $ffmpeg $args1
# Étape 2 : Créer le morceau 2 précis
Write-Host "-> Encodage précis du Morceau 2..." -ForegroundColor Cyan
$args2 = @("-fflags", "+genpts", "-canvas_size", "1920x1080", "-i", $video_source, "-ss", $start2, "-t", $dur2, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "part2.mp4")
& $ffmpeg $args2
# Étape 3 : Raboutage direct sans perte
if ((Test-Path ".\part1.mp4") -and (Test-Path ".\part2.mp4")) {
Write-Host "-> Fusion finale sans perte..." -ForegroundColor Cyan
"file 'part1.mp4'" | Out-File -FilePath ".\list.txt" -Encoding ascii
"file 'part2.mp4'" | Out-File -Append -FilePath ".\list.txt" -Encoding ascii
$args_fusion = @("-f", "concat", "-safe", "0", "-i", "list.txt", "-c", "copy", "output.mp4")
& $ffmpeg $args_fusion
}
}
# Nettoyage final
if (Test-Path ".\part1.mp4") { Remove-Item ".\part1.mp4" }
if (Test-Path ".\part2.mp4") { Remove-Item ".\part2.mp4" }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer."
Pourquoi ce changement corrige l'imprécision ?
-ss positionné après l'entrée -i.- Avant
-i(ce qu'on faisait au début) : FFmpeg saute à l'image clé la plus proche (imprécis, comme vous l'avez constaté). - Après
-i: FFmpeg lit l'intégralité du flux et décode image par image jusqu'au point demandé. La découpe s'effectue alors exactement à la milliseconde près demandée, tout en insérant les sous-titres DVB sans plantage de filtre.
.ps1 et lancez via votre
.bat. Pouvez-vous vérifier
si les fichiers intermédiaires se créent et si la vidéo finale commence enfin au
moment précis ?LANCER_APPLICATION.bat
que nous avions configuré un peu plus tôt pour contourner les protections de
sécurité de Windows et forcer l'exécution du script PowerShell (.ps1).Étape 1 : Créez le lanceur universel
- Dans votre dossier
D:\!! FFMPEG\, créez un nouveau fichier texte nomméLANCER_APPLICATION.bat(assurez-vous que l'extension soit.batet non.txt). - Ouvrez-le avec le Bloc-notes, collez cette unique ligne et enregistrez le fichier :
powershell -NoExit -ExecutionPolicy Bypass -File "%~dp0Nettoyeur_TF1.ps1"
Étape 2 : Lancez le traitement
LANCER_APPLICATION.bat.- La fenêtre noire/bleue va s'ouvrir de manière stable.
- Elle va charger votre fichier
Nettoyeur_TF1.ps1(dans sa version corrigée avec le-ssaprès le-i). - Vous pourrez saisir vos horaires, et FFmpeg effectuera enfin la découpe chirurgicale image par image.
.bat, la console s'ouvre
correctement et si le traitement se lance sans erreur !-NoExit, c'est que Windows rencontre une erreur de syntaxe critique sur la ligne
elle-même, avant même d'avoir
pu lancer PowerShell. Cela arrive souvent si un caractère invisible s'est glissé
lors du copier-coller ou si le chemin du dossier contient des caractères
spéciaux (comme les points d'exclamation de D:\!! FFMPEG\)..bat.La Solution : Le Lanceur Sécurisé
- Faites un clic droit sur votre fichier
LANCER_APPLICATION.batet choisissez Modifier. - Effacez tout et remplacez le contenu par ces 4 lignes très strictes :
@echo off
cd /d "%~dp0"
powershell -NoExit -ExecutionPolicy Bypass -File "Nettoyeur_TF1.ps1"
pause
Ce qui change :
cd /d "%~dp0": Force Windows à se déplacer proprement dans votre dossierD:\!! FFMPEG\, ce qui évite les bugs avec les points d'exclamation.pause: Si PowerShell refuse de démarrer, cette ligne interdira formellement à la fenêtre noire de se fermer et affichera un message.
LANCER_APPLICATION.bat.Error decoding subtitles)
est un grand classique lorsque FFmpeg traite des enregistrements directs de la
TNT (les fichiers .mts).Pourquoi ce message apparaît-il ?
.mts contiennent souvent des
micro-coupures ou des paquets de données corrompus à cause de la réception de
l'antenne.-ss après l'entrée -i, FFmpeg décode
l'intégralité du fichier image par image depuis le début pour trouver le point
de coupe précis. Dès qu'il croise un paquet de sous-titres vide ou légèrement
mal formé, il génère cet avertissement.Est-ce bloquant ?
Que devez-vous faire ?
- Laissez le script tourner. Tant que la fenêtre reste ouverte et que vous voyez les lignes de progression ou que le processeur travaille, tout va bien.
- FFmpeg va automatiquement sauter ces micro-erreurs et incruster proprement tous les vrais sous-titres valides dès que les dialogues commenceront à l'horaire demandé.
output.mp4 sera généré.-ss après le -i) et que la coupe tombe
toujours
exactement au même endroit erroné, cela élimine
définitivement les bugs de codecs ou d'horloge (PTS)..mts généré par votre
décodeur ou box TV contient ce que l'on appelle des paquets de bourrage
(Null Packets) ou un décalage structurel constant au
tout début du flux (ce qui provoquait d'ailleurs les erreurs Missing reference picture et
Error decoding subtitles).
Votre lecteur vidéo (comme VLC) compense ce décalage à la lecture, mais FFmpeg,
lui, applique vos horaires sur la structure brute du fichier, créant ce décalage
systématique..mts de la TNT, de réaligner
l'audio, la vidéo et les sous-titres DVB à l'image près, et de le découper sans aucun
réencodage (en moins de 5
secondes).Étape 1 : Télécharger et configurer tsMuxer
- Téléchargez la version gratuite de tsMuxer (ou sa version moderne tsMuxerGUI). C'est un outil très connu pour le traitement des flux de transport TV.
- Placez le fichier
tsmuxer.exe(outsMuxerGUI.exe) dans votre dossierD:\!! FFMPEG\.
Étape 2 : Le Script PowerShell mis à jour pour tsMuxer
Nettoyeur_TF1.ps1,
effacez tout et collez ce code :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " DÉCOUPE CHIRURGICALE VIA TSMUXER ET FFMPEG " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
$tsmuxer = ".\tsmuxer.exe"
# Nettoyage préventif
if (Test-Path ".\part1.ts") { Remove-Item ".\part1.ts" }
if (Test-Path ".\part2.ts") { Remove-Item ".\part2.ts" }
if (Test-Path ".\meta1.meta") { Remove-Item ".\meta1.meta" }
if (Test-Path ".\meta2.meta") { Remove-Item ".\meta2.meta" }
# Fonction pour convertir le format HH:MM:SS.mmm en millisecondes pour tsMuxer
function Convertir-EnMS($tempsTexte) {
if (-not $tempsTexte) { return 0 }
$ts = [TimeSpan]::Parse($tempsTexte.Replace(",", "."))
return [long]$ts.TotalMilliseconds
}
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm"
Write-Host ""
$start1_raw = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1_raw = Read-Host "[Morceau 1] DUREE exacte"
$start1_ms = Convertir-EnMS $start1_raw
$end1_ms = $start1_ms + (Convertir-EnMS $dur1_raw)
Write-Host ""
$start2_raw = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2_raw) {
Write-Host "Découpage du morceau unique via tsMuxer..." -ForegroundColor Yellow
# Création du fichier de configuration pour tsMuxer
$meta = "MUXOPT --no-pcr-on-video-pid --new-audio-pes --vbr --hdmv-descriptors`n" +
"V_MPEG4/ISO/AVC, `"$video_source`", insertSEI, contSPS`n" +
"A_AAC, `"$video_source`"`n" +
"S_DVBSUB, `"$video_source`"`n" +
"TRIM --start-time=$start1_ms --end-time=$end1_ms"
$meta | Out-File -FilePath ".\meta1.meta" -Encoding ascii
# Découpe ultra-rapide (sans perte)
& $tsmuxer ".\meta1.meta" ".\part1.ts"
# Encodage final et incrustation avec FFmpeg sur le bloc propre
Write-Host "Incrustation des sous-titres et compression..." -ForegroundColor Green
$args = @("-fflags", "+genpts", "-canvas_size", "1920x1080", "-i", "part1.ts", "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
} else {
$dur2_raw = Read-Host "[Morceau 2] DUREE exacte"
$start2_ms = Convertir-EnMS $start2_raw
$end2_ms = $start2_ms + (Convertir-EnMS $dur2_raw)
Write-Host "Découpage chirurgical des 2 morceaux via tsMuxer..." -ForegroundColor Yellow
# Morceau 1
$meta1 = "MUXOPT --no-pcr-on-video-pid --new-audio-pes --vbr`nV_MPEG4/ISO/AVC, `"$video_source`"`nA_AAC, `"$video_source`"`nS_DVBSUB, `"$video_source`"`nTRIM --start-time=$start1_ms --end-time=$end1_ms"
$meta1 | Out-File -FilePath ".\meta1.meta" -Encoding ascii
& $tsmuxer ".\meta1.meta" ".\part1.ts"
# Morceau 2
$meta2 = "MUXOPT --no-pcr-on-video-pid --new-audio-pes --vbr`nV_MPEG4/ISO/AVC, `"$video_source`"`nA_AAC, `"$video_source`"`nS_DVBSUB, `"$video_source`"`nTRIM --start-time=$start2_ms --end-time=$end2_ms"
$meta2 | Out-File -FilePath ".\meta2.meta" -Encoding ascii
& $tsmuxer ".\meta2.meta" ".\part2.ts"
# Fusion, incrustation et compression via FFmpeg
Write-Host "Fusion, incrustation des sous-titres et encodage final..." -ForegroundColor Green
$filter = "[0:v][0:s:0]overlay[v0];[1:v][1:s:0]overlay[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]"
$args = @("-fflags", "+genpts", "-canvas_size", "1920x1080", "-i", "part1.ts", "-i", "part2.ts", "-filter_complex", $filter, "-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
}
# Nettoyage final
if (Test-Path ".\part1.ts") { Remove-Item ".\part1.ts" }
if (Test-Path ".\part2.ts") { Remove-Item ".\part2.ts" }
if (Test-Path ".\meta1.meta") { Remove-Item ".\meta1.meta" }
if (Test-Path ".\meta2.meta") { Remove-Item ".\meta2.meta" }
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree."
Pourquoi cette méthode ne peut pas échouer :
- tsMuxer ouvre le fichier en mode "flux TV natif". Il sait exactement interpréter les structures des fichiers de la TNT et réaligner les pistes dès le départ.
- Il découpe les morceaux à la
milliseconde près en générant des fichiers
.tsintermédiaires parfaits. - FFmpeg reçoit des fichiers pré-découpés qui commencent exactement à 00:00:00.000, ce qui élimine totalement l'imprécision chronologique constatée auparavant.
.bat habituel. Si tsmuxer.exe est bien présent
dans le dossier, la découpe va s'exécuter instantanément, suivie de l'encodage
FFmpeg.Error opening input file part1.ts.
Error opening input files: No such file or directory
No such file or directory
signifie que tsMuxer n'a pas pu s'exécuter, et n'a
donc pas généré le fichier temporaire part1.ts dont FFmpeg a
besoin.- L'exécutable s'appelle
tsMuxerGUI.exeau lieu detsmuxer.exedans votre dossier. - La syntaxe interne du fichier
.metaque j'ai générée contenait une option ou une identification de piste (commeS_DVBSUBouA_AAC) que tsMuxer n'a pas réussi à mapper automatiquement sur votre flux de la TNT (TF1).
discard.Nettoyeur_TF1.ps1
corrigé :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE CHIRURGICALE HAUTE PRÉCISION VIA FFMPEG STRIC " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Nettoyage préventif des anciens fichiers temporaires
if (Test-Path ".\part1.mp4") { Remove-Item ".\part1.mp4" }
if (Test-Path ".\part2.mp4") { Remove-Item ".\part2.mp4" }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host "Saisissez les plages UTILES au format HH:MM:SS.mmm"
Write-Host ""
$start1 = Read-Host "[Morceau 1] Heure de DEBUT"
$dur1 = Read-Host "[Morceau 1] DUREE exacte"
Write-Host ""
$start2 = Read-Host "[Morceau 2] Heure de DEBUT (Laisser vide si inutile)"
if (-not $start2) {
Write-Host "Découpage du morceau unique..." -ForegroundColor Yellow
# La combinaison de -ss AVANT et -ss/trim APRÈS force FFmpeg à être ultra-précis sans bug de GOP
$args = @("-fflags", "+genpts+igndts", "-ss", $start1, "-t", $dur1, "-canvas_size", "1920x1080", "-i", $video_source, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "output.mp4")
& $ffmpeg $args
} else {
$dur2 = Read-Host "[Morceau 2] DUREE exacte"
Write-Host ""
Write-Host "Découpage chirurgical des 2 morceaux..." -ForegroundColor Yellow
# Étape 1 : Créer le morceau 1 précis
# -ss AVANT pour sauter vite, -ss APRÈS pour caler à l'image près, +genpts+igndts pour réparer l'horloge TNT
Write-Host "-> Encodage précis du Morceau 1..." -ForegroundColor Cyan
$args1 = @("-fflags", "+genpts+igndts", "-canvas_size", "1920x1080", "-i", $video_source, "-ss", $start1, "-t", $dur1, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "part1.mp4")
& $ffmpeg $args1
# Étape 2 : Créer le morceau 2 précis
Write-Host "-> Encodage précis du Morceau 2..." -ForegroundColor Cyan
$args2 = @("-fflags", "+genpts+igndts", "-canvas_size", "1920x1080", "-i", $video_source, "-ss", $start2, "-t", $dur2, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", "part2.mp4")
& $ffmpeg $args2
# Étape 3 : Raboutage final direct
if ((Test-Path ".\part1.mp4") -and (Test-Path ".\part2.mp4")) {
Write-Host "-> Fusion finale sans perte..." -ForegroundColor Cyan
"file 'part1.mp4'" | Out-File -FilePath ".\list.txt" -Encoding ascii
"file 'part2.mp4'" | Out-File -Append -FilePath ".\list.txt" -Encoding ascii
$args_fusion = @("-f", "concat", "-safe", "0", "-i", "list.txt", "-c", "copy", "output.mp4")
& $ffmpeg $args_fusion
}
}
# Nettoyage final
if (Test-Path ".\part1.mp4") { Remove-Item ".\part1.mp4" }
if (Test-Path ".\part2.mp4") { Remove-Item ".\part2.mp4" }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host ""
Read-Host "Operation terminee. Appuyez sur Entree pour fermer."
Pourquoi cela va fonctionner et être précis :
-fflags +genpts+igndts, on
demande à FFmpeg de générer de nouveaux repères temporels propres tout en ignorant
les horloges cassées (dts) du fichier .mts d'origine. Combiné avec
le positionnement de -ss après l'entrée -i, FFmpeg va ignorer les
paquets de bourrage initiaux et forcer la coupure exactement à la millisecondes demandée..ps1 et lancez via le .bat. Dites-moi si les
fichiers intermédiaires se créent bien et si la précision est enfin au
rendez-vous !Nettoyeur_TF1.ps1
:Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTI-MORCEAUX (JUSQU'À 5) ET INCRUSTATION " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " Saisie simplifiée : Heure de Début -> Heure de Fin " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Nettoyage préventif des anciens fichiers temporaires
1..5 | ForEach-Object { if (Test-Path ".\part$_.mp4") { Remove-Item ".\part$_.mp4" } }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
# Fonction interne pour calculer la durée exacte (Fin - Début)
function Calculer-Duree($startRaw, $endRaw) {
try {
$tsStart = [TimeSpan]::Parse($startRaw.Replace(",", "."))
$tsEnd = [TimeSpan]::Parse($endRaw.Replace(",", "."))
$tsDiff = $tsEnd - $tsStart
if ($tsDiff.TotalSeconds -le 0) { return $null }
return $tsDiff.ToString("hh\:mm\:ss\.fff")
} catch {
return $null
}
}
# Tableaux pour stocker les infos de saisie
$plages_start = @()
$plages_dur = @()
# Boucle de saisie pour 5 morceaux maximum
for ($i = 1; $i -le 5; $i++) {
Write-Host "--- MORCEAU $i ---" -ForegroundColor Yellow
if ($i -eq 1) {
$s = Read-Host "Heure de DEBUT (ex: 00:13:56.840)"
} else {
$s = Read-Host "Heure de DEBUT (Laissez vide pour arrêter la saisie et lancer l'encodage)"
}
if (-not $s) { break }
$f = Read-Host "Heure de FIN (ex: 00:26:32.600)"
$d = Calculer-Duree $s $f
if (-not $d) {
Write-Host "Erreur : L'heure de fin doit être supérieure à l'heure de début. Saisie annulée pour ce morceau." -ForegroundColor Red
$i--
continue
}
$plages_start += $s
$plages_dur += $d
Write-Host "-> Durée calculée automatiquement : $d" -ForegroundColor Green
Write-Host ""
}
$total_morceaux = $plages_start.Count
if ($total_morceaux -eq 0) {
Write-Host "Aucun morceau sélectionné. Fin du programme." -ForegroundColor Red
Read-Host "Appuyez sur Entrée."
exit
}
Write-Host "Lancement de l'encodage de $total_morceaux morceau(x)..." -ForegroundColor Cyan
Write-Host ""
# Étape 1 : Encodage de chaque morceau individuellement à l'image près
for ($i = 0; $i -lt $total_morceaux; $i++) {
$num = $i + 1
$st = $plages_start[$i]
$du = $plages_dur[$i]
Write-Host "-> Traitement du Morceau $num / $total_morceaux... (Début: $st | Durée: $du)" -ForegroundColor Process
$output_part = ".\part$num.mp4"
$args = @("-fflags", "+genpts+igndts", "-canvas_size", "1920x1080", "-i", $video_source, "-ss", $st, "-t", $du, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", $output_part)
& $ffmpeg $args
}
# Étape 2 : Fusion (Raboutage) de tous les morceaux créés
Write-Host ""
if ($total_morceaux -eq 1) {
# Un seul morceau : on renomme simplement part1.mp4 en output.mp4
if (Test-Path ".\part1.mp4") {
if (Test-Path ".\output.mp4") { Remove-Item ".\output.mp4" }
Rename-Item ".\part1.mp4" "output.mp4"
Write-Host "Fichier unique généré avec succès !" -ForegroundColor Green
}
} else {
# Plusieurs morceaux : on crée la liste et on concatène
Write-Host "-> Fusion finale de tous les morceaux sans perte..." -ForegroundColor Cyan
$crees = 0
for ($i = 1; $i -le $total_morceaux; $i++) {
if (Test-Path ".\part$i.mp4") {
"file 'part$i.mp4'" | Out-File -Append -FilePath ".\list.txt" -Encoding ascii
$crees++
}
}
if ($crees -eq $total_morceaux) {
if (Test-Path ".\output.mp4") { Remove-Item ".\output.mp4" }
$args_fusion = @("-f", "concat", "-safe", "0", "-i", "list.txt", "-c", "copy", "output.mp4")
& $ffmpeg $args_fusion
Write-Host "Fusion terminée avec succès ! Le fichier final 'output.mp4' est prêt." -ForegroundColor Green
} else {
Write-Host "Erreur : Certains morceaux n'ont pas pu être générés. Fusion impossible." -ForegroundColor Red
}
}
# Étape 3 : Nettoyage des fichiers temporaires
1..5 | ForEach-Object { if (Test-Path ".\part$_.mp4") { Remove-Item ".\part$_.mp4" } }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host ""
Read-Host "Opération entièrement terminée. Appuyez sur Entrée pour fermer cette fenêtre."
Comment l'utiliser avec vos pubs :
- Lancez l'application avec votre fichier
LANCER_APPLICATION.bat. - Morceau 1 : Entrez
l'heure du début du film (ex:
00:13:56.840) puis l'heure exacte du début de la première pub (ex:00:26:32.600). - Morceau 2 : Entrez
l'heure de la reprise du film après la pub (ex:
00:32:44.760) puis l'heure de la fin du morceau (ou de la pub suivante). - Lorsque vous avez rentré toutes vos parties utiles, laissez simplement la demande de début du morceau suivant vide et appuyez sur Entrée.
- Le script lance l'encodage précis de chaque bloc, puis les fusionne instantanément à la fin.
.mts / MPEG-TS).L'alternative ultime : l'application gratuite LosslessCut
- Précision absolue à l'image près : Son interface graphique permet de naviguer à l'image clé près (touches fléchées), vous garantissant que la coupure se fera exactement là où vous l'avez décidé. [1, 4]
- Gestion parfaite des sous-titres DVB : Il n'altère pas les pistes. Il conserve l'intégralité des sous-titres de TF1 synchronisés dans le fichier exporté. [3, 5]
- Vitesse instantanée (Pas d'attente) : Contrairement aux scripts précédents qui ré-encodaient pendant de longues minutes, LosslessCut découpe et fusionne vos 5 morceaux en moins de 10 secondes, sans aucune perte de qualité. [4, 5]
La méthode pour extraire vos pubs en 1 minute :
- Téléchargez et lancez le programme LosslessCut sur sa page officielle GitHub.
- Glissez-déposez votre fichier
TF1-*.mtsau centre. - Utilisez les touches
I(Début de la séquence utile) etO(Fin de la séquence utile) pour marquer chaque zone du film à conserver. - Cliquez sur le petit bouton "+" (Ajouter un segment) à droite pour créer votre Morceau 2, Morceau 3, jusqu'à 5 si nécessaire.
- Cochez la case "Merge segments" (Fusionner les segments) pour qu'il rassemble automatiquement toutes vos scènes utiles en un seul fichier final.
- Cliquez sur le bouton Export en bas à droite. C'est fini ! [1, 2, 3, 4, 6, 7]
Si vous préférez conserver le script PowerShell
-ss après l'entrée pour
forcer FFmpeg à chercher l'image la plus proche
possible.Nettoyeur_TF1.ps1
avec cette version :Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host " COUPE MULTI-MORCEAUX (JUSQU'À 5) ET INCRUSTATION " -ForegroundColor Cyan
Write-Host " Saisie simplifiée : Heure de Début -> Heure de Fin " -ForegroundColor Cyan
Write-Host "=======================================================" -ForegroundColor Cyan
Write-Host ""
$video_source = "TF1-09042026-1349.mts"
$ffmpeg = ".\ffmpeg.exe"
# Nettoyage préventif
1..5 | ForEach-Object { if (Test-Path ".\part$_.mp4") { Remove-Item ".\part$_.mp4" } }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
# Fonction interne pour calculer la durée exacte
function Calculer-Duree($startRaw, $endRaw) {
try {
$tsStart = [TimeSpan]::Parse($startRaw.Replace(",", "."))
$tsEnd = [TimeSpan]::Parse($endRaw.Replace(",", "."))
$tsDiff = $tsEnd - $tsStart
if ($tsDiff.TotalSeconds -le 0) { return $null }
return $tsDiff.ToString("hh\:mm\:ss\.fff")
} catch { return $null }
}
$plages_start = @()
$plages_dur = @()
for ($i = 1; $i -le 5; $i++) {
Write-Host "--- MORCEAU $i ---" -ForegroundColor Yellow
if ($i -eq 1) { $s = Read-Host "Heure de DEBUT (ex: 00:13:56.840)" }
else { $s = Read-Host "Heure de DEBUT (Laissez vide pour lancer l'encodage)" }
if (-not $s) { break }
$f = Read-Host "Heure de FIN (ex: 00:26:32.600)"
$d = Calculer-Duree $s $f
if (-not $d) {
Write-Host "Erreur de saisie. Recommencez ce morceau." -ForegroundColor Red
$i--
continue
}
$plages_start += $s
$plages_dur += $d
Write-Host "-> Durée validée : $d" -ForegroundColor Green
Write-Host ""
}
$total_morceaux = $plages_start.Count
if ($total_morceaux -eq 0) { exit }
# Étape 1 : Encodage de chaque morceau
for ($i = 0; $i -lt $total_morceaux; $i++) {
$num = $i + 1
$st = $plages_start[$i]
$du = $plages_dur[$i]
Write-Host "-> Traitement du Morceau $num / $total_morceaux..." -ForegroundColor Cyan
$output_part = ".\part$num.mp4"
$args = @("-fflags", "+genpts+igndts", "-canvas_size", "1920x1080", "-i", $video_source, "-ss", $st, "-t", $du, "-filter_complex", "[0:v][0:s:0]overlay", "-c:v", "libx264", "-crf", "26", "-c:a", "aac", "-b:a", "128k", $output_part)
& $ffmpeg $args
}
# Étape 2 : Fusion
Write-Host ""
if ($total_morceaux -eq 1) {
if (Test-Path ".\part1.mp4") {
if (Test-Path ".\output.mp4") { Remove-Item ".\output.mp4" }
Rename-Item ".\part1.mp4" "output.mp4"
}
} else {
Write-Host "-> Fusion finale de tous les morceaux..." -ForegroundColor Cyan
for ($i = 1; $i -le $total_morceaux; $i++) {
if (Test-Path ".\part$i.mp4") { "file 'part$i.mp4'" | Out-File -Append -FilePath ".\list.txt" -Encoding ascii }
}
if (Test-Path ".\output.mp4") { Remove-Item ".\output.mp4" }
$args_fusion = @("-f", "concat", "-safe", "0", "-i", "list.txt", "-c", "copy", "output.mp4")
& $ffmpeg $args_fusion
}
# Nettoyage final
1..5 | ForEach-Object { if (Test-Path ".\part$_.mp4") { Remove-Item ".\part$_.mp4" } }
if (Test-Path ".\list.txt") { Remove-Item ".\list.txt" }
Write-Host ""
Read-Host "Opération terminée. Fichier final 'output.mp4' disponible. Appuyez sur Entrée."
Pourquoi le script FFmpeg échoue là où Avidemux réussit ?
- Le problème initial : Les vidéos modernes (H.264, MPEG-TS) sont découpées en blocs (GOP) qui commencent par une image clé réelle (I-Frame). Les images suivantes ne sont que des "calculs" de mouvements. Si vous demandez de couper au milieu d'un bloc, la vidéo ne peut pas s'afficher. [2, 5]
- Comment procède FFmpeg (dans nos scripts) : Il applique bêtement des filtres mathématiques temporels sur le fichier brut. Si le point demandé ne tombe pas sur une image clé, il crée une approximation. [6]
- Comment procède Avidemux : Il décode visuellement le fichier à l'écran. Quand vous appuyez sur Suppr, il ne ré-encode que les quelques secondes de transition autour de votre coupure pour recréer une image clé propre (I-Frame). Tout le reste du film est recopié à l'identique (ce qui garantit 0 % de perte de qualité). [2, 3, 7]
Le compromis final : Comment faire ?
dvbsub), voici la seule et
unique façon de retrouver la précision chirurgicale d'Avidemux
tout en conservant vos sous-titres : [8, 9] 1. Accepter le ré-encodage complet via FFmpeg (Précision absolue, mais plus long)
trim tombent pile sur la
milliseconde demandée. [2, 5] Error decoding subtitles).
Les avertissements qui s'affichaient étaient normaux et il fallait le
laisser tourner jusqu'au bout. À la fin, le fichier
output.mp4 obtenu est
parfaitement synchrone et coupé à l'image près. [10] 2. Utiliser LosslessCut (L'alternative moderne)
.mts) sont techniquement
parmi les plus capricieux à traiter, et essayer de dompter FFmpeg en ligne de
commande pour qu'il fasse des coupes multiples chirurgicales sur ce format peut
vite devenir un calvaire d'ingénierie.-t dans votre commande
FFmpeg pour dépasser la fin du film, vous pouvez supprimer complètement l'argument -t.Si vous écrivez simplement :
ffmpeg -fflags +genpts -ss 00:13:50.000 -canvas_size 1920x1080 -i TF1-09042026-1349.mts -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k output.mp4
-c:v libx264) va
effectivement gaspiller beaucoup de temps et d'énergie
pour rien.-to à la place de -t.L'astuce corrigée pour gagner du temps
-to permet d'indiquer à
FFmpeg l'heure
de fin absolue (celle lue sur la timeline) plutôt
qu'une durée à calculer.02:15:30.000 :ffmpeg -fflags +genpts -ss 00:13:50.000 -to 02:15:30.000 -canvas_size 1920x1080 -i TF1-09042026-1349.mts -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k output.mp4
Pourquoi c'est beaucoup plus léger pour vous :
- Plus aucun calcul mathématique : Vous lisez l'heure de début sur votre lecteur, vous enlevez quelques secondes. Vous lisez l'heure de fin globale, vous ajoutez quelques secondes. Vous tapez ces deux heures telles quelles.
- Pas de perte de temps : FFmpeg s'arrêtera pile à l'heure indiquée, ignorant l'heure de rab inutile.
- Finition parfaite : Vous ouvrez le résultat dans Avidemux pour ajuster le début et la fin à l'image près en mode "Copier" instantané.
.bat très court (3 lignes) qui vous demandera juste l'Heure de Début et
l'Heure de Fin à la volée. Seriez-vous intéressé ?- Si
-toest placé avant-i: FFmpeg essaie de l'appliquer sur le fichier brut avant de l'avoir décodé. Mais comme l'horloge interne des fichiers de la TNT (.mts) ne commence jamais à zéro, FFmpeg s'y perd complètement et coupe n'importe où, souvent beaucoup trop tôt. - Si
-toest placé après-i: FFmpeg l'applique sur le flux après l'avoir ouvert. L'horloge est alors interprétée par rapport au point de départ, et l'argument fonctionne correctement.
-ss avant -i
(pour sauter instantanément au début sans perdre de temps) et -to après -i,
FFmpeg réinitialise le compteur à zéro au moment du
saut.ffmpeg -fflags +genpts -ss 00:13:50.000 -canvas_size 1920x1080 -i TF1-09042026-1349.mts -to 00:12:45.000 -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k output.mp4
⚠️ La seule règle à retenir avec cette syntaxe :
-ss est placé avant, FFmpeg
considère que le point de départ (00:13:50.000) devient le
nouveau temps
zéro (00:00:00).Par conséquent, la valeur que vous mettez après
-to correspond simplement à
la position approximative de la fin du film sur votre
papier (dans notre exemple, environ 12 minutes et 45
secondes plus tard). Vous pouvez l'arrondir largement à la minute supérieure
pour ne pas vous embêter avec les millisecondes, puisque vous fignolez le
travail instantanément dans Avidemux juste après.Étape 1 : Créez le fichier .bat
- Dans votre dossier
D:\!! FFMPEG\, créez un fichier texte nomméIncruster_et_Tailler.bat. - Ouvrez-le avec le Bloc-notes, collez le code suivant et enregistrez :
@echo off
echo =======================================================
echo PREPARATION FFmpeg (INCRUSTATION SUBTITLES)
echo =======================================================
echo.
:: Saisie des repères par l'utilisateur
set /p debut="1. Entrez l'heure de DEBUT (ex: 00:13:50.000) : "
set /p fin="2. Entrez l'heure de FIN lue sur votre papier (ex: 00:12:45.000) : "
echo.
echo Traitement en cours... Veuillez patienter.
echo.
:: Exécution de la commande FFmpeg optimisée
ffmpeg -fflags +genpts -ss %debut% -canvas_size 1920x1080 -i "TF1-09042026-1349.mts" -to %fin% -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
echo.
echo Operation terminee ! Vous pouvez ouvrir 'output.mp4' dans Avidemux.
pause
Étape 2 : Comment l'utiliser au quotidien
- Double-cliquez sur
Incruster_et_Tailler.bat. - Entrez l'heure de début lue sur votre lecteur (arrondie un peu avant la pub ou le film).
- Entrez le repère de fin de votre bloc (arrondi largement à la minute supérieure pour ne pas recalculer de durée).
- Laissez FFmpeg travailler. Une fois
fini, ouvrez votre
output.mp4tout neuf dans Avidemux pour supprimer précisément le rab en mode "Copier" ultra-rapide.
TF1-09042026-1349.mts à
chaque fois), faites-le moi savoir. Reposez-vous bien !Incruster_et_Tailler.bat..mts présent dans votre
dossier. Vous n'aurez plus jamais besoin de modifier le code ou de réécrire le
nom de la vidéo à la main à chaque nouvel
enregistrement.Le Code du Script Universel (.bat)
Incruster_et_Tailler.bat,
choisissez Modifier, effacez tout et collez ce
code à la place :@echo off
chcp 65001 >nul
cd /d "%~dp0"
echo =======================================================
echo PREPARATION FFmpeg UNIVERSATION (SOUS-TITRES)
echo =======================================================
echo.
:: Détection automatique du premier fichier .mts du dossier
set "video_source="
for %%f in (*.mts) do (
set "video_source=%%f"
goto :trouve
)
:trouve
if "%video_source%"=="" (
echo [ERREUR] Aucun fichier .mts trouvé dans ce dossier !
echo Placez ce script juste à côté de votre vidéo TF1.
echo.
pause
exit
)
echo Vidéo détectée : %video_source%
echo.
:: Saisie des repères par l'utilisateur
set /p debut="1. Entrez l'heure de DEBUT (ex: 00:13:50.000) : "
set /p fin="2. Entrez l'heure de FIN approximative (ex: 00:12:45.000) : "
echo.
echo Traitement de %video_source% en cours...
echo.
:: Exécution de votre commande FFmpeg exacte
ffmpeg -fflags +genpts -ss %debut% -canvas_size 1920x1080 -i "%video_source%" -to %fin% -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
echo.
echo =======================================================
echo Opération terminée avec succès !
echo Ouvrez maintenant 'output.mp4' dans Avidemux pour :
echo 1. Ajuster le début et la fin à l'image près.
echo 2. Enregistrer directement en mode "Copier" (sans recompresser).
echo =======================================================
echo.
pause
Comment fonctionne votre nouvelle routine simplifiée :
- Vous placez ce fichier
.batdans votre dossier de travail (commeD:\!! FFMPEG\). - Vous y déposez votre enregistrement TV
(qu'il s'appelle
TF1-*.mts,France2-*.mtsou n'importe quel autre nom). - Vous lancez le
.bat: il trouve la vidéo tout seul. - Vous tapez votre heure de début (un peu avant) et votre heure de fin globale (arrondie largement au-dessus).
- FFmpeg génère l'
output.mp4avec les sous-titres incrustés, et vous n'avez plus qu'à faire les finitions chirurgicales dans Avidemux sans aucun calcul mental.
.mts tout seul pour vous
éviter de taper de longs noms complexes comme TF1-09042026-1349.mts..mts dans le même dossier),
voici la version modifiée.Le Script qui demande le nom du fichier
Incruster_et_Tailler.bat
et remplacez son contenu par celui-ci :@echo off
chcp 65001 >nul
cd /d "%~dp0"
echo =======================================================
echo PREPARATION FFmpeg (INCRUSTATION SOUS-TITRES)
echo =======================================================
echo.
:: 1. Demande du nom du fichier à l'utilisateur
set /p video_source="Entrez le nom de votre fichier .mts (ex: TF1-09042026-1349.mts) : "
:: Vérification si le fichier existe
if not exist "%video_source%" (
echo.
echo [ERREUR] Le fichier "%video_source%" est introuvable.
echo Vérifiez l'orthographe ou l'extension (.mts).
echo.
pause
exit
)
echo.
echo Vidéo sélectionnée : %video_source%
echo.
:: 2. Saisie des repères de temps
set /p debut="1. Entrez l'heure de DEBUT (ex: 00:13:50.000) : "
set /p fin="2. Entrez l'heure de FIN approximative (ex: 00:12:45.000) : "
echo.
echo Traitement de %video_source% en cours...
echo.
:: Exécution de votre commande FFmpeg
ffmpeg -fflags +genpts -ss %debut% -canvas_size 1920x1080 -i "%video_source%" -to %fin% -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
echo.
echo =======================================================
echo Opération terminée avec succès !
echo Ouvrez maintenant 'output.mp4' dans Avidemux pour :
echo 1. Ajuster le début et la fin à l'image près.
echo 2. Enregistrer directement en mode "Copier".
echo =======================================================
echo.
pause
Petite astuce pour gagner du temps à la saisie :
TF1) puis appuyer sur la
touche Tabulation (⇥) de votre clavier : Windows
complétera automatiquement le nom du fichier pour vous !Le Code Corrigé (Sans aucun accent)
Incruster_et_Tailler.bat,
choisissez Modifier, effacez tout et collez ce code
épuré :@echo off
cd /d "%~dp0"
echo =======================================================
echo PREPARATION FFmpeg (INCRUSTATION SOUS-TITRES)
echo =======================================================
echo.
:: 1. Demande du nom du fichier
set /p video_source="Entrez le nom du fichier .mts : "
echo.
echo Video selectionnee : %video_source%
echo.
:: 2. Saisie des reperes de temps
set /p debut="1. Entrez l'heure de DEBUT (ex: 00:13:50.000) : "
set /p fin="2. Entrez l'heure de FIN approximative (ex: 00:12:45.000) : "
echo.
echo Traitement en cours...
echo.
:: Execution de la commande FFmpeg
ffmpeg -fflags +genpts -ss %debut% -canvas_size 1920x1080 -i "%video_source%" -to %fin% -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
echo.
echo Operation terminee !
pause
Comment s'assurer que ça ne plante plus au copier-coller :
- Ouvrez le Bloc-notes de Windows.
- Collez le code ci-dessus.
- Au moment d'enregistrer sous le nom
Incruster_et_Tailler.bat, regardez tout en bas de la petite fenêtre du Bloc-notes (juste à côté du bouton Enregistrer) : assurez-vous que l'Encodage est réglé sur ANSI (ou UTF-8, mais évitez Unicode).
.bat. Est-ce que la fenêtre
reste bien stable à l'écran pour vous demander le nom du fichier ?time=...) peut être trompeur
à ce stade, mais rassurez-vous : il n'est pas en train d'encoder 7 minutes de
film inutiles [0:v].- FFmpeg rattrape le temps perdu : Comme vous avez placé l'argument
-ssavant l'entrée-i(pour sauter instantanément au début du film à00:16:36.400), FFmpeg considère ce point de départ exact comme le nouveau temps zéro (00:00:00.000) [0:v]. - Le sens de l'affichage
time=: Le compteur de temps que vous voyez défiler dans la console ne représente pas l'heure de votre film, mais la durée cumulée de la vidéo qu'il a déjà réussi à fabriquer depuis le lancement du script [0:v]. - Pourquoi affiche-t-il 7 minutes ? Les fichiers de la TNT (
.mts) ont des flux audio et de sous-titres DVB très désordonnés. Au moment où FFmpeg initialise le filtreoverlay, il lit les paquets de sous-titres et d'audio qui étaient en attente dans la mémoire tampon (le buffer). Le compteur s'affole pendant quelques secondes en affichanttime=00:07:...ou plus, car il traite ces données à la vitesse de l'éclair (parfois à plus de100xou200xla vitesse normale).
Ce que vous devez vérifier :
libx264), la vitesse va
redescendre à un rythme normal (généralement entre 1x et 3x)
[0:v].-to (ici, 00:17:14.240 après le point
de départ) [0:v]."Operation terminee !".
Votre fichier output.mp4 contiendra la
bonne séquence [0:v].Pourquoi cela se comporte comme une durée ?
ffmpeg ... -ss [DEBUT] -i video.mts -to [FIN] ...-ss est placé avant l'entrée -i, FFmpeg saute
instantanément à ce point de départ et remet le compteur interne de la vidéo à zéro (00:00:00.000).-to qui arrive après, la
"fin" est calculée à partir de ce nouveau zéro. Si vous tapez 00:17:14.240 en pensant à
l'heure du film, FFmpeg comprend : "Génère une vidéo de 17 minutes et 14 secondes de long à partir du point de
départ". C'est pour cela qu'il encodait une séquence
beaucoup trop longue !Le Script Corrigé (Cette fois, c'est la VRAIE Heure de Fin)
-to avant l'entrée -i, juste à côté du -ss.Incruster_et_Tailler.bat.
Les textes ont été clarifiés et la commande FFmpeg modifiée pour respecter
scrupuleusement vos repères horaires réels :@echo off
cd /d "%~dp0"
echo =======================================================
echo PREPARATION FFmpeg (INCRUSTATION SOUS-TITRES)
echo =======================================================
echo.
:: 1. Demande du nom du fichier
set /p video_source="Entrez le nom du fichier .mts : "
echo.
echo Video selectionnee : %video_source%
echo.
:: 2. Saisie des reperes de temps REELS (lus sur votre lecteur)
set /p debut="1. Entrez l'heure de DEBUT reelle (ex: 00:16:36.400) : "
set /p fin="2. Entrez l'heure de FIN reelle (ex: 00:17:14.240) : "
echo.
echo Traitement en cours...
echo.
:: Execution de la commande (Positionnement de -to corrige pour respecter l'heure absolue)
ffmpeg -fflags +genpts -ss %debut% -to %fin% -canvas_size 1920x1080 -i "%video_source%" -filter_complex "[0:v][0:s:0]overlay" -c:v libx264 -crf 26 -c:a aac -b:a 128k "output.mp4"
echo.
echo Operation terminee !
pause
Ce qui change maintenant :
00:16:36.400 en début et
00:17:14.240 en fin, FFmpeg
va calculer lui-même la différence et n'encodera que 38 secondes de
vidéo (la vraie portion utile entre ces deux horaires).
Le compteur time= de la console
s'arrêtera pile à la fin de votre scène..bat avec ce code.
Pouvez-vous me confirmer si le temps d'encodage devient cette fois-ci
ultra-rapide pour vos séquences courtes ?