[Ex] Conversion d'un TS(TNT HD) en MKV avec ffmpeg et mkvmerge
Posté : ven. 05 août 2016 04:12
Bonjour,
Modification du 8 nov 2016
au départ je n'utilisais que ffmpeg, mais il plantait trop souvent sur des changements de scènes (zoom/coupure pub...)
donc j'utilise mkvmerge pour la video et l'audio mais qui ne reconnait pas les sous-titres et ffmpeg pour les sous-titres
je réassemble les 2 avec mkvmerge ou ffmpeg
mon film est là: -ss 00:07:36 -to 01:48:12 / --split parts:00:07:36-01:48:12
je sélectionne aud fre, aud eng, sub fre
ce n'est pas le même système de numérotation
pour sélectionner mes pistes:
ffmpeg -map 1 = toutes les pistes du 2° fichier (crimeS.mkv)
pour avoir des sous-titres en bas de l’écran rajouter un -s 720x516 dans les commandes ffmpeg concernant les sous-titres:
-s 720x516 -map 0:5 -scodec dvdsub
logiciels utilisés:
https://ffmpeg.org/download.html (ffmpeg.exe)
http://www.videohelp.com/software/MKVtoolnix (mkvmerge.exe)
http://www.nikse.dk/ (Subtitle Edit)
https://mpc-hc.org/ (le seul player que je connaisse écrit avec des bibliothèque standard, les autre sont écrit avec QT/linux)
pour faire simple copier ffmpeg.exe et mkvmerge.exe dans le même répertoire que le script
glisser votre fichier TS dans la fenêtre input
ouvrez votre fichier TS avec MPC-HC
allez au début du film, appuyer sur la touche 'd' --> copie du temps récupéré de MPC dans la fenêtre 'debut'
allez a la fin du film, appuyer sur la touche 'f' --> copie du temps récupéré de MPC dans la fenêtre 'fin'
appuyer sur 'b' --> création d'un fichier batch xxx 01.bat
si coupure pub, répéter la manip plusieurs fois
vous pouvez aussi faire 'a la main':
notez vos début/fin dans les fenêtres 'temps' puis file/batch
lancer votre(vos) fichiers batch
on peut transformer le "idx/sub" en "srt" (ocr) avec Subtitle Edit fichier/ouvrir "fichier.mkv" --> "fichier.fre.srt"
Ma petite interface graphique pour automatiser tout ça:
c'est la première que je poste du code sur un forum, soyez indulgent.
un grand merci à mikell pour m'avoir fait connaitre les expressions régulière.
A bientôt
Modification du 8 nov 2016
au départ je n'utilisais que ffmpeg, mais il plantait trop souvent sur des changements de scènes (zoom/coupure pub...)
donc j'utilise mkvmerge pour la video et l'audio mais qui ne reconnait pas les sous-titres et ffmpeg pour les sous-titres
je réassemble les 2 avec mkvmerge ou ffmpeg
mon film est là: -ss 00:07:36 -to 01:48:12 / --split parts:00:07:36-01:48:12
je sélectionne aud fre, aud eng, sub fre
Code : Tout sélectionner
ffmpeg.exe -i crime.ts
Stream #0:0[0x1a4]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
Stream #0:1[0x1ae](fra): Audio: eac3 ([6][0][0][0] / 0x0006), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:2[0x1af](qad): Audio: eac3 ([6][0][0][0] / 0x0006), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:3[0x1b8](fra): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
Stream #0:4[0x1b0](qaa): Audio: eac3 ([6][0][0][0] / 0x0006), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:5[0x1b9](fra): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
Code : Tout sélectionner
mkvmerge -i crime.ts
File 'crime.ts': container: MPEG transport stream
Track ID 4: video (MPEG-4p10/AVC/h.264)
Track ID 5: audio (AC-3/E-AC-3)
Track ID 6: audio (AC-3/E-AC-3)
Track ID 8: audio (AC-3/E-AC-3)
pour sélectionner mes pistes:
- ffmpeg: j'utilise -map 0:3 -scodec dvdsub
mkvmerge: j'utilise -a 5,8
ffmpeg -map 1 = toutes les pistes du 2° fichier (crimeS.mkv)
Code : Tout sélectionner
Subtitle options:
-s size set frame size (WxH or abbreviation)
-sn disable subtitle
-scodec codec force subtitle codec ('copy' to copy stream)
-s 720x516 -map 0:5 -scodec dvdsub
Code : Tout sélectionner
::video+audio
mkvmerge.exe -o "crimeVA.mkv" -a 5,8 "crime.ts" --split parts:00:07:36-01:48:12
::subtitle
ffmpeg.exe -i "crime.ts" -ss 00:07:36 -to 01:48:12 -vn -an -s 720x516 -map 0:3 -scodec dvdsub -map 0:5 -scodec dvdsub -y "crimeS.mkv"
::merge les 2
mkvmerge.exe -o "crimeVAS.mkvmerge.mkv" "crimeVA.mkv" "crimeS.mkv"
::OU
fmpeg.exe -i "crimeVA.mkv" -i "crimeS.mkv" -map 0 -c:v copy -c:a copy -map 1 -c:s copy -y "crimeVAS.fmpeg.mkv"
https://ffmpeg.org/download.html (ffmpeg.exe)
http://www.videohelp.com/software/MKVtoolnix (mkvmerge.exe)
http://www.nikse.dk/ (Subtitle Edit)
https://mpc-hc.org/ (le seul player que je connaisse écrit avec des bibliothèque standard, les autre sont écrit avec QT/linux)
pour faire simple copier ffmpeg.exe et mkvmerge.exe dans le même répertoire que le script
glisser votre fichier TS dans la fenêtre input
ouvrez votre fichier TS avec MPC-HC
allez au début du film, appuyer sur la touche 'd' --> copie du temps récupéré de MPC dans la fenêtre 'debut'
allez a la fin du film, appuyer sur la touche 'f' --> copie du temps récupéré de MPC dans la fenêtre 'fin'
appuyer sur 'b' --> création d'un fichier batch xxx 01.bat
si coupure pub, répéter la manip plusieurs fois
vous pouvez aussi faire 'a la main':
notez vos début/fin dans les fenêtres 'temps' puis file/batch
lancer votre(vos) fichiers batch
on peut transformer le "idx/sub" en "srt" (ocr) avec Subtitle Edit fichier/ouvrir "fichier.mkv" --> "fichier.fre.srt"
Ma petite interface graphique pour automatiser tout ça:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=icon\arte_de.ico
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <DateTimeConstants.au3>
#include <array.au3>
#include <Date.au3>
Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)
Global Const $mkvmerge = @ScriptDir & '\mkvmerge.exe'
Global Const $ffmpeg = @ScriptDir & '\ffmpeg.exe'
Global $g_sTS, $g_sTS_old
Global $hGUI, $idfile, $iddeb, $idfin
Global $idvid, $idaud1, $idaud2, $idaud3, $idaud4, $idsub1, $idsub2, $idsub3, $idsub4
Global $idlvid, $idlaud1, $idlaud2, $idlaud3, $idlaud4, $idlsub1, $idlsub2, $idlsub3, $idlsub4
Global Const $g_sclass = "[CLASS:MediaPlayerClassicW]"
Gui()
HotKeySet("d", "debut")
HotKeySet("f", "fin")
HotKeySet("b", "key_B")
While 1
$g_sTS = GUICtrlRead($idfile)
If $g_sTS <>$g_sTS_old Then Info() ;si on glisse un nouveau fichier on relance la fonction Info()
$g_sTS_old = $g_sTS
Sleep(100)
WEnd
Func Debut()
pass_along("d", "debut")
If @error Then Return
Local $time = get_time()
GUICtrlSetData($iddeb, $time)
EndFunc ;==>Debut d
Func fin()
pass_along("f", "fin")
If @error Then Return
Local $time = get_time()
GUICtrlSetData($idfin, $time)
EndFunc ;==>fin dd
Func key_B()
pass_along("b", "key_B")
If @error Then Return
Batch()
EndFunc ;==>key_B dd
Func pass_along($key, $fonction)
If WinActive($g_sclass) Then Return
HotKeySet($key)
Send($key)
HotKeySet($key, $fonction)
Return SetError(1,0,'')
EndFunc ;==>pass_along
Func get_time() ;recupere le temps dans MPC-HC
Local $time
$time=ControlGetText ($g_sclass,'','[CLASS:Static; INSTANCE:2]')
$time = StringStripWS($time, 7)
Local $T = StringSplit($time, @LF, 2)
Local $pattern = '(.*) /.*' ;06:47 / 18:20 recupere avant le /
$time = StringRegExpReplace($T[0], $pattern, '${1}')
If StringLen($time) = 5 Then $time = '00:' & $time
Return '1999/01/01 ' & $time
EndFunc ;==>get_time
Func Info() ; ffmpeg.exe -y -i "fichier.ts"
Local $s, $cmd, $T, $T1, $i
GUICtrlSetData($idlvid, $s)
GUICtrlSetData($idlaud1, $s)
GUICtrlSetData($idlaud2, $s)
GUICtrlSetData($idlaud3, $s)
GUICtrlSetData($idlaud4, $s)
GUICtrlSetData($idlsub1, $s)
GUICtrlSetData($idlsub2, $s)
GUICtrlSetData($idlsub3, $s)
GUICtrlSetData($idlsub4, $s)
$cmd = $ffmpeg & ' -i ' & Cote($g_sTS) & ' 2>&1'
$T = Lire_Console($cmd)
If UBound($T) < 30 Then ; une sortie normale a plus de 100 lignes donc il y a un probleme
ConsoleWrite($cmd & @LF)
_ArrayDisplay($T)
Return
EndIf
$T1 = _ArrayFindAll($T, 'dvb_subtitle', 0, 0, 0, 1) ;partial
;Stream #0:4[0x8c](fre): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
For $i = 0 To UBound($T1) - 1
$s = $T[$T1[$i]]
$s = StringStripWS($s, 7)
$s = StringLeft($s, 50)
If $i = 0 Then GUICtrlSetData($idlsub1, $s)
If $i = 1 Then GUICtrlSetData($idlsub2, $s)
If $i = 2 Then GUICtrlSetData($idlsub3, $s)
If $i = 3 Then GUICtrlSetData($idlsub4, $s)
Next
$cmd = $mkvmerge & ' -i ' & Cote($g_sTS) & ' 2>&1'
$T = Lire_Console($cmd)
;Track ID 4: video (MPEG-4p10/AVC/h.264)
$T1 = _ArrayFindAll($T, 'video', 0, 0, 0, 1) ;partial
$s = $T[$T1[0]]
$s = StringStripWS($s, 7)
$s = StringLeft($s, 40)
GUICtrlSetData($idlvid, $s)
$T1 = _ArrayFindAll($T, 'audio', 0, 0, 0, 1) ;partial
;Track ID 5: audio (AC-3/E-AC-3)
For $i = 0 To UBound($T1) - 1
$s = $T[$T1[$i]]
$s = StringStripWS($s, 7)
$s = StringLeft($s, 40)
If $i = 0 Then GUICtrlSetData($idlaud1, $s)
If $i = 1 Then GUICtrlSetData($idlaud2, $s)
If $i = 2 Then GUICtrlSetData($idlaud3, $s)
If $i = 3 Then GUICtrlSetData($idlaud4, $s)
Next
EndFunc ;==>Info
Func mkvmergeVA($mkv_vid_aud)
Local $T, $cmd, $i, $pattern, $video, $aud, $aud1, $aud2, $aud3, $aud4
Local $split = ' --split parts:' & GUICtrlRead($iddeb) & '-' & GUICtrlRead($idfin)
;Track ID 5: audio (AC-3/E-AC-3)
$pattern = '.*?(\d):.*' ; garde 1 chiffre avant :
;$i = StringRegExpReplace(GUICtrlRead($idlvid), $pattern, '${1}')
;$video = ' -map 0:' & $i & ' -vcodec copy '
$i = StringRegExpReplace(GUICtrlRead($idlaud1), $pattern, '${1}')
$aud1 = GUICtrlRead($idaud1) = $GUI_CHECKED ? $i &',' : ''
$i = StringRegExpReplace(GUICtrlRead($idlaud2), $pattern, '${1}')
$aud2 = GUICtrlRead($idaud2) = $GUI_CHECKED ? $i &',' : ''
$i = StringRegExpReplace(GUICtrlRead($idlaud3), $pattern, '${1}')
$aud3 = GUICtrlRead($idaud3) = $GUI_CHECKED ? $i &',' : ''
$i = StringRegExpReplace(GUICtrlRead($idlaud4), $pattern, '${1}')
$aud4 = GUICtrlRead($idaud4) = $GUI_CHECKED ? $i &',' : ''
$aud = $aud1 & $aud2 & $aud3 & $aud4
$aud = StringRegExpReplace($aud, '(.*),' ,'${1}') ; supp derniere virgule
;mkvmerge.exe -o "crimeVA.mkv" -a 5,8 "crime.ts" --split parts:00:07:36-01:48:12
$cmd = $mkvmerge & ' -o ' & Cote($mkv_vid_aud) &' -a ' & $aud &' '& Cote($g_sTS) & ' ' & $split
$cmd = StringStripWS($cmd, 7)
cw($cmd)
Return $cmd
EndFunc
Func ffmpegS($mkv_sub)
#cs
Subtitle options:
-s size set frame size (WxH or abbreviation)
-sn disable subtitle
-scodec codec force subtitle codec ('copy' to copy stream)
#ce
Local $i, $pattern, $cmd, $sub, $sub1, $sub2, $sub3, $sub4
Local $cut = ' -ss ' & GUICtrlRead($iddeb) & ' -to ' & GUICtrlRead($idfin)
;Stream #0:7[0x156](deu): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
$pattern = '.*?:(\d).*' ; garde 1 chiffre apres le premier :
$i = StringRegExpReplace(GUICtrlRead($idlsub1), $pattern, '${1}')
$sub1 = GUICtrlRead($idsub1) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$i = StringRegExpReplace(GUICtrlRead($idlsub2), $pattern, '${1}')
$sub2 = GUICtrlRead($idsub2) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$i = StringRegExpReplace(GUICtrlRead($idlsub3), $pattern, '${1}')
$sub3 = GUICtrlRead($idsub3) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$i = StringRegExpReplace(GUICtrlRead($idlsub4), $pattern, '${1}')
$sub4 = GUICtrlRead($idsub4) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$sub = '-s 720x516 '&$sub1 & $sub2 & $sub3 & $sub4
;ffmpeg.exe -i "Hercule Poirot.ts" -t 01:42:27 -vn -an -map 0:4 -scodec dvdsub "Hercule Poirot_sub.mkv"
$cmd = $ffmpeg & ' -y -i ' & Cote($g_sTS) & ' ' & $cut & ' -vn -an ' & $sub & ' ' & Cote($mkv_sub)
$cmd = StringStripWS($cmd, 7)
cw($cmd)
Return $cmd
EndFunc
Func Batch()
Local $name = basename($g_sTS)
Local $batch, $hbatch, $mkv_vid_aud, $mkv_sub, $mkv_merge, $idx_sub
Local $cmd, $i, $si
;Local $hmylist, $mylist=BaseName($g_sTS) & '.list.txt', $concat=BaseName($g_sTS) & '.concat.mkv'
$i = 0
While 1 ; si je supprime les coupures pub je cree 3 fichiers batch fichier01.bat fichier02.bat fichier03.bat
$i += 1
$si = ' ' & StringFormat("%02d", $i)
$batch = $name & $si & '.bat'
If FileExists($batch) Then ContinueLoop
$mkv_vid_aud = $name & $si & '_VA.mkv'
$mkv_sub = $name & $si & '_S.mkv'
$mkv_merge = $name & $si & '_VAS.mkv'
ExitLoop
WEnd
;http://www.clubic.com/forum/programmation/probleme-d-accents-en-batch-id897807-page1.html
;http://www.developpez.net/forums/d1295041/systemes/windows/vos-contributions/faqs-windows/batch-faire-passer-accents-script-batch/
$hbatch = FileOpen($batch, 2 + 512) ; ansi
FileWriteLine($hbatch, '::')
FileWriteLine($hbatch, 'chcp 1252 > nul') ; 65001 1252 28591
$cmd=mkvmergeVA($mkv_vid_aud)
FileWriteLine($hbatch, $cmd)
FileWriteLine($hbatch, @CRLF)
$cmd=ffmpegS($mkv_sub)
FileWriteLine($hbatch, $cmd)
FileWriteLine($hbatch, @CRLF)
;---MERGE
$cmd = $mkvmerge & ' -o ' & cote($mkv_merge) & ' ' & cote($mkv_vid_aud) & ' ' & cote($mkv_sub)
$cmd = StringStripWS($cmd, 7)
FileWriteLine($hbatch, $cmd)
FileWriteLine($hbatch, @CRLF)
$cmd = $ffmpeg & ' -i ' & cote($mkv_vid_aud) & ' -i ' & cote($mkv_sub) & ' -map 0 -c:v copy -c:a copy -map 1 -c:s copy -y ' & cote($mkv_merge)
$cmd = StringStripWS($cmd, 7)
FileWriteLine($hbatch, '::' & $cmd)
FileWriteLine($hbatch, @CRLF)
FileWriteLine($hbatch, 'pause')
FileClose($hbatch)
EndFunc ;==>Batch
Func Gui()
Local $w = 300, $h = 300
Local $ExStyle = BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST)
$hGUI = GUICreate("TS --> MKV", $w, $h, 10, @DesktopHeight - $h - 50, -1, $ExStyle)
GUISetOnEvent($GUI_EVENT_CLOSE, "sortie", $hGUI)
Local $Outilmenu, $filemenu, $audiomenu
$filemenu = GUICtrlCreateMenu("&File")
GUICtrlCreateMenuItem("Info", $filemenu)
GUICtrlSetOnEvent(-1, "Info")
GUICtrlCreateMenuItem("Batch", $filemenu)
GUICtrlSetOnEvent(-1, "Batch")
GUICtrlCreateMenuItem("", $filemenu)
GUICtrlCreateMenuItem("Exit", $filemenu)
GUICtrlSetOnEvent(-1, "sortie")
;------------------------------------------------------------------------
$idfile = GUICtrlCreateInput('', 5, 5, 280, 20)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetTip(-1, 'Glisser votre fichier TS ici')
$iddeb = GUICtrlCreateDate('', -1, t($idfile), 70, 20, $DTS_TIMEFORMAT)
GUICtrlSetTip(-1, 'Debut')
GUICtrlSetData($iddeb, '1999/01/01 00:28:39')
$idfin = GUICtrlCreateDate('', l($iddeb), t($idfile), 70, 20, $DTS_TIMEFORMAT)
GUICtrlSetTip(-1, 'Fin')
GUICtrlSetData($idfin, '1999/01/01 01:06:25')
$idvid = GUICtrlCreateCheckbox('', 5, t($iddeb), 20, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$idlvid = GUICtrlCreateLabel('video', l($idvid), t($iddeb), 250)
$idaud1 = GUICtrlCreateCheckbox('', 5, t($idvid), 20, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$idlaud1 = GUICtrlCreateLabel('audio1', l($idaud1), t($idvid), 250)
$idaud2 = GUICtrlCreateCheckbox('', 5, t($idaud1), 20, 20)
$idlaud2 = GUICtrlCreateLabel('audio2', l($idaud1), t($idaud1), 250)
$idaud3 = GUICtrlCreateCheckbox('', 5, t($idaud2), 20, 20)
$idlaud3 = GUICtrlCreateLabel('audio3', l($idaud1), t($idaud2), 250)
$idaud4 = GUICtrlCreateCheckbox('', 5, t($idaud3), 20, 20)
$idlaud4 = GUICtrlCreateLabel('audio4', l($idaud1), t($idaud3), 250)
$idsub1 = GUICtrlCreateCheckbox('', 5, t($idlaud4), 20, 20)
$idlsub1 = GUICtrlCreateLabel('sub1', l($idsub1), t($idlaud4), 250)
$idsub2 = GUICtrlCreateCheckbox('', 5, t($idsub1), 20, 20)
$idlsub2 = GUICtrlCreateLabel('sub2', l($idsub1), t($idsub1), 250)
$idsub3 = GUICtrlCreateCheckbox('', 5, t($idsub2), 20, 20)
$idlsub3 = GUICtrlCreateLabel('sub3', l($idsub1), t($idsub2), 250)
$idsub4 = GUICtrlCreateCheckbox('', 5, t($idsub3), 20, 20)
$idlsub4 = GUICtrlCreateLabel('sub4', l($idsub1), t($idsub3), 250)
GUISetState(@SW_SHOW, $hGUI)
EndFunc ;==>Gui
Func sortie()
;Local $hmylist, $mylist=BaseName($g_sTS) & '.list.txt', $concat=BaseName($g_sTS) & '.concat.mkv'
;Local $hbatch, $batch
;If FileExists($batch) Then wt($batch)
Exit
EndFunc ;==>sortie
;--------------------------------------------------------
Func l($id) ; mes Control 'flottant'
Local $T = ControlGetPos($hGUI, '', $id)
Return $T[0] + $T[2] + 5
EndFunc ;==>l
Func t($id) ; mes Control 'flottant'
Local $T = ControlGetPos($hGUI, '', $id)
Return $T[1] + $T[3] + 5
EndFunc ;==>t
Func Cote($fichier, $delim = '"')
Return $delim & $fichier & $delim
EndFunc ;==>Cote
Func Lire_Console($cmd) ; je recupere le StdoutRead dans un tableau
Local $out, $err, $hcmd, $T
$cmd = StringStripWS($cmd, 7) ; double space
$hcmd = Run(@ComSpec & " /c " & $cmd, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) ;$STDERR_MERGED + $STDOUT_CHILD)
While 1
$err = StderrRead($hcmd)
If @error Then ExitLoop
TrayTip($cmd, $err, 10, 2)
WEnd
While 1
$out = StdoutRead($hcmd)
If @error Then ExitLoop
If $out <> '' Then
$T = StringSplit($out, @CRLF, 2)
Return $T
Else
Return ''
EndIf
WEnd
EndFunc ;==>Lire_Console
Func cw($text, $line = @ScriptLineNumber)
ConsoleWrite(StringFormat("%04d", $line) & @TAB & '|')
ConsoleWrite($text)
ConsoleWrite('|' & @LF)
EndFunc ;==>cw
Func wt($texte = @ScriptLineNumber, $titre = @ScriptLineNumber)
If MsgBox(1, $titre, '|' & $texte & '|') <> 1 Then Exit
EndFunc ;==>wt
Func AD($T, $line = @ScriptLineNumber)
If IsArray($T) Then _ArrayDisplay($T, $line)
EndFunc ;==>AD
Func BaseName($fichier)
Local $spattern = '(.*)\..*' ; garder jusqu'au point
Local $sname = StringRegExpReplace($fichier, $spattern, '${1}')
If @extended = 1 Then Return $sname
Return SetError(1, 0, '')
EndFunc ;==>BaseName
#AutoIt3Wrapper_Icon=icon\arte_de.ico
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <DateTimeConstants.au3>
#include <array.au3>
#include <Date.au3>
Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)
Global Const $mkvmerge = @ScriptDir & '\mkvmerge.exe'
Global Const $ffmpeg = @ScriptDir & '\ffmpeg.exe'
Global $g_sTS, $g_sTS_old
Global $hGUI, $idfile, $iddeb, $idfin
Global $idvid, $idaud1, $idaud2, $idaud3, $idaud4, $idsub1, $idsub2, $idsub3, $idsub4
Global $idlvid, $idlaud1, $idlaud2, $idlaud3, $idlaud4, $idlsub1, $idlsub2, $idlsub3, $idlsub4
Global Const $g_sclass = "[CLASS:MediaPlayerClassicW]"
Gui()
HotKeySet("d", "debut")
HotKeySet("f", "fin")
HotKeySet("b", "key_B")
While 1
$g_sTS = GUICtrlRead($idfile)
If $g_sTS <>$g_sTS_old Then Info() ;si on glisse un nouveau fichier on relance la fonction Info()
$g_sTS_old = $g_sTS
Sleep(100)
WEnd
Func Debut()
pass_along("d", "debut")
If @error Then Return
Local $time = get_time()
GUICtrlSetData($iddeb, $time)
EndFunc ;==>Debut d
Func fin()
pass_along("f", "fin")
If @error Then Return
Local $time = get_time()
GUICtrlSetData($idfin, $time)
EndFunc ;==>fin dd
Func key_B()
pass_along("b", "key_B")
If @error Then Return
Batch()
EndFunc ;==>key_B dd
Func pass_along($key, $fonction)
If WinActive($g_sclass) Then Return
HotKeySet($key)
Send($key)
HotKeySet($key, $fonction)
Return SetError(1,0,'')
EndFunc ;==>pass_along
Func get_time() ;recupere le temps dans MPC-HC
Local $time
$time=ControlGetText ($g_sclass,'','[CLASS:Static; INSTANCE:2]')
$time = StringStripWS($time, 7)
Local $T = StringSplit($time, @LF, 2)
Local $pattern = '(.*) /.*' ;06:47 / 18:20 recupere avant le /
$time = StringRegExpReplace($T[0], $pattern, '${1}')
If StringLen($time) = 5 Then $time = '00:' & $time
Return '1999/01/01 ' & $time
EndFunc ;==>get_time
Func Info() ; ffmpeg.exe -y -i "fichier.ts"
Local $s, $cmd, $T, $T1, $i
GUICtrlSetData($idlvid, $s)
GUICtrlSetData($idlaud1, $s)
GUICtrlSetData($idlaud2, $s)
GUICtrlSetData($idlaud3, $s)
GUICtrlSetData($idlaud4, $s)
GUICtrlSetData($idlsub1, $s)
GUICtrlSetData($idlsub2, $s)
GUICtrlSetData($idlsub3, $s)
GUICtrlSetData($idlsub4, $s)
$cmd = $ffmpeg & ' -i ' & Cote($g_sTS) & ' 2>&1'
$T = Lire_Console($cmd)
If UBound($T) < 30 Then ; une sortie normale a plus de 100 lignes donc il y a un probleme
ConsoleWrite($cmd & @LF)
_ArrayDisplay($T)
Return
EndIf
$T1 = _ArrayFindAll($T, 'dvb_subtitle', 0, 0, 0, 1) ;partial
;Stream #0:4[0x8c](fre): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
For $i = 0 To UBound($T1) - 1
$s = $T[$T1[$i]]
$s = StringStripWS($s, 7)
$s = StringLeft($s, 50)
If $i = 0 Then GUICtrlSetData($idlsub1, $s)
If $i = 1 Then GUICtrlSetData($idlsub2, $s)
If $i = 2 Then GUICtrlSetData($idlsub3, $s)
If $i = 3 Then GUICtrlSetData($idlsub4, $s)
Next
$cmd = $mkvmerge & ' -i ' & Cote($g_sTS) & ' 2>&1'
$T = Lire_Console($cmd)
;Track ID 4: video (MPEG-4p10/AVC/h.264)
$T1 = _ArrayFindAll($T, 'video', 0, 0, 0, 1) ;partial
$s = $T[$T1[0]]
$s = StringStripWS($s, 7)
$s = StringLeft($s, 40)
GUICtrlSetData($idlvid, $s)
$T1 = _ArrayFindAll($T, 'audio', 0, 0, 0, 1) ;partial
;Track ID 5: audio (AC-3/E-AC-3)
For $i = 0 To UBound($T1) - 1
$s = $T[$T1[$i]]
$s = StringStripWS($s, 7)
$s = StringLeft($s, 40)
If $i = 0 Then GUICtrlSetData($idlaud1, $s)
If $i = 1 Then GUICtrlSetData($idlaud2, $s)
If $i = 2 Then GUICtrlSetData($idlaud3, $s)
If $i = 3 Then GUICtrlSetData($idlaud4, $s)
Next
EndFunc ;==>Info
Func mkvmergeVA($mkv_vid_aud)
Local $T, $cmd, $i, $pattern, $video, $aud, $aud1, $aud2, $aud3, $aud4
Local $split = ' --split parts:' & GUICtrlRead($iddeb) & '-' & GUICtrlRead($idfin)
;Track ID 5: audio (AC-3/E-AC-3)
$pattern = '.*?(\d):.*' ; garde 1 chiffre avant :
;$i = StringRegExpReplace(GUICtrlRead($idlvid), $pattern, '${1}')
;$video = ' -map 0:' & $i & ' -vcodec copy '
$i = StringRegExpReplace(GUICtrlRead($idlaud1), $pattern, '${1}')
$aud1 = GUICtrlRead($idaud1) = $GUI_CHECKED ? $i &',' : ''
$i = StringRegExpReplace(GUICtrlRead($idlaud2), $pattern, '${1}')
$aud2 = GUICtrlRead($idaud2) = $GUI_CHECKED ? $i &',' : ''
$i = StringRegExpReplace(GUICtrlRead($idlaud3), $pattern, '${1}')
$aud3 = GUICtrlRead($idaud3) = $GUI_CHECKED ? $i &',' : ''
$i = StringRegExpReplace(GUICtrlRead($idlaud4), $pattern, '${1}')
$aud4 = GUICtrlRead($idaud4) = $GUI_CHECKED ? $i &',' : ''
$aud = $aud1 & $aud2 & $aud3 & $aud4
$aud = StringRegExpReplace($aud, '(.*),' ,'${1}') ; supp derniere virgule
;mkvmerge.exe -o "crimeVA.mkv" -a 5,8 "crime.ts" --split parts:00:07:36-01:48:12
$cmd = $mkvmerge & ' -o ' & Cote($mkv_vid_aud) &' -a ' & $aud &' '& Cote($g_sTS) & ' ' & $split
$cmd = StringStripWS($cmd, 7)
cw($cmd)
Return $cmd
EndFunc
Func ffmpegS($mkv_sub)
#cs
Subtitle options:
-s size set frame size (WxH or abbreviation)
-sn disable subtitle
-scodec codec force subtitle codec ('copy' to copy stream)
#ce
Local $i, $pattern, $cmd, $sub, $sub1, $sub2, $sub3, $sub4
Local $cut = ' -ss ' & GUICtrlRead($iddeb) & ' -to ' & GUICtrlRead($idfin)
;Stream #0:7[0x156](deu): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
$pattern = '.*?:(\d).*' ; garde 1 chiffre apres le premier :
$i = StringRegExpReplace(GUICtrlRead($idlsub1), $pattern, '${1}')
$sub1 = GUICtrlRead($idsub1) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$i = StringRegExpReplace(GUICtrlRead($idlsub2), $pattern, '${1}')
$sub2 = GUICtrlRead($idsub2) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$i = StringRegExpReplace(GUICtrlRead($idlsub3), $pattern, '${1}')
$sub3 = GUICtrlRead($idsub3) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$i = StringRegExpReplace(GUICtrlRead($idlsub4), $pattern, '${1}')
$sub4 = GUICtrlRead($idsub4) = $GUI_CHECKED ? ' -map 0:' & $i & ' -scodec dvdsub ' : ''
$sub = '-s 720x516 '&$sub1 & $sub2 & $sub3 & $sub4
;ffmpeg.exe -i "Hercule Poirot.ts" -t 01:42:27 -vn -an -map 0:4 -scodec dvdsub "Hercule Poirot_sub.mkv"
$cmd = $ffmpeg & ' -y -i ' & Cote($g_sTS) & ' ' & $cut & ' -vn -an ' & $sub & ' ' & Cote($mkv_sub)
$cmd = StringStripWS($cmd, 7)
cw($cmd)
Return $cmd
EndFunc
Func Batch()
Local $name = basename($g_sTS)
Local $batch, $hbatch, $mkv_vid_aud, $mkv_sub, $mkv_merge, $idx_sub
Local $cmd, $i, $si
;Local $hmylist, $mylist=BaseName($g_sTS) & '.list.txt', $concat=BaseName($g_sTS) & '.concat.mkv'
$i = 0
While 1 ; si je supprime les coupures pub je cree 3 fichiers batch fichier01.bat fichier02.bat fichier03.bat
$i += 1
$si = ' ' & StringFormat("%02d", $i)
$batch = $name & $si & '.bat'
If FileExists($batch) Then ContinueLoop
$mkv_vid_aud = $name & $si & '_VA.mkv'
$mkv_sub = $name & $si & '_S.mkv'
$mkv_merge = $name & $si & '_VAS.mkv'
ExitLoop
WEnd
;http://www.clubic.com/forum/programmation/probleme-d-accents-en-batch-id897807-page1.html
;http://www.developpez.net/forums/d1295041/systemes/windows/vos-contributions/faqs-windows/batch-faire-passer-accents-script-batch/
$hbatch = FileOpen($batch, 2 + 512) ; ansi
FileWriteLine($hbatch, '::')
FileWriteLine($hbatch, 'chcp 1252 > nul') ; 65001 1252 28591
$cmd=mkvmergeVA($mkv_vid_aud)
FileWriteLine($hbatch, $cmd)
FileWriteLine($hbatch, @CRLF)
$cmd=ffmpegS($mkv_sub)
FileWriteLine($hbatch, $cmd)
FileWriteLine($hbatch, @CRLF)
;---MERGE
$cmd = $mkvmerge & ' -o ' & cote($mkv_merge) & ' ' & cote($mkv_vid_aud) & ' ' & cote($mkv_sub)
$cmd = StringStripWS($cmd, 7)
FileWriteLine($hbatch, $cmd)
FileWriteLine($hbatch, @CRLF)
$cmd = $ffmpeg & ' -i ' & cote($mkv_vid_aud) & ' -i ' & cote($mkv_sub) & ' -map 0 -c:v copy -c:a copy -map 1 -c:s copy -y ' & cote($mkv_merge)
$cmd = StringStripWS($cmd, 7)
FileWriteLine($hbatch, '::' & $cmd)
FileWriteLine($hbatch, @CRLF)
FileWriteLine($hbatch, 'pause')
FileClose($hbatch)
EndFunc ;==>Batch
Func Gui()
Local $w = 300, $h = 300
Local $ExStyle = BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST)
$hGUI = GUICreate("TS --> MKV", $w, $h, 10, @DesktopHeight - $h - 50, -1, $ExStyle)
GUISetOnEvent($GUI_EVENT_CLOSE, "sortie", $hGUI)
Local $Outilmenu, $filemenu, $audiomenu
$filemenu = GUICtrlCreateMenu("&File")
GUICtrlCreateMenuItem("Info", $filemenu)
GUICtrlSetOnEvent(-1, "Info")
GUICtrlCreateMenuItem("Batch", $filemenu)
GUICtrlSetOnEvent(-1, "Batch")
GUICtrlCreateMenuItem("", $filemenu)
GUICtrlCreateMenuItem("Exit", $filemenu)
GUICtrlSetOnEvent(-1, "sortie")
;------------------------------------------------------------------------
$idfile = GUICtrlCreateInput('', 5, 5, 280, 20)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetTip(-1, 'Glisser votre fichier TS ici')
$iddeb = GUICtrlCreateDate('', -1, t($idfile), 70, 20, $DTS_TIMEFORMAT)
GUICtrlSetTip(-1, 'Debut')
GUICtrlSetData($iddeb, '1999/01/01 00:28:39')
$idfin = GUICtrlCreateDate('', l($iddeb), t($idfile), 70, 20, $DTS_TIMEFORMAT)
GUICtrlSetTip(-1, 'Fin')
GUICtrlSetData($idfin, '1999/01/01 01:06:25')
$idvid = GUICtrlCreateCheckbox('', 5, t($iddeb), 20, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$idlvid = GUICtrlCreateLabel('video', l($idvid), t($iddeb), 250)
$idaud1 = GUICtrlCreateCheckbox('', 5, t($idvid), 20, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$idlaud1 = GUICtrlCreateLabel('audio1', l($idaud1), t($idvid), 250)
$idaud2 = GUICtrlCreateCheckbox('', 5, t($idaud1), 20, 20)
$idlaud2 = GUICtrlCreateLabel('audio2', l($idaud1), t($idaud1), 250)
$idaud3 = GUICtrlCreateCheckbox('', 5, t($idaud2), 20, 20)
$idlaud3 = GUICtrlCreateLabel('audio3', l($idaud1), t($idaud2), 250)
$idaud4 = GUICtrlCreateCheckbox('', 5, t($idaud3), 20, 20)
$idlaud4 = GUICtrlCreateLabel('audio4', l($idaud1), t($idaud3), 250)
$idsub1 = GUICtrlCreateCheckbox('', 5, t($idlaud4), 20, 20)
$idlsub1 = GUICtrlCreateLabel('sub1', l($idsub1), t($idlaud4), 250)
$idsub2 = GUICtrlCreateCheckbox('', 5, t($idsub1), 20, 20)
$idlsub2 = GUICtrlCreateLabel('sub2', l($idsub1), t($idsub1), 250)
$idsub3 = GUICtrlCreateCheckbox('', 5, t($idsub2), 20, 20)
$idlsub3 = GUICtrlCreateLabel('sub3', l($idsub1), t($idsub2), 250)
$idsub4 = GUICtrlCreateCheckbox('', 5, t($idsub3), 20, 20)
$idlsub4 = GUICtrlCreateLabel('sub4', l($idsub1), t($idsub3), 250)
GUISetState(@SW_SHOW, $hGUI)
EndFunc ;==>Gui
Func sortie()
;Local $hmylist, $mylist=BaseName($g_sTS) & '.list.txt', $concat=BaseName($g_sTS) & '.concat.mkv'
;Local $hbatch, $batch
;If FileExists($batch) Then wt($batch)
Exit
EndFunc ;==>sortie
;--------------------------------------------------------
Func l($id) ; mes Control 'flottant'
Local $T = ControlGetPos($hGUI, '', $id)
Return $T[0] + $T[2] + 5
EndFunc ;==>l
Func t($id) ; mes Control 'flottant'
Local $T = ControlGetPos($hGUI, '', $id)
Return $T[1] + $T[3] + 5
EndFunc ;==>t
Func Cote($fichier, $delim = '"')
Return $delim & $fichier & $delim
EndFunc ;==>Cote
Func Lire_Console($cmd) ; je recupere le StdoutRead dans un tableau
Local $out, $err, $hcmd, $T
$cmd = StringStripWS($cmd, 7) ; double space
$hcmd = Run(@ComSpec & " /c " & $cmd, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) ;$STDERR_MERGED + $STDOUT_CHILD)
While 1
$err = StderrRead($hcmd)
If @error Then ExitLoop
TrayTip($cmd, $err, 10, 2)
WEnd
While 1
$out = StdoutRead($hcmd)
If @error Then ExitLoop
If $out <> '' Then
$T = StringSplit($out, @CRLF, 2)
Return $T
Else
Return ''
EndIf
WEnd
EndFunc ;==>Lire_Console
Func cw($text, $line = @ScriptLineNumber)
ConsoleWrite(StringFormat("%04d", $line) & @TAB & '|')
ConsoleWrite($text)
ConsoleWrite('|' & @LF)
EndFunc ;==>cw
Func wt($texte = @ScriptLineNumber, $titre = @ScriptLineNumber)
If MsgBox(1, $titre, '|' & $texte & '|') <> 1 Then Exit
EndFunc ;==>wt
Func AD($T, $line = @ScriptLineNumber)
If IsArray($T) Then _ArrayDisplay($T, $line)
EndFunc ;==>AD
Func BaseName($fichier)
Local $spattern = '(.*)\..*' ; garder jusqu'au point
Local $sname = StringRegExpReplace($fichier, $spattern, '${1}')
If @extended = 1 Then Return $sname
Return SetError(1, 0, '')
EndFunc ;==>BaseName
c'est la première que je poste du code sur un forum, soyez indulgent.
un grand merci à mikell pour m'avoir fait connaitre les expressions régulière.
A bientôt