so I'm writing a script to scan mkv files and downconvert any 1080p files to 720p. I'm currently running through each file using a "for /r" loop to include subfolders. Is there a way I can recreate the subfolders into the output destination?
Here's what I have so far (p.s. It's my first script):
#echo off
set mediainfo="%~dp0MediaInfo.exe"
set result="%~dp0width.txt"
set handbrake="%~dp0HandBrakeCLI.exe"
SETLOCAL ENABLEDELAYEDEXPANSION
Set /P source=Enter source path:
Set /P output=Enter destination for converted files:
if %output:~-1%==\ set output=%output:~0,-1%
if not exist %output% mkdir %output%
for /R %source% %%j in (*.mkv) do (
Echo Filepath is: %%j
%mediainfo% --Inform=Video;%%Width%% "%%j" > %result%
set /P width=<%result%
del %result%
echo Width is: !width!
if !width! == 1920 (%handbrake% -i "%%j" -o "%output%\%%~xnj" -f mkv -e x264 -q 20 --vfr -a 1,1 -E av_aac,ac3 -B 192 -w 1280 --keep-display-aspect -x level=4.1:vbv-bufsize=78125:vbv-maxrate=62500) else (echo No need to transcode.)
)
Now if I have a structure like:
TV Show\Season 1
\Season 2
\Season 3
I would like the source dir to be "TV Show" and the output to keep the files in the same folder structure. Would this be doable?
EDIT: I updated the code a bit, added an if stated to compare %%~nxq (Season X) minus the last 2 characters to the word "Season" to determine if the working folder was inside a season subfolder. Only problem is if it's "Season 10" then the if comparison will read "Season ". Haven't tested it out and I'm not sure if there is a way to use wildcards in an if statement. Here's the updated code:
#echo off
set mediainfo="%~dp0MediaInfo.exe"
set result="%~dp0width.txt"
set handbrake="%~dp0HandBrakeCLI.exe"
SETLOCAL ENABLEDELAYEDEXPANSION
Set /P source=Enter source path:
echo Source path is: %source%
Set /P a=Enter destination for converted files:
set output=%a:"=%
if not %output:~-1%==\ (set output="%output%\") else (set output="%output%")
echo Destinition path is: %output%
if not exist %output% mkdir %output%
set dest=%output%
for /R %source% %%j in (*.mkv) do (
Echo Filepath is: %%j
for %%q in ("%%~dpj.") do (
set sea=%%~nxq
if "!sea:~0,-2!"=="Season" (
set dest="%output:"=%%%~nxq\%%~xnj"
set seafold="%output:"=%%%~nxq"
if not exist !seafold! mkdir !seafold!
) else (
set dest="%output:"=%%%~xnj"
)
echo Output Path is: !dest!
)
%mediainfo% --Inform=Video;%%Width%% "%%j" > %result%
set /P width=<%result%
del %result%
echo Width is: !width!
if !width! == 1920 (%handbrake% -i "%%j" -o !dest! -f mkv -e x264 -q 20 --vfr -a 1,1 -E av_aac,ac3 -B 192 -w 1280 --keep-display-aspect -x level=4.1:vbv-bufsize=78125:vbv-maxrate=62500) else (echo No need to transcode.)
)
Certainly.
for %%q in ("%%~dpj.") do echo %%~nxq
should provide you with a clue, given that you've worked out your first batch so far...
(~dpj gives you the drive/path of %%j; then use a quirk to extract the name and extension of the last element of the directoryname)
Related
I need to combine a specific set of files with a randomized selection from another set of files; for more specific context, voice clips followed by a randomized walky-talky beep. At the moment, I've managed to assemble this so far from searching around:
setlocal EnableDelayedExpansion
cd beeps
set n=0
for %%f in (*.*) do (
set /A n+=1
set "file[!n!]=%%f"
)
set /A "rand=(n*%random%)/32768+1"
cd ..
for %%A IN (*.ogg) DO ffmpeg -y -i radio_beep.wav -i "%%A" -i "beeps\!file[%rand%]!" -filter_complex "[0:a:0][1:a:0][2:a:0]concat=n=3:v=0:a=1[outa]" -map "[outa]" "helper\%%A"
At the moment, this will only run the randomization once and use that selection for every file. How can I have it do the randomization for each .ogg in the folder, and get that into FFmpeg as an input?
You need to perform the randomisation for each iteration of the .ogg loop.
Here's an example which does that by Calling a labelled section on each iteration:
#Echo Off
SetLocal EnableDelayedExpansion
Set "i=0"
For %%A In (beeps\*) Do (Set /A i+=1
Set "file[!i!]=%%A")
For %%A In (*.ogg) Do Call :Process "%%A"
GoTo :EOF
:Process
Set /A "rand=(%RANDOM%%%i)+1"
ffmpeg -y -i "radio_beep.wav" -i %1 -i "!file[%rand%]!" -filter_complex "[0:a:0][1:a:0][2:a:0]concat=n=3:v=0:a=1[outa]" -map "[outa]" "helper\%~nx1"
Exit /B
I would like to ask if anyone has an idea how to send search result to console in single command line but with some specific code before and after the search results output
I need to run program Xconverter that is made to be operated by console, and has parameters:
-s :silent mode (only mode suported yet)
-i [files] : list location of the files in quotes: {-i "a.txt" "b.txt"..}
-t [tool file] : tool file location
-m 5 : conversion style
syntax accepted for example (single command for XConverter):
"C:\XConverter.exe" -s -i "C:\a.pgm" "C:\abc\b.pgm" -t "tool.tlgx" -m 5
but I need about 500 -i [files] to list
so i created search that fill look for those .pgm in tree mode where .bat is located and adds search result (file locations) one after other
my code is working but the only way i made it to work is that i outputed echo result in to extra .bat file and started the file. Is there i way to reprogram my code that it will send these outpust in to single one line command?
echo off
SET mypath=%~dp0
::THIS STARTS PROGRAM
(
echo | set /p="""
echo | set /p="C:\Program Files (x86)\Scm Group\Maestro\XConverter.exe" -s -i "
)>seznam_konvertovanych_suboru.bat
::THIS SEARCHERS FOR PGM FILES AND ADDS PATH OF EACH FILE TO THE LINE
for /f "delims=" %%A in ('forfiles /s /m *.pgm /c "cmd /c echo #relpath"') do (
set "file=%%~A"
setlocal enableDelayedExpansion
echo | set /p="""
echo | set /p="%mypath:~0,-1%\!file:~2!"
echo | set /p="" "
)>>seznam_konvertovanych_suboru.bat
::THIS ADDS SOME EXTRA FILE PATH TO THE LINE OF TOOL FILE, THAT IS NEEDED
(
echo | set /p=-t "Tlgx\def.tlgx" -m 5
)>>seznam_konvertovanych_suboru.bat
seznam_konvertovanych_suboru.bat
This code will output file seznam_konvertovanych_suboru.bat exactly in this format
"C:\XConverter.exe" -s -i "C:\a.pgm" "C:\abc\b.pgm" -t "tool.tlgx" -m 5
Anyone knows how to reprogram this to send that output to console in single line without creating extra file to store that code?
Edited:
What i need is having START_CONVERTING.BAT file that will send to console one command :
"C:\XConverter.exe" -s -i "C:\a.pgm" "C:\abc\b.pgm" -t "tool.tlgx" -m 5
but "C:\a.pgm" "C:\abc\b.pgm" are the search results of all .pgm files in that folder and child folders. So i will copy this START_CONVERTING.BAT anywehere where i store .pgm files. (some of them are in folders and those folders in other folders) so i will just copy STAR_CONVERTING.BAT in major folder that will thake care of all files with all files in child folders.
I will just click START_CONVERTING.BAT and it will convert those .pgm files. (without creating creating any other output to any other .bat file.
SOLVED (code)
#echo off & setlocal enableDelayedExpansion
PushD "%~dp0"
Set "XC=C:\Program Files (x86)\Scm Group\Maestro\XConverter.exe"
Set "TOOLFILE=Tlgx\def.tlgx"
Set "Files="
:: Concatenate all files in one string
for /f "delims=" %%A in ('Dir /B /S *.pgm') do set Files=!Files! "%%~A"
:: command, command line length may be an issue
"%XC%" -s -i%Files% -t "%TOOLFILE%" -m 5
If I understand right this might work
#echo off & setlocal enableDelayedExpansion
PushD "%~dp0"
Set "XC=C:\Program Files (x86)\Scm Group\Maestro\XConverter.exe"
Set "Files="
:: Concatenate all files in one string
for /f "delims=" %%A in ('Dir /B /S *.pgm') do set Files=!Files! "%%~A"
:: store command in batch file, command line length may be an issue
>"seznam_konvertovanych_suboru.bat" Echo "%XC%" -s -i %Files% -t "tool.tlgx" -m 5
try with that batch
Xconverter is for xxl to PGMX
1 set all path for converter
2 creat to do list of xxl files on desktop on this exemple or desktop sub folder!
3 Masetro can't be install as Office PC you must run it on CN PC!
#echo OFF
COLOR F1
TITLE "Convertor XXL to PGMX"
echo ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
echo º Converteur Xconverter º
echo ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
echo.
echo "Stop command with Ctrl+C"
echo.
Echo "Path SET"
TIMEOUT /t 5 >nul
Set todo="%userprofile%\desktop\todo.txt"
Set def="%PROGRAMFILES(x86)%\Scm Group\Maestro\Tlgx\def.tlgx"
Set Compil="%PROGRAMFILES(x86)%\Scm Group\Maestro\Xconverter.exe"
Set desktop="%userprofile%\desktop"
echo "To do list of *.XXL files"
TIMEOUT /T 10 >nul
cd %userprofile%\desktop
dir /a /b /o /s *.xxl > %todo%
echo "Files convert command"
TIMEOUT /T 10 >nul
for /f "delims=" %%a in (%todo%) do %Compil% ^ -s -m 4 ^
-i "%%a" ^
-t %def%
echo "Rapport files"
Timeout /T 10 >nul
cd %desktop%
dir /a /b /o /s *.pgmx > Rapport.txt
Echo "Delete to do list"
TIMEOUT /T 10 >nul
DEL %todo% /F /S /Q >nul
But haven't go detail of Convesion style -m X
if you can replie me detail of -m number it was great!
All the best, and hope this is helpful
D-Alexandre V.
I guess I'm mad enough to use a batch file, in the first place, but this problem has me tearing my hair out! The below batch script usually works just fine. However, on first run it will give a "The syntax of the command is incorrect" error; and it will do this until I REM out everything, run it through, and then unREM it. Then it magically starts working again!
#echo off
REM Create processed data directory
set "PROCDIR=processed"
mkdir %PROCDIR% 2>nul
REM Loop through CSV files and process them
for %%f in (*.csv) do (
set "in=%%~nf"
set "input=%%~nxf"
set "out_lang=%PROCDIR%\%in%_lang.csv"
set "out_spr=%PROCDIR%\%in%_spr.csv"
set "out_ajt=%PROCDIR%\%in%_ajt.csv"
echo Processing %input%
REM Split input file appropriately
REM FIXME Hardcoded line ranges are brittle
sed -n "1,2p" %input% > %out_lang%
sed -n "3,55p" %input% > %out_spr%.tmp
sed -n "56,$p" %input% > %out_ajt%.tmp
REM Unpack SPR data
REM n.b., Needs gawk 4, or later
gawk -f spr.awk %out_spr%.tmp > %out_spr%
del %out_spr%.tmp
REM Substitute AJT data values
REM n.b., -i seems to be buggy in Windows
sed -f ajt.sed %out_ajt%.tmp > %out_ajt%
del %out_ajt%.tmp
)
If I REM out the #echo off, it appears it's failing because the variable substitution sometimes -- for unknown reasons -- doesn't work. Then, when it gets to sed, it just gives up.
I assume I'm missing something... Any ideas what it might be!? (Besides my marbles!)
If I could give advice, use and abuse the PAUSE command, ECHO and escape characters ^ in it. Also Ctrl-C to stop the script during a PAUSE.
Here is a debugged version:
#echo off
SETLOCAL
REM Create processed data directory
set "PROCDIR=processed"
echo mkdir %PROCDIR% 2^>nul
REM Loop through CSV files and process them
for %%F in (*.csv) do (
set "in=%%~nF"
echo in: %in%
set "input=%%~nxF"
echo input: %input%
set "out_lang=%PROCDIR%\%in%_lang.csv"
set "out_spr=%PROCDIR%\%in%_spr.csv"
set "out_ajt=%PROCDIR%\%in%_ajt.csv"
echo Processing %input%
PAUSE
REM Split input file appropriately
REM FIXME Hardcoded line ranges are brittle
echo sed -n "1,2p" %input% ^> %out_lang%
echo sed -n "3,55p" %input% ^> %out_spr%.tmp
echo sed -n "56,$p" %input% ^> %out_ajt%.tmp
PAUSE
REM Unpack SPR data
REM n.b., Needs gawk 4, or later
echo gawk -f spr.awk %out_spr%.tmp ^> %out_spr%
echo del %out_spr%.tmp
PAUSE
REM Substitute AJT data values
REM n.b., -i seems to be buggy in Windows
echo sed -f ajt.sed %out_ajt%.tmp ^> %out_ajt%
echo del %out_ajt%.tmp
PAUSE
)
ENDLOCAL
GOTO :EOF
EXIT /B 0
I added setlocal enabledelayedexpansion and this seems to solve undeclared variable errors.
Here is a working version (you have to remove every redundant echo and carets ^):
#echo off
setlocal enabledelayedexpansion
REM Create processed data directory
set "PROCDIR=processed"
echo mkdir %PROCDIR% 2^>nul
REM Loop through CSV files and process them
for %%F in (*.csv) do (
set "in=%%~nF"
echo in: !in!
set "input=%%~nxF"
echo input: !input!
set "out_lang=!PROCDIR!\!in!_lang.csv"
set "out_spr=!PROCDIR!\!in!_spr.csv"
set "out_ajt=!PROCDIR!\!in!_ajt.csv"
echo Processing !input!
PAUSE
REM Split input file appropriately
REM FIXME Hardcoded line ranges are brittle
echo sed -n "1,2p" !input! ^> !out_lang!
echo sed -n "3,55p" !input! ^> !out_spr!.tmp
echo sed -n "56,$p" !input! ^> !out_ajt!.tmp
PAUSE
REM Unpack SPR data
REM n.b., Needs gawk 4, or later
echo gawk -f spr.awk !out_spr!.tmp ^> !out_spr!
echo del !out_spr!.tmp
PAUSE
REM Substitute AJT data values
REM n.b., -i seems to be buggy in Windows
echo sed -f ajt.sed !out_ajt!.tmp ^> !out_ajt!
echo del !out_ajt!.tmp
PAUSE
)
endlocal
GOTO :EOF
EXIT /B 0
Stephan is right, batch code is not working because of not using delayed expansion within FOR loop.
#echo off
setlocal EnableDelayedExpansion
REM Create processed data directory
set "PROCDIR=processed"
mkdir "%PROCDIR%" 2>nul
REM Loop through CSV files and process them
for %%f in (*.csv) do (
set "in=%%~nf"
set "input=%%~nxf"
set "out_lang=%PROCDIR%\!in!_lang.csv"
set "out_spr=%PROCDIR%\!in!_spr.csv"
set "out_ajt=%PROCDIR%\!in!_ajt.csv"
echo Processing !input!
REM Split input file appropriately
REM FIXME Hardcoded line ranges are brittle
sed -n "1,2p" "!input!" >"!out_lang!"
sed -n "3,55p" "!input!" >"!out_spr!.tmp"
sed -n "56,$p" "!input!" >"!out_ajt!.tmp"
REM Unpack SPR data
REM n.b., Needs gawk 4, or later
gawk -f spr.awk "!out_spr!.tmp" >"!out_spr!"
del "!out_spr!.tmp"
REM Substitute AJT data values
REM n.b., -i seems to be buggy in Windows
sed -f ajt.sed "!out_ajt!.tmp" >"!out_ajt!"
del "!out_ajt!.tmp"
)
endlocal
Every environment variable referenced within a block defined by ( ... ) is expanded by command processor already on parsing the entire block. On one of the help pages output into a command prompt window on execution of if /? explains that in detail.
This could been seen on running the batch code in question without the first line from within a command prompt window. Running a batch file from within a command prompt window without echo off or with echo on should be used on debugging batch code not working as expected.
And in case of any CSV file in current directory contains 1 or more spaces in file name, it is necessary to enclose all file references in double quotes to have a working code also for such files.
I have the following batch-file code to convert some video files with HandBrakeCLI:
for /R .\test %%F in (*.mp4,*.avi,*.flv,*.mov,*.3gp,*.wmv,*.mkv,*.ts) do (
HandBrakeCLI -e x264 --x264-preset medium -q 35 --crop 0:0:0:0 --aencoder copy -i "%%~fF" -o "%%~dpF%%~nF_conv.mp4"
if exist "%%~dpF%%~nF_conv.mp4" (
del "%%~fF"
ren "%%~dpF%%~nF_conv.mp4" "%%~nxF"
)
)
To apply this code on videos, I should copy the batch-file and Handbrake.exe (and also its relative folders) and paste them beside the folder named test (in the code above) then change the name "test" in the batch file to the name of that folder, then run the batch-file.
Could you write the batch-file in a way we run it in an arbitrary folder, so it prompt for a folder containing videos and we write the path (or just simply drag and drop the folder to the command line and press enter) without moving the files and renaming the "test"?
Use "%~1" to read a drag-and-drop argument.
for /R "%~1" %%F in (etc...)
If the batch script is launched without drag and drop (if "%~1"==""), you could use a folder chooser to let the user browse for a folder.
#if (#CodeSection == #Batch) #then
:: based on fchooser2.bat
:: https://stackoverflow.com/a/15906994/1683264
#echo off
setlocal
if "%~1"=="" (
call :chooser dir || goto usage
) else if exist "%~1" (
set "dir=%~1"
) else goto usage
for /R "%dir%" %%F in (*.mp4,*.avi,*.flv,*.mov,*.3gp,*.wmv,*.mkv,*.ts) do (
HandBrakeCLI -e x264 --x264-preset medium -q 35 --crop 0:0:0:0 --aencoder copy -i "%%~fF" -o "%%~dpF%%~nF_conv.mp4"
if exist "%%~dpF%%~nF_conv.mp4" (
del "%%~fF"
ren "%%~dpF%%~nF_conv.mp4" "%%~nxF"
)
)
:: end main runtime. Pause if dragged-and-dropped or double-clicked.
if /i "%cmdcmdline:~0,6%"=="cmd /c" pause
goto :EOF
:chooser <var_to_set>
setlocal
for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0"') do (
if not "%%~I"=="" if exist "%%~I" (
endlocal & set "%~1=%%~I"
exit /b 0
)
)
exit /b 1
:usage
echo Usage: %~nx0 [directory]
goto :EOF
#end
// JScript portion
var shl = new ActiveXObject("Shell.Application");
var folder = shl.BrowseForFolder(0, "Please choose a folder.", 0, 0x00);
WSH.Echo(folder ? folder.self.path : '');
You should create a variable to be read from user input
set /p path=Videos path :
for /R %path% %%F in (*.mp4,*.avi,*.flv,*.mov,*.3gp,*.wmv,*.mkv,*.ts) do (
HandBrakeCLI -e x264 --x264-preset medium -q 35 --crop 0:0:0:0 --aencoder copy -i "%%~fF" -o "%%~dpF%%~nF_conv.mp4"
if exist "%%~dpF%%~nF_conv.mp4" (
del "%%~fF"
ren "%%~dpF%%~nF_conv.mp4" "%%~nxF"
)
)
set /p will work fine either writing down the path or with folder drag-and-drop
I am creating this batch file, that works with handbrakecli, to batch convert avi to mp4.
However I am stuck in how to continue the loop and skip the current file inside a loop.
FOR /R "%somepath%" %%G in (*.avi) DO (
rem skip if filename contains word trailer
rem skip if file name contains word sample
rem do conversion
)
This currently doesn't work in skipping the files that contain trailer or sample
I have tried using find or findstr and both fail to skip.
echo "%%G" | c:\windows\system32\findstr /i "trailer" > NUL
If %ERRORLEVEL% EQU 1 set skip Yes
Here is for sample.
echo "%%G" | c:\windows\system32\findstr /i "sample" > NUL
If %ERRORLEVEL% EQU 1 set skip Yes
If a file contains either trailer or sample, I do not want to do any handbrakecli conversions, but to just skip it.
I do echo's to display which files get converted, and it does include files with Sample or sample in the name.
I have tried using find or findstr and both fail to set skip to yes
if skip == No do ( rem do conversion )
I only want to convert non-trailer/sample avi files.
Thank you for your time.
try this, put your conversion commands in the loop and remove the word echo before handbrakecli if the output is OK:
#echo off &setlocal
FOR /R "%somepath%" %%G in (*.avi) DO (
set "fpath=%%G"
set "fname=%%~nG"
setlocal enabledelayedexpansion
if "!fname!"=="!fname:trailer=!" if "!fname!"=="!fname:sample=!" (
echo handbrakecli.exe "!fpath!" &rem put your conversion command here
>>"logfile.log" echo !fname!
)
endlocal
)
The file name+file path is in the variable "!fpath!".
Added some code concerning the needs of the OP:
#echo off &setlocal
rem replace avi with mp4 files in my movie folder
rem grab 4 random folders with avi in them and no mp4
rem Settings for this Batch File
set "moviepath=H:\Movies"
set "logfile=C:\Documents and Settings\%USERNAME%\LogFiles\avi_converter.log"
rem check if log file exists
if not exist "%logfile%" echo(>"%logfile%"
rem create empty convert file
copy nul "convert_movies.bat" >nul 2>&1
rem add echo off
echo #echo off >>"convert_movies.bat"
rem set counter
SET /A COUNT=1
FOR /R "%moviepath%" %%G in (*.avi) DO (
set "fpath=%%~fG"
set "fname=%%~nG"
setlocal enabledelayedexpansion
rem check if count greater than 4
if !COUNT! gtr 4 goto:eof
if "!fname!"=="!fname:trailer=!" if "!fname!"=="!fname:sample=!" (
rem echo handbrakecli.exe "!fpath!" &rem put your conversion command here
rem Send File To HandBrakeCLI
CALL :DOHandBrakeCLI "!fpath!"
rem Delete File
CALL :DeleteOldFile "!fpath!"
rem Add Log Entry
CALL :LogEntry "!fpath!"
rem add line break space
echo( >>"convert_movies.bat"
endlocal
rem increment counter
SET /A COUNT+=1
) else endlocal
)
rem end main program, to close cmd window replace it with EXIT
goto:eof
:DOHandBrakeCLI
rem skip if the parameter is empty
IF "%~1"=="" goto:eof
For %%A in ("%~1") do (
Set "Folder=%%~dpA"
Set "Name=%%~nxA"
)
rem echo %Folder%%Name%
echo start /b "" "c:\handbrakecli\HandBrakeCLI.exe" -i "%~1" -o "%Folder%%~n1.mp4" --preset="High Profile">>"convert_movies.bat"
exit /b
:DeleteOldFile
rem skip if the parameter is empty
IF "%~1"=="" goto:eof
For %%A in ("%~1") do (
Set "Folder=%%~dpA"
Set "Name=%%~nxA"
)
rem sends parameters to deletefile which will make sure new file exists before deleting old one
echo c:\projects\deletefile.bat "%~1" "%Folder%%~n1.mp4">>"convert_movies.bat"
exit /b
:LogEntry
rem skip if the parameter is empty
IF "%~1"=="" goto:eof
echo "%~1">>"%logfile%"
exit /b
This should work:
#echo off
FOR /R "%somepath%" %%G in (*.avi) DO (
echo "%%~nG" |findstr /i "trailer sample">nul || (
rem do conversion
)
)
It's difficult to see where your post is pseudocode and where actual code.
The first sample contains only REM statements, so it's not surprising it apparently does nothing.
Your second and third sample are effectively identical - the only difference is the target string. It's not surprising that the variable skip isn't set to Yes since the correct syntax is
if %errorlevel% equ 0 set skip=Yes
The syntax you've posted will REPORT that skip is not defined - it ignores the Yes
HOWEVER this syntax is only usable OUTSIDE of a "block statement" - that is, a multiple-instruction statement (enclosed in parentheses) or cascaded&by&ersands. Batch first PARSES a complete statement - from the FOR or if through to the appropriate closing-parenthesis and THEN executes it. As part of the PARSING phase, any %var% - including %errorlevel% is replaced by its value as it stands at the time the entire statement is parsed - not as it changes due to the operation of the for.
In order to use the value as it changes, you need to use
if errorlevel 1 (do_something) else (do_something_else)
where do_something and do_something_else) may themselves be compound statements.
OR
if defined variable (do_something) else (do_something_else)
where the variable either is defined or not
OR
setlocal enabledelayedexpansion
....
if !errorlevel! equ x (do_something) else (do_something_else)
OR
if !var! neq something (do_something) else (do_something_else)
But it's quite possible that
FOR /R "%somepath%" %%G in (*.avi) DO (
echo(%%G|findstr /i "sample trailer" >nul
if errorlevel 1 echo %%G
)
will give you an appropriate skeleton.
Echo the filename through FINDSTR and look for "sample" or "trailer" /i case-insensitive. Findstr sets errorlevel 0 if either target string is found, 1 otherwise - and the if errorlevel x syntax works on the dynamic value of errorlevel within a loop.
#ECHO on &SETLOCAL
REM This script was inspired by Endoro's expanded script
(https://stackoverflow.com/a/16891696/10572786).
REM This batch script will recursively search for all .mp4 files that don't
have (x265) in the file name. Any valid results will be encoded with x265
using FFmpeg. The original .mp4 file will remain unchanged in it's original
folder with the new x265 version.
REM Example: %PATH%\A.mp4 > %PATH%\A(x265).mp4
REM If you don't have ffmpeg.exe on your PC you must download or build it
with Microsoft Visual Studios. I recommend you download and run media
autobuild suite on GitHub: (https://github.com/jb-alvarado/media-
autobuild_suite).
REM Once ffmpeg is compiled/downloaded make sure to set it's folder path as
an environmental variable in Windows before running the script. Change the
script's working directory to your .mp4 files root folder using the "cd"
command.
REM !!BEGIN SCRIPT!!
cd /d %USERPROFILE%\Desktop\Vids\
REM or perhaps use [cd /d %OneDrive%\Desktop\Vids]
REM Set mp4PATH to the root folder you wish to recursively search.
SET "mp4PATH=%USERPROFILE%\Desktop\Vids\"
REM Create empty convert file.
COPY NUL "convert_movies.bat" >NUL 2>&1
REM Add ECHO off.
ECHO #ECHO off >>"convert_movies.bat"
REM Recursively search root folder.
FOR /R "%mp4PATH%" %%G IN (*.mp4) DO (
SET "fpath=%%~fG"
SET "fname=%%~nG"
SETLOCAL enabledelayedexpansion
REM Ignore all files that have "(x265)" in the file name.
IF "!fname!"=="!fname:*(x265)=!" (
CALL :DO_FFmpeg_CLI "!fpath!"
ECHO(>>"convert_movies.bat"
) ELSE ENDLOCAL
)
)
GOTO:EOF
REM CALL variables for use in FFmpeg's command line.
:DO_FFmpeg_CLI
IF "%~1"=="" GOTO:EOF
FOR %%I IN ("%~1") DO (
SET "Folder=%%~dpI"
SET "Name=%%~nxI"
)
REM Export info to "convert_movies.bat and run ffmpeg.exe's command line in the cmd.exe window.
ECHO ffmpeg -y -i "%~1" -c:v libx265 -preset slow -crf
18 -c:a aac "%Folder%%~n1(x265).mp4">>"convert_movies.bat" && ffmpeg |
ffmpeg -y -i "%~1" -c:v libx265 -preset slow
-crf 18 -c:a aac "%Folder%%~n1(x265).mp4"
EXIT /B
PAUSE
The Batch file below solve the original question AND limit the number of converted files to a given number (that does not appear in the original question):
#echo off
setlocal EnableDelayedExpansion
rem Insert in the next line the list of files to skip
set skip=/trailer/sample/
set count=0
FOR /R "%somepath%" %%G in (*.avi) DO (
if /I "!skip:/%%~nG/=!" equ "%skip%" (
echo Current file name is not in skip variable
echo Do conversion on: %%G
set /A count+=1
if !count! equ 20 goto :endLoop
)
)
:endLoop
echo Converted files: %count%