-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmkv_to_mp4.bat
291 lines (237 loc) · 10.5 KB
/
mkv_to_mp4.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
@echo off
setlocal enabledelayedexpansion
echo.
echo This program is a .mkv to .mp4 converter with subtitles burner onto the video itself.
echo It uses ffmpeg to process the files, so you first need to install it on your computer.
echo The final video .mp4 will include the subtitles in the original pictures themselves.
echo.
echo.
REM Check if ffmpeg is installed (to do later)
echo So first, you need to ensure that all the files you want to convert have the same streams (audio, video, subtitles)
echo If you want to convert a file, write the relative or absolute path with the file name and extension. (ex : C:\Users\John\Videos\myvideo.mkv)
echo If you want to convert a set of files, just write the relative or absolute path (ex : C:\Users\John\Videos)
powershell -Command "Write-Host 'Your file names can NOT contain characters such as^: ^! ^^^ & .. ; () ' -ForegroundColor Yellow"
set current_directory=%cd%
:input_path
cd %current_directory%
echo.
set /p input_path=Enter the file or folder path :
set "folder_path="
set is_1_file=0
echo.
REM Check if the last character is a backslash and remove it
if "%input_path:~-1%"=="\" (
set input_path=%input_path:~0,-1%
)
REM Check if the input path is correct, and if it is a file or a folder
if exist "%input_path%" (
if exist "%input_path%\*" (
REM This is a folder
set is_1_file=0
set folder_path=%input_path%
) else (
REM This is a file
set is_1_file=1
REM get the path of the file and remove the backslash
for %%A in ("%input_path%") do set folder_path=%%~dpA
set folder_path=!folder_path:~0,-1!
)
) else (
echo Can't find this folder or file, please try something else.
goto input_path
)
REM Change the current directory to the folder path, to use easily relative paths
cd %folder_path%
REM Create the subfolder to store the subtitles and a txt file to store the file names
set "temp=temp"
if not exist "%temp%" mkdir "%temp%"
REM Now, we'll check the mkv files, if there is and if they have the same streams
REM Check if there are .mkv files in the folder or if the file is a .mkv file
REM Here the future list of names of the mkv files to convert in a txt file, so we create the txt file
set "file_names=%temp%\file_names.txt"
type nul > %file_names%
set files_count=0
if %is_1_file%==1 (
if "%input_path:~-4%" NEQ ".mkv" (
echo This is not a .mkv file, please try something else.
goto input_path
)
REM We add only the filename and extension to the list of file names
for %%A in ("%input_path%") do echo %%~nxA >> %file_names%
set files_count=1
) else (
REM Loop through all the .mkv files in the folder
for %%A in (*.mkv) do (
REM We add only the filename and extension to the list of file names
echo %%~nxA >> %file_names%
set /a files_count+=1
)
if !files_count!==0 (
echo There is no .mkv file in this folder, please try something else.
goto input_path
)
)
REM check for the special characters : ( ) { } [] ^ & , .. ! ;
set "error_count=0"
for /f "tokens=1 delims=" %%i in (%file_names%) do (
set "str=%%i"
call set "stri=%%str:&=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^&' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:,=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^,' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:..=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^..' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:(=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^(' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:)=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^)' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:{=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^{' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:}=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^}' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:[=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^[' is not allowed in "%%i" & set /a error_count+=1
call set "stri=%%str:]=CHANGE%%"
if not "!stri!"=="%%i" echo the character '^]' is not allowed in "%%i" & set /a error_count+=1
REM characters such as ^, !, ; are not even catchable without provoking an error
)
if %error_count% gtr 0 (
echo.
echo Naming errors had been found. Please rename your files and retry.
echo.
pause
goto input_path
)
echo.
echo %files_count% files selected :
for /f "tokens=1 delims=" %%A in (%file_names%) do echo - %%A
echo.
REM Now we are in the folder path, and have the list of file names and the number of files to convert
REM Choose the right audio and subtitle streams
set audio_count=0
set sub_count=0
REM Put into first_file, the first file of the list
set "first_file="
for /f "tokens=1 delims=" %%A in (%file_names%) do set first_file=%%A
REM Get the number of audio and subtitle streams in the first file
for /f %%A in ('ffmpeg -i "%first_file%" 2^>^&1 ^| findstr /r "Stream.*Audio" ^| find /c /v ""') do set audio_count=%%A
for /f %%A in ('ffmpeg -i "%first_file%" 2^>^&1 ^| findstr /r "Stream.*Subtitle" ^| find /c /v ""') do set sub_count=%%A
if !audio_count! EQU 0 (
echo There is no audio stream in %first_file%, please try with another set of files.
goto input_path
)
if !sub_count! EQU 0 (
echo There is no subtitle stream in %first_file%, please try with another set of files.
goto input_path
)
REM if we have several files to compare the compatibility of streams, we loop through the files
if is_1_file==0 (
for /f "tokens=1 delims=" %%F in (%file_names%) do (
for /f %%A in ('ffmpeg -i "%%F" 2^>^&1 ^| findstr /r "Stream.*Audio" ^| find /c /v ""') do set temp_audio_count=%%A
for /f %%A in ('ffmpeg -i "%%F" 2^>^&1 ^| findstr /r "Stream.*Subtitle" ^| find /c /v ""') do set temp_sub_count=%%A
if !temp_audio_count! NEQ !audio_count! (
echo The audio streams are not the same in your .mkv files, please try with another set of files.
echo There are !temp_audio_count! audio streams in %%F, whereas %fisrt_file% have !audio_count! audio streams
goto input_path
) else (
if !temp_sub_count! NEQ !sub_count! (
echo There are !temp_sub_count! subtitle streams in %%F, whereas %fisrt_file% have !sub_count! subtitle streams
goto input_path
)
)
)
echo There are !audio_count! audio and !sub_count! subtitle streams in your mkv file
) else (
echo There are !audio_count! audio and !sub_count! subtitle streams in your mkv files.
)
REM display the audio and subtitle streams with their ID and Title
echo Each audio or subtitle stream have an ID (1, 2, 3...) and a language :
for /f "delims=" %%A in ('ffmpeg -i "%first_file%" 2^>^&1 ^| findstr /r "Stream.*Audio | Stream.*Subtitle"') do (
for /f "tokens=2,3,4 delims=:()" %%B in ("%%A") do (
set "lang=%%C"
if "%%C"=="fre" (set "lang=French")
if "%%C"=="eng" (set "lang=English")
if "%%C"=="ger" (set "lang=German")
if "%%C"=="ita" (set "lang=Italian")
if "%%C"=="spa" (set "lang=Spanish")
if "%%C"=="dut" (set "lang=Dutch")
if "%%C"=="por" (set "lang=Portuguese")
if "%%C"=="rus" (set "lang=Russian")
if "%%C"=="jpn" (set "lang=Japanese")
if "%%C"=="chi" (set "lang=Chinese")
if "%%C"=="kor" (set "lang=Korean")
echo Stream %%B: %%D - !lang!
)
)
echo.
set /p audio_id=Choose the stream ID for audio (1, 2, 3...) :
set /p sub_id=Choose the stream ID for subtitles (1, 2, 3...) :
REM Now we will convert the files
REM First step is to extract the subtitles into a .srt file for each file of the list
REM The srt files will be in a subfolder and named as the original file with a .srt instead of .mkv
set counter=0
REM Loop through the list of files to extract the subtitles
for /f "tokens=1 delims=" %%A in (%file_names%) do (
set /a counter+=1
set "current_mkv_file=%%~nxA"
set "current_sub_file=%temp%\%%~nA.srt"
powershell -Command "Write-Host 'Extraction of subtitles from !current_mkv_file! to !current_sub_file! :' -ForegroundColor Blue"
ffmpeg -i "!current_mkv_file!" -map 0:%sub_id% "!current_sub_file!"
if exist !current_sub_file! (
powershell -Command "Write-Host '############ %%~nA.srt successfully created (!counter! / %files_count%) ############' -ForegroundColor Green"
) else (
powershell -Command "Write-Host 'Failed to create !current_sub_file!' -ForegroundColor Red"
pause
exit
)
)
echo.
echo.
powershell -Command "Write-Host '---------------- ALL SUBTITLES SUCCESSFULLY EXTRACTED ----------------' -ForegroundColor Green"
echo.
echo.
REM Now we will convert the files to .mp4 with the subtitles burned into the video
REM Create the subfolder
set "mp4_folder=mp4 converted"
if exist "%mp4_folder%" (
powershell -Command "Write-Host 'The folder "%mp4_folder%" already exists, the files will be overwritten.' -ForegroundColor Yellow"
set /p "overwrite=Do you want to continue ? (y/n) : "
if /i "%overwrite%" NEQ "y" (
rmdir /s /q "%mp4_folder%"
mkdir "%mp4_folder%"
) else (
powershell -Command "Write-Host 'Processus aborted by the user.' -ForegroundColor Red"
pause
goto input_path
)
) else (
mkdir "%mp4_folder%"
)
set counter=0
REM Loop through the list of files to convert them
for /f "tokens=1 delims=" %%A in (%file_names%) do (
set /a counter+=1
set "current_mkv_file=%%~nxA"
set "current_mp4_file=%mp4_folder%\%%~nA.mp4"
powershell -Command "Write-Host 'Creation of !current_mp4_file! :' -ForegroundColor Blue"
ffmpeg -i "!current_mkv_file!" -map 0:v -map 0:%audio_id% -vf subtitles="!temp!/%%~nA.srt" "!current_mp4_file!"
if exist !current_mp4_file! (
echo.
powershell -Command "Write-Host '############ %%~nxA successfully converted (!counter!/%files_count%) ############' -ForegroundColor Green"
echo.
) else (
powershell -Command "Write-Host 'Failed to create !current_mp4_file! ' -ForegroundColor Red"
pause
exit
)
)
REM delete the subtitles and filenames folder
rmdir /s /q "%temp%"
echo.
echo.
powershell -Command "Write-Host '---------------------- ALL FILES SUCCESSFULLY CONVERTED ------------------------' -ForegroundColor Green"
echo.
echo.
REM Open the folder with the converted files
explorer "%mp4_folder%"
pause