FFmpeg - Batch file bulk editing - batch-file

I have started a huge video project which I am trying to automate. So far, I made good progress, but now I am stuck. I have searched in Google and here, in Stack OverFlow for answers, but can’t find the solution to my problem.
For completion I will explain my full project.
First step of my project is to convert all of my files to *.mp4 and in the same run burn my logo and website in the video. I do this with this code:
for %%a in ("*.*") do ffmpeg -i "%%a" -i "C:\Users\PC03\Desktop\Video test\Overlay.png" -filter_complex "[0:v][1:v] overlay" -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k "newfiles\%%~na.mp4"
pause
After that, I will place all the video files in their relevant subfolder. This way I have almost a hundred subfolders, with 2 or 3 files in them. Per submap I want a video with an intro (not in the submap) the video’s in the submap, and an outro (not in the submap).
I can do the above with this code:
ffmpeg -f concat -i intro.mp4 -i mylist.txt -outro.png -c copy total.mp4
To automate everything, I have this code to make a mylist.txt file per subfolder:
>output.txt (
echo C:\Users\PC03\Desktop\Video test\vast\intro.mp4
(for %%i in (*.mp4) do #echo file '%%i')
echo C:\Users\PC03\Desktop\Video test\vast\outro.mp4
)
Now the only thing which I have to do is automate the following code:
ffmpeg -f concat -i intro.mp4 -i mylist.txt -outro.png -c copy total.mp4
to go through all the subfolders.
I have made this code:
FOR /R "C:\Users\PC03\Desktop\Video test" %%F IN (.) DO (
> %%F\output.txt (
echo "C:\Users\PC03\Desktop\Video test\vast\intro.mp4"
(for %%i in (*.mp4) do (
#echo file '%%i'
))
echo "C:\Users\PC03\Desktop\Video test\vast\outro.mp4"
)
)
This codes provides me with a mylist.txt file in every subfolder, but the content is not what I want. It takes the content of the parentmap instead of the subfolders. I have a strong feeling that somewhere in this code I have to make another FOR /R but I can’t make it work.
Does someone have a suggestion on how to do this?

The FOR /R will iterate the folders but you try to iterate the *.mp4 files without referring to the currently processed (sub)folder.
#Echo off
Set "Base=C:\Users\PC03\Desktop\Video test"
Set "Ext=*.mp4"
FOR /R "%Base%" %%F IN (.) DO (
PushD "%%F"
if exist "%Ext%" (
> "%%~fF\output.txt" (
echo "%Base%\vast\intro.mp4"
For %%I in (%Ext%) do #echo file '%%~fI'
echo "%Base%\vast\outro.mp4"
)
Echo created "%%~fF\output.txt"
)
PopD
)

Related

Batch attachment of multiple .ttf files to a .mkv

Ok, I'm total new at this... Basically I'm using a tool call mkvmerge to attach multiple font files(.ttf) to .mkv files. I have separated the .mkv files into folders together with the respective fonts I would like to attach.
My aim is to create a batch that creates a copy of all the .mkv files with all the added attachments and deposits them in a newly created a folder (i.e Revised) in the parent directory.
Beginning with just a single folder:
mkdir Revised
for %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "%%~.ttf"
This works if I change the "%%~.ttf" to an actual .tff file name
(i.e
mkdir Revised
for %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "sans serif.ttf"
and I would end up with newly created Revised folder which contains a .mkv file with the sans serif.tff file attach within the .mkv file itself.
However I would like to add multiple .ttf files without naming them individually. (searching online it seems I need something like "$file" though I dont know how to use it)
Next if I have a parent folder with multiple sub-folders:
mkdir Revised
for /R %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "%%~.ttf"
This just flat out doesn't work. Not just because of the "%%~.ttf" issue I'm sure.
I know that it might be a bit too ambitious, so if some one could just help solve the first half of my problem, that would be lovely. Thanks a lot in advance.
Ps: If anyone need to understand the mkvmerge specific commands to help out: https://mkvtoolnix.download/doc/mkvmerge.html
Updates: For the first part
mkdir Revised
for %%x in (*.ttf) do (
for %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "%%x"
)
It seems to work better but I think the script would now add and remove the the .ttf files until the last .ttf file in the folder remained.
Please give this a try. (Remember to set your %mkvmerge% variable to your executable path):
#echo off
set "mkvmerge=C:\Some Path\mkvmerge.exe"
for %%a in (*.ttf) do (
for /f %%i in ('dir /s /b /a-d *.mkv ^| findstr /vi Revised') do (
if not exist "%%~dpiRevised" mkdir "%%~dpi\Revised"
if not exist "%%~dpiRevised\%%~nxi" copy "%%~fi" "%%~dpiRevised"
"%mkvmerge%" -q -o "%%~dpiRevised\%%~ni_rev%%~xi" "%%~dpiRevised\%%~nxi" --attachment-mime-type application/x-truetype-font --attach-file "%%~dpi%%a"
)
)
So to explain what went wrong with your examples:
In the for loop, you take apply from the mkv inside the root folder, and apply a ttf file to it and create the new mkv file with the attached ttf to the Revised directory, then for the next ttf you again copy from the root directory, overwriting the mkv file in the Revised directory with a new one where a new ttf was applied etc.
Instead, we need to first make a copy of the mkv file into the Revised directory then we apply the first ttf file to itself in Revised and then take the mkv with the already attached ttf and apply another ttf to it until all ttf files have been applied to the new mkv inside of Revised The original mkv and all the ttf files will remain in the parent folder.
Note if any of what I explained does not make sense, let me know and I will rephrase.
I have decided to take a stab at this, it is intended to be run from the parent directory holding your directories, (I have assumed that those directories are all on the same level, this is not recursing through nested directories).
Please be aware that I am unable to test this.
#Echo Off
Set "mkvm=%UserProfile%\Downloads\Video Players, Editors, & Downloaders\MKVTool Batch Modifier\mkvmerge.exe"
For /F Delims^=^ EOL^= %%A In ('Dir/B/AD 2^>Nul^|FindStr/IVXC:"Revised"'
) Do If Exist "%%A\*.mkv" (If Exist "%%A\*.ttf" (
If Not Exist "Revised\" MD "Revised" 2>Nul||Exit /B
Call :S1 "%%A"))
GoTo :EOF
:S1
PushD %1 2>Nul||Exit /B
Set "as=--attachment-mime-type application/x-truetype-font --attach-file"
Set "ttfs="
For /F Delims^=^ EOL^= %%A In ('Where .:*.ttf'
) Do Call Set "ttfs=%%ttfs%% %as% "%%~nxA""
For /F Delims^=^ EOL^= %%A In ('Where .:*.mkv'
) Do "%mkvm%" -q -o "%~dp0Revised\%%~nxA" "%%~nxA" %ttfs%
PopD
I think I have also made this in such a way as to allow for more than one .mkv file in a directory, where each will be attached to all of the same .ttf files.
Get-ChildItem *.mkv | ForEach-Object {
$FontFlags = ""
Get-ChildItem -LiteralPath $_.BaseName -Exclude *.xml | ForEach-Object {
$FontFlags += " --add-attachment `"$($_.FullName)`""
}
Write-Host "Running &`"C:\Program Files\MKVToolNix\mkvpropedit.exe`" `"$_`" $FontFlags"
Invoke-Expression "&`"C:\Program Files\MKVToolNix\mkvpropedit.exe`" `"$_`" $FontFlags"
}
Read-Host "Press any key to exit..."
Make a folder with the same names as mkv without extension. Put mkv file, folder , this code in same folder and run it.
I didn't make this code. I asked someone to make this for my personal use.

merge multiple videos and audios with ffmpeg

I have used the program youtube-dl to download a Youtube playlist, i have chosen to download videos and audios separately, i have now a folder full of videos with their corresponding audios that i wish to merge together with ffmpeg.
I need to do this using a batch script but the problem is that youtube-dl added aleatory letters after the original file's title so the videos doesn't have the same name as their corresponding audio, file names looks like this:
First title in the playlist 5J34JG.mp4
First title in the playlist H3826D.webm
Second title in the playlist 3748JD.mp4
Second title in the playlist 6SHJFZ.webm
How to merge these multiple video/audio files using windows batch script and ffmpeg ?
Edit: I forgot to mention that the .webm files are the audio files and that i have multiple files i can't rename them one by one.
#echo off
setlocal
set "outdir=muxed"
if not exist "%outdir%" md "%outdir%" || exit /b 1
:: Get each mp4 file and call the label to mux with webm file.
for %%A in (*.mp4) do call :mux "%%~A"
exit /b
:mux
setlocal
set "videofile=%~1"
set "name=%~n1"
:: Last token of the name is the pattern to remove.
for %%A in (%name:-=- %) do set "pattern=-%%~A"
:: Remove the pattern from the name.
call set "name=%%name:%pattern%=%%"
:: Get the webm filename.
for %%A in ("%name%-*.webm") do set "audiofile=%%~A"
:: Mux if webm file exist and output file does not exist.
if exist "%audiofile%" if not exist "%outdir%\%name%.mp4" (
ffmpeg -i "%videofile%" -i "%audiofile%" -c copy "%outdir%\%name%.mkv"
)
exit /b
The script will 1st make the output directory to save mp4
files so that the output will not become input.
The main for loop will get each mp4 filename. The :mux
label is called with the mp4 filename as an argument.
The variable videofile stores the mp4 filename and
variable name stores just the name without extension.
The last token of name will be the YTID pattern while a
for loop will set the last token to pattern.
The call set will substitute the pattern with "" from the
name. This will give a name that can used with a wildcard to
find the webm filename. A for loop will get the webm
filename.
If the destination does exist and not the output file, then
ffmpeg will mux the 2 files into an output file.
Output file container format is mkv.
Since I was needing to do something similar, I am posting my shorter code to help others out.
This is for in a subfolder
FOR /F "tokens=*" %%f IN ('dir /b /s F2M\*.mp4') DO ffmpeg -i "%%~dpnxf" -i "%%~dpnf.m4a" -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 "F2M\%%~nf-clean.mp4"
This is for if you're doing it in the same directory
for %%f in (*.mkv) do ffmpeg -i "%%~dpnxf" -i "%%~dpnf.m4a" -c:v copy -c:a copy -map 0:0 -map 0:1 -shortest "%%~nf-remux.mp4"
This is if ffmpeg is not in the same folder
set ffmpeg=C:\ffmpeg.exe
for %%a in (*.mkv) do "%ffmpeg%" -i "%%~dpnxf" -i "%%~dpnf.m4a" -c:v copy -c:a copy -map 0:0 -map 1:0 -shortest "%%~nf-remux.mp4"
Just example codes, not specifically formatted for the OP. Use with caution.

Batch script that will get files name and rename those files in Linux

I was trying to create a batch script that will get all the files (using ls command) and append those files in a text file. After that, it will look for each filename available in text file and check if those file names have .abc.ms at the end of the file name. If .abc.ms is available, then it will do nothing; if it is not available, then it will rename them (on Linux server using mv) with "file name".abc.ms .
Below is my code and I am unable to rename those files:
E:\plink -i E:\abc.ppk user#linuxserver ls /xyz/vc/dt/bbb/toy/ >> %filetemp%
FOR /f %%F IN (%filetemp%) DO (
echo %%F >>C:\temp1.txt
::if "*lock.processed"=="%%F"
find /i "lock.processed" C:\GE_RESTRICTED\RITM\NewTask\temp1.txt
if not %errorlevel%==0 (
E:\plink -i E:\abc.ppk user#linuxserver mv %%F %%F.lock.processed
)
)
...where %filetemp% is a text file used to store all the names from linux server.
If you open an SSH shell (which is effectively what you are doing when using plink.exe), you start off in the home directory of the user you are connecting with, probably something like /home/user. Since the files you want to rename reside somewhere else (Looking at your ls command, the location is /xyz/vc/dt/bbb/toy/), I think you just need to prepend that full path to files you want to rename:
E:\plink -i E:\abc.ppk user#linuxserver ls /xyz/vc/dt/bbb/toy/ >> %filetemp%
FOR /f %%F IN (%filetemp%) DO (
echo %%F >>C:\temp1.txt
::if "*lock.processed"=="%%F"
find /i "lock.processed" C:\GE_RESTRICTED\RITM\NewTask\temp1.txt
if not %errorlevel%==0 (
E:\plink -i E:\abc.ppk user#linuxserver mv /xyz/vc/dt/bbb/toy/%%F /xyz/vc/dt/bbb/toy/%%F.lock.processed
)
)
following is the solution for my question:
pushd C:\JobTest\src
for /f "delims=" %%f in ('dir /b /a-d-h-s') do (
echo %%f >>C:\NewTask\temp.txt
)
FOR /f %%a IN (C:\NewTask\temp.txt) DO (
::set FileName=%%~nxa
if not "%%~xa"==".processed" E:\plink -i E:\abc.ppk user#linuxserver mv /xyz/vc/dt/bbb/toy/%%~fa /xyz/vc/dt/bbb/toy/%%~nxa.processed
)
popd

Batch script for ffmpeg to extract images from several video files

On Windows cmd trying this code to convert all .mp4 files in directory to set of images named "filename_imagenumber.jpeg"
pushd %1
if not exist Images\ (
mkdir Images
)
for %%F in (*.mp4) do (
ffmpeg -i %%F -r 1 -f image2 -qscale:v 2 "Images\%%~nF_image-%3d.jpeg"
)
popd
However ffmpeg's argument %3d is not interpreted by Windows cmd.
Any suggestions? Thank you

Windows Batch Lame Encode syntax

I need to get working properly a tiny Windows batch file (convert.cmd) that changes bitrate of all MP3 files in a specified folder. I need to pass 2 parameters to the batch file:
the path to the folder with MP3 files
bitrate I want to change them to.
I am using Lame.exe encoder. The lame.exe is in one place, convert.cmd can be in the same folder with lame.exe, but the folder with MP3 files can be anywhere. The original version (without parameters) was (and it's working fine if I place convert.cmd in the folder wit MP3 files):
#ECHO OFF
FOR %%f IN (*.mp3) DO (
D:\Apps\Lame\lame.exe -h -b 128 "%%f" "%%f.temp"
DEL "%%f"
REN "%%f.temp" "%%f"
)
PAUSE
Instead of 128 I need to pass "%2" and it will be a second command-line parameter, the bitrate, and for MP3 files folder path I need to pass "%1". So, I got this, but it's not working.
#ECHO OFF
FOR %%f IN (%1\*.mp3) DO (
D:\Apps\Lame\lame.exe -h -b %2 "%%f" "%%f.temp"
DEL "%%f"
REN "%%f.temp" "%%f"
)
PAUSE
How to make it work as described?
How can I ensure that my batch file convert existing files, and not creating new converted copies of them somewhere? Thanks a bunch ;) Cheers.
UPDATE
The location of convert.cmd is:
d:\Apps\Lame\convert.cmd, same folder with lame.exe
The location of MP3 files is:
d:\temp\xxx\
File1.mp3
File2.mp3
When I execute convert.cmd from the command line like this:
convert.cmd d:\temp\xxx\ 64
what I get in d:\temp\xxx\ is this:
File1.mp3.temp
File2.mp3.temp
Where did the converted files go?
Thanks.
Thanks, I have already figured out how to write this script.
If someone needs this type of conversion, here we go:
1 param - full path to the folder with mp3 files
2 param - bitrate to convert to
(remember, lame.exe does not preserve mp3 tags)
p.s. who needs mp3 tags anyways ? :)
#ECHO OFF
ECHO.
ECHO BEGIN CONVERSION
ECHO.
CD %1
DIR *.mp3
ECHO -------------------------------------------------------------------------------
ECHO THESE MP3 FILES WILL BE CONVERTED TO BITRATE %2 KBPS
ECHO -------------------------------------------------------------------------------
PAUSE
FOR %%f IN (*.mp3) DO (
ECHO -------------------------------------------------------------------------------
ECHO CONVERTING: %%f
ECHO -------------------------------------------------------------------------------
D:\Apps\Lame\lame.exe -h -b %2 "%%f" "%%~nf.wav"
DEL "%%f"
REN "%%~nf.wav" "%%f"
)
ECHO.
ECHO END CONVERSION
ECHO.
PAUSE

Resources