3

I recently started converting all my video files to MP4 for streaming purposes, and was using batch so far without issues. Now I have 6000+ videos to convert and needed some sort of queue system I could manipulate.

This is my current code to convert everything from directories into commands in a separate folder.

@echo off
setlocal disabledelayedexpansion
set dirs=D:\ANIME E:\ANIME F:\ANIME
for %%a in (%dirs%) do (
    echo %%a
    pushd %%a
    for /f "tokens=* delims= " %%f IN ('dir/b/s *.avi *.mkv *.m4v *.mpeg *.mpg') do (
        echo D:\handbrake\HandBrakeCLI.exe -i "%%f" -e qsv_h264 -q 20 -E fdk_haac -B 196 -R Auto -D 0,0,0,0 --audio-copy-mask aac,ac3,dtshd,dts,mp3 --audio-fallback copy:* --subtitle=1 --subtitle-default --subtitle-forced --subtitle-burn -o "%%~dpf%%~nf.mp4" > "D:\batch\%%~nf.bat"
        echo del /F "%%f" >> "D:\batch\%%~nf.bat"
    )
)

This works great and makes me 1000's of bat files to call and that is where the issue arises. A lot of files have special characters like ! in their names which messes up the for loop I use to loop through these. I set the file to read-only before processing, so my other batch won't try to convert the same file (I run 3 at once).

I found a workaround using ENABLEDELAYEXPANSION, but after a few loops I will get the error saying I exceeded the maximum calls for that.

@echo off
setlocal enableextensions 
echo Starting loop
goto loop

:loop
for  %%f in (D:\batch\*.bat) do (
    set ATTRIBS=%%~af
    setlocal enabledelayedexpansion
    set READ_ATTRIB=!ATTRIBS:~1,1!
    if !READ_ATTRIB!==- (
        setlocal disabledelayedexpansion
        attrib +R "%%f"
        call "%%f"
    )

    timeout /t 2 /nobreak
    goto loop
)
endlocal

Normally you'd say just change the ! variables to % and remove delayedexpansion, but that gives me errors in getting the file attributes.

set READ_ATTRIB=%ATTRIBS:~1,1%
        if %READ_ATTRIB%==- (

Will give me no result and the error ( is unexpected If I echo READ_ATTRIB the result will be ~1,1 always and when echoing others I will get ECHO IS OFF.

Is there any way to not use delayedexpansion or in a way that I won't get errors after a few loops?

2
  • 2
    You should be using endlocal when you're done with setlocal. Commented Nov 27, 2015 at 7:54
  • Trying that solution, but will have results in a few hours since these files takes ages to convert. Commented Nov 27, 2015 at 10:04

1 Answer 1

2

32 is the deepest level of setlocal when used in batch file. You need to use setlocal - endlocal pair analogously to a pair of ( left and ) right parentheses. See capitalized ENDLOCAL below.

@echo off
setlocal enableextensions 
echo Starting loop
goto loop

:loop
for  %%f in (D:\batch\*.bat) do (
    set ATTRIBS=%%~af
    setlocal enabledelayedexpansion
    set READ_ATTRIB=!ATTRIBS:~1,1!
    if !READ_ATTRIB!==- (
        setlocal disabledelayedexpansion
        attrib +R "%%f"
        call "%%f"
        ENDLOCAL
    )
    ENDLOCAL
    timeout /t 2 /nobreak
    REM                    this was totally mazy:  goto loop
)
endlocal

Moreover, latter goto loop in your original code causes that for %%f loop is initialised over and over indefinitely against the same data set, i.e. %%f in the loop body refers to the only file all the time. See capitalized REM.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I added the goto to add new data to the loop. If a new release came out the loop would start over at the beginning so I could add it. Else it would iterate over the known first until everything is done and then get the new files in the folder.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.