Batch Script to Download Video with youtube-dl and Convert with FFmpeg - batch-file

I'm trying to
Using a single batch script to
Download an mp4 video using youtube-dl
Save the video's original title to a batch variable
Convert the video to webm with FFmpeg
I want to keep the original title, so it needs to read the title with youtube-dl, save it to a variable, and use that variable for FFmpeg input/output filename.
CMD Batch
1. Download Video
youtube-dl -f best "https://www.youtube.com/watch?v=TWNhqCHw0qc" -o "C:\Users\Matt\Downloads\%%(title)s.mp4" --merge-output-format mp4
2. Download Video using Loop
This is used to save the title to a variable %%a.
for /f "delims=" %%a in ('youtube-dl -f best "https://www.youtube.com/watch?v=TWNhqCHw0qc" -o #"C:\Users\Matt\Downloads\%%(title)s.mp4" --merge-output-format mp4') do (echo example)
3. Final Script
Download Video, Save Title, Convert with FFmpeg
Sorted
for /f "delims=" %%a in ('
youtube-dl
-f best "https://www.youtube.com/watch?v=TWNhqCHw0qc"
-o #"C:\Users\Matt\Downloads\%%(title)s.mp4"
--merge-output-format mp4
')
do (ffmpeg -y
-i "C:\Users\Matt\Downloads\%%a.mp4"
-c:v libvpx -b:v 1300K -crf 16 -pix_fmt yuv420p
-map 0:v:0? -sn
-c:a libvorbis -q:a 6 -ac 2 -map 0:a:0?
-f webm
"C:\Users\Matt\Downloads\%%a.webm"
)
Inline
for /f "delims=" %%a in ('youtube-dl -f best "https://www.youtube.com/watch?v=TWNhqCHw0qc" -o #"C:\Users\Matt\Downloads\%%(title)s.mp4" --merge-output-format mp4') do (ffmpeg -y -i "C:\Users\Matt\Downloads\%%a.mp4" -c:v libvpx -b:v 1300K -crf 16 -pix_fmt yuv420p -map 0:v:0? -sn -c:a libvorbis -q:a 6 -ac 2 -map 0:a:0? -f webm "C:\Users\Matt\Downloads\%%a.webm")
Error
Before the script can ever reach FFmpeg, youtube-dl fails to download the file. It says the file has already been downloaded, even when there is no file in the directory.
[download] #C#\Users\Matt\Downloads\Color Balloons.mp4 has already
been downloaded

I was able to create a script that works.
One of the problems was that youtube-dl wasn't working properly if located in C:\Program Files\, but works when located somewhere that doesn't require Administrator Privileges.
The --get-filename part requires an # symbol before the youtube-dl path.
youtube-dl gets filename from video and saves to var %%f
youtube-dl downloads the video to C:\Path\To\Downloads\
Merge output as mp4, so you can specify the extension for FFmpeg input
FFmpeg converts video to webm and uses %%f as input/output filename.
for /f "delims=" %%f in ('
#"C:\Users\Matt\Desktop\youtube-dl.exe"
--get-filename -o "%%(title)s"
"https://www.youtube.com/watch?v=TWNhqCHw0qc"
')
do ("C:\Users\Matt\Desktop\youtube-dl.exe"
-f best "https://www.youtube.com/watch?v=TWNhqCHw0qc"
-o "C:\Users\Matt\Downloads\%%f.mp4"
--merge-output-format mp4
&&
ffmpeg -y
-i "C:\Users\Matt\Downloads\%%f.mp4"
-c:v libvpx
-b:v 1300K -crf 16
-pix_fmt yuv420p
-map 0:v:0?
-sn
-c:a libvorbis
-q:a 6
-map 0:a:0?
-f webm
"C:\Users\Matt\Downloads\%%f.webm"
)

Related

Batch file to perform multiple conversions in a row

I'm trying to write a batch file that can be launched from Handbrake GUI with the "send file to" feature, that will split an MKV into chapters with MKVmerge, then convert all those new files into mp4s with ffmpeg. Handbrake passes only one argument into the batch file, the full file path of the output (surrounded by quotes). I'm very new to batch scripting and am having difficulty getting it all to work together -- all the individual parts work just fine when absolute paths are given. Here's the content of the .bat file:
START /WAIT "C:\Program Files\MKVToolNix\mkvmerge.exe -o output.mkv --split chapters:all %1"
for %%i in (*.mkv) do C:\ffmpeg\bin\ffmpeg.exe -i "%%i" -loop 1 -i "%%~dpi"\folder.jpg -map 1:v -map 0:a -c:a ac3 -b:a 640K -pix_fmt yuv420p -c:v libx264 -shortest -fflags +shortest -max_interleave_delta 100M "%%~ni.mp4"
Any glaring mistakes I'm making? I've been at this for hours reading SO threads and documentation, and can't figure it out for the life of me. Any help is appreciated, thanks in advance.

Workaround to .ts files in video merging?

I've got these sentences of code that I use for video processing, the first one adds a watermark, the second creates a .ts file of the watermarked video and then adds an intro and outro to it but I found that it quickly fills disk space because of the .ts files being used, is there a way to achieve the same results without them? Either by deleting them right after using them or by using a different process altogether.
for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do ffmpeg.exe
-y -i "%%I" -i white.png -filter_complex "[0:v]scale=iw:ih[v0];[1:v][v0]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1[v]"
-map "[v]" -map 0:a -codec:v libx264 -preset ultrafast -crf 23 -codec:a copy "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"
for %%I in ("C:\Users\Administrator\Desktop\Complete-videos\*.mp4") do ffmpeg -y
-i %%I -c copy -vbsf h264_mp4toannexb -f mpegts -s 1280*720 %%I.ts && ffmpeg -y -i "concat:out1.ts|%%I.ts|out1.ts" -c:v libx264 -strict experimental -bsf:a aac_adtstoasc -ar 48000 -r 20 "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4
pause
This does it in one command, with no intermediate files.
for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do ffmpeg.exe
-y -i "%%I" -i white.png -i out1.ts -filter_complex "[1:v][0:v]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1,scale=hd720,setsar=1[vl];[2:v][2:a][vl][0:a][2:v][2:a]concat=n=3:v=1:a=1[v][a]"
-map "[v]" -map "[a]" -r 20 -c:v libx264 -ar 48000 "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"
pause
Notes: Depending on where out1.ts is, you may have to specify its full path during input. In the first command, in your 2nd step, the size option has no effect as you're copying streams. If resize is needed, insert scale=hd720 after the concat filter in my command. Add -strict experimental if your ffmpeg is older than Dec 2015 and you don't want to upgrade.
[totally untried suggestion since I have no idea what the ffmpeg line is doing]
I suggest you try this on a small file subset on a device with a restricted space like a ramdrive or a usb drive. USB drive may take a while. Coffee is good.
for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do (
ffmpeg.exe -y -i "%%I" -i white.png -filter_complex "[0:v]scale=iw:ih[v0];[1:v][v0]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1[v]"
-map "[v]" -map 0:a -codec:v libx264 -preset ultrafast -crf 23 -codec:a copy "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"
for %%Q in ("C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4") do ffmpeg -y
-i %%Q -c copy -vbsf h264_mp4toannexb -f mpegts -s 1280*720 %%Q.ts && ffmpeg -y -i "concat:out1.ts|%%I.ts|out1.ts" -c:v libx264 -strict experimental -bsf:a aac_adtstoasc -ar 48000 -r 20 "C:\Users\Administrator\Desktop\Complete-videos\%%~nQ.mp4
del *.ts
)
pause
This way, the first loop using %%I selects the file to be processed and apparently puts the processed file in another directory then immediately performs the second process on that file, controlled by %%Q using the name in %%~nI to select the single file created by the previous process.
Consequently, instead of processing 10 files each with its own .ts set, one is processed at a time and only one .ts set is created. I don't know whether the second process deletes the .ts files, but I've added a del to get rid of them on each cycle. I've also no idea whether the first process creates the .ts files, but I've made that assumption.
As the educationalists said about "new maths" - it's the idea that's important.

How to stop ffmpeg and continue batch running

I have this small batch script. The purpose is to save small portion of our rtmp live stream
#echo off
echo Live Stream Cropper v0.1
echo **************************
echo video codec : libxh264
echo audio codec : mp3
echo **************************
echo Recording...
echo.
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
set output=%datetime:~0,8%-%datetime:~8,4%
ffmpeg -i rtmp://my.streaming.path/public/appname -acodec mp3 -vcodec libx264 "X:\PATH\%output%.avi" -nostats -loglevel 0
echo.
echo "Recorded video is saved on X:\PATH\%output%.avi"
pause
The ffmpeg process is working as expected. My problem is after pressing CTRL + C to stop the process of ffmpeg, the echo command to show where the recorded file is saved is not executed.
How can I stop the ffmpeg process and then continue running the remaining of the script?
Thanks
Some programs ignore the /wait option but you can try this. Essentially you will have to spawn ffmpeg into another environment and the main environment will wait for ffmpeg to finish before it continues.
START "FFMPEG" /WAIT ffmpeg -i rtmp://my.streaming.path/public/appname -acodec mp3 -vcodec libx264 "X:\PATH\%output%.avi" -nostats -loglevel 0
Give this a try as well.
cmd /c ffmpeg -i rtmp://my.streaming.path/public/appname -acodec mp3 -vcodec libx264 "X:\PATH\%output%.avi" -nostats -loglevel 0

ffmpeg batch retains old filetype in name

I'm using the following ffmpeg script to convert all .mp4 files in the folder to .webm.
for %%A IN (*.mp4) DO ffmpeg -i "%%A" -c:v libvpx -crf 4 -b:v 3M -c:a libvorbis "%%A.webm"
I am trying to make it go from "xxx.mp4" to "xxx.webm"
However when I run the script the file name goes from "xxx.mp4" to "xxx.mp4.webm"
Any suggestions are highly appreciated.
Use %%~nA.webm to select the name-part of the filename.
see for /? from the prompt or documentation.
To recursively convert in webm all the mp4 video files in nested folders, you can try this command:
find '~/Video/' -iname '*.mp4' -exec bash -c 'D=$(dirname "{}"); B=$(basename "{}"); mkdir "$D/webm/"; ffmpeg -i "{}" -c:v libvpx -crf 4 -b:v 3M -c:a libvorbis "$D/webm/${B%.*}.webm"' \;
It will create a folder named "webm" inside the one with mp4 video files and, inside the "webm" folder, it will save relative webm files, without keeping the old file extension in the name.

Batch convert all files in a directory with spaces in filename

I've done this batch file that should convert all mp3 files in given folder but, I dont know why, it doesn't work...
Here is the code:
#echo off
title Converting...
set fold=C:\Users\Username\Music\Music to convert\
set ext=*.mp3
set dest=C:\Users\Username\Music\Converted Music\
for %%f in (%fold%%ext%) do ffmpeg -i %%f -b 192k %dest%%%f
pause>nul
exit
I think it's because of the spaces in the files names and in the folder name but i don't actually know... can someone verify and find out the right code?
Thanks...
Easy.
for %%f in ("%fold%%ext%") do ffmpeg -i "%%f" -b 192k "%dest%%%~nxf"
(modified version)
Here's my test batch
#echo OFF
SETLOCAL
REM title Converting...
set fold=U:\Users\Username\Music\Music to convert\
set ext=*.mp3
set dest=U:\Users\Username\Music\Converted Music\
:: This makes the directories, then creates two dummy files
:: only used for testing.
MD "%fold%"
MD "%dest%"
dir>"%fold%file1.mp3"
dir>"%fold%file two.mp3"
for %%f in ("%fold%%ext%") do ECHO ffmpeg -i "%%f" -b 192k "%dest%%%~nxf"
The ECHO in the last line is to show what would be executed. After verification, remove the ECHO keyword to activate the FFMPEG command.
%%~nxf is the name+extension of the file %%f
results:
ffmpeg -i "U:\Users\Username\Music\Music to convert\file1.mp3" -b 192k "U:\Users\Username\Music\Converted Music\file1.mp3"
ffmpeg -i "U:\Users\Username\Music\Music to convert\file two.mp3" -b 192k "U:\Users\Username\Music\Converted Music\file two.mp3"
Hmmm...perhaps you need to replace USERNAME when you're setting FOLD and DEST with %username%
revised to add processing for multiple filetypes
#echo OFF
SETLOCAL
REM title Converting...
set fold=U:\Users\Username\Music\Music to convert\
set ext=*.mp3 *.wma *.m4a
set dest=U:\Users\Username\Music\Converted Music\
:: This makes the directories, then creates dummy files
MD "%fold%"
MD "%fold%subdir"
MD "%dest%"
dir>"%fold%file1.mp3"
dir>"%fold%file two.mp3"
dir>"%fold%file3.wma"
dir>"%fold%subdir\file four.wma"
for /r "%fold%" %%f in (%ext%) do ECHO ffmpeg -i "%%~ff" -b 192k "%dest%%%~nxf"
Noting that I haven't changed the FFMPEG command - you are aware of the parameters you require. Command echoed as usual.
If you want to use a constant output extension, say .MP3, change "%dest%%%~nxf" to "%dest%%%~nf.MP3"
Revised batch output:
ffmpeg -i "U:\Users\Username\Music\Music to convert\file1.mp3" -b 192k "U:\Users\Username\Music\Converted Music\file1.mp3"
ffmpeg -i "U:\Users\Username\Music\Music to convert\file two.mp3" -b 192k "U:\Users\Username\Music\Converted Music\file two.mp3"
ffmpeg -i "U:\Users\Username\Music\Music to convert\file3.wma" -b 192k "U:\Users\Username\Music\Converted Music\file3.wma"
ffmpeg -i "U:\Users\Username\Music\Music to convert\subdir\file four.wma" -b 192k "U:\Users\Username\Music\Converted Music\file four.wma"

Resources