I have an CMD Batch Script that will convert a folder of mp4 videos to webm.
You will need:
- FFmpeg/FFprobe installed and set in Environment Variables to run from CMD.
- A folder with an mp4 for FFprobe to parse.
To make it easy, this is only the first part of the script, showing the Video Bitrate
variable.
Here is a full script, just replace the paths.
https://pastebin.com/raw/3ng77Exz
How the Script works:
- Loops through all videos in folder
- Has FFprobe parse the Video's Bitrate and save it to
%V
and
%vBitrate%
.
- Has FFmpeg use
%V
. Such as -b:v %V
will become the parsed value
-b:v 9401k
.
- Converts each video from mp4 to webm using the parsed Bitrate
Problem
I can't get FFprobe's Output to save to the variable. I've come up with a workaround, having it first save the bitrate value to a temp file
, then import that to the %vBitrate%
variable.
Example: (%V > tmp_vBitrate) & SET /p vBitrate= < tmp_vBitrate
.
Works
Temp File Variable
cd "C:\Users\Matt\Videos\" && for %f in (*.mp4) do ffprobe -i "C:\Users\Matt\Desktop\Test\%~f" -select_streams v:0 -show_entries stream=bit_rate -v quiet -of csv="p=0" & for /f "tokens=*" %V in ("ffprobe -i "%~f" -select_streams v:0 -show_entries stream=bit_rate -v quiet -of csv=p=0") do (echo ) & (%V > tmp_vBitrate) & SET /p vBitrate= < tmp_vBitrate & del tmp_vBitrate & for /F %V in ('echo %vBitrate%') do (echo %V)
Does Not Work
Memory Variable
cd "C:\Users\Matt\Videos\" && for %f in (*.mp4) do ffprobe -i "C:\Users\Matt\Desktop\Test\%~f" -select_streams v:0 -show_entries stream=bit_rate -v quiet -of csv="p=0" & for /f "tokens=*" %V in ("ffprobe -i "%~f" -select_streams v:0 -show_entries stream=bit_rate -v quiet -of csv=p=0") do (echo ) & SET vBitrate=%V & for /F %V in ('echo %vBitrate%') do (echo %V)
Testing It
Run the first command. When it is finished, type echo %vBitrate%
in CMD and press Enter. You'll see the bitrate of the last mp4 file parsed.
Do the same for the second command and you'll see it doesn't work.
Solution
I would like to get rid of the Temp File Variable
and get the second command to work.
(%V > tmp_vBitrate) & SET /p vBitrate= < tmp_vBitrate
to just SET vBitrate=%V
.
Maybe this whole thing can be simplified? Am I using the variables wrong?
I believe I solved this using different FFmpeg commands with 2^>^&1
.
Now it no longer uses a temporary file to set the variable.
Video Bitrate
for /F "delims=" %V in ('@ffprobe -v error -select_streams v:0 -show_entries stream^=bit_rate -of default^=noprint_wrappers^=1:nokey^=1 "%~f" 2^>^&1') do (SET vBitrate=%V) & for /F %V in ('echo %vBitrate%') do (echo %V)
Audio Bitrate
for /F "delims=" %A in ('@ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default^=noprint_wrappers^=1:nokey^=1 "%~f" 2^>^&1') do (SET aBitrate=%A) & for /F %A in ('echo %aBitrate%') do (echo %A)
Full Script
Here is a full batch script
that will convert mp4
to webm
and calculate and match the bitrates automatically using video birate = (((size * 8) / 1000) / duration) * 1000
.
cd "C:\Users\Matt\Videos\" && for %f in (*.mp4) do (for /F "delims=" %S in ('@ffprobe -v error -select_streams v:0 -show_entries format^=size -of default^=noprint_wrappers^=1:nokey^=1 "%~f" 2^>^&1') do (SET size=%S) & for /F %S in ('echo %size%') do (echo %S) & for /F "delims=" %D in ('@ffprobe -v error -select_streams v:0 -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 "%~f" 2^>^&1') do (SET duration=%D) & for /F "tokens=1 delims=." %R in ('echo %duration%') do (SET duration=%R) & for /F %D in ('echo %duration%') do (echo %D) & for /F "delims=" %V in ('@ffprobe -v error -select_streams v:0 -show_entries stream^=bit_rate -of default^=noprint_wrappers^=1:nokey^=1 "%~f" 2^>^&1') do (SET vBitrate=%V) & for /F %V in ('echo %vBitrate%') do (echo %V) & (if %V EQU N/A (SET /a vBitrate=%S*8/1000/%D*1000) ELSE (echo Video Bitrate Detected)) & for /F %V in ('echo %vBitrate%') do (echo %V) & for /F "delims=" %A in ('@ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default^=noprint_wrappers^=1:nokey^=1 "%~f" 2^>^&1') do (echo) & SET aBitrate=%A & for /F %A in ('echo %aBitrate%') do (echo %A) & (IF %A EQU N/A (SET aBitrate=320000)) & for /F %A in ('echo %aBitrate%') do (echo %A) & (IF %A gtr 500000 (SET aBitrate=500000) ELSE (echo Bitrate within Vorbis Limit of 500k)) & for /F %A in ('echo %aBitrate%') do (echo %A) && ffmpeg -y -i "C:\Users\Matt\Videos\%~f" -vcodec libvpx -quality good -cpu-used 0 -b:v %V -pass 1 -acodec libvorbis -b:a %A -map 0:v:0? -map 0:a:0? -sn -map_metadata 0 -threads 8 "C:\Users\Matt\Videos\%~nf.webm" && ffmpeg -y -i "C:\Users\Matt\Videos\%~f" -vcodec libvpx -quality good -cpu-used 0 -b:v %V -pass 2 -acodec libvorbis -b:a %A -map 0:v:0? -map 0:a:0? -sn -map_metadata 0 -threads 8 "C:\Users\Matt\Videos\%~nf.webm")