Don't use an arithmetic expression to assign a value to an environment variable. There is usually no reason to do so. Just use SET "stream_type_total=%%A"
without /A
.
There should be a space between command GOTO
and its first argument :EOF
.
But the main problem is the command block:
( ENDLOCAL
FOR /L %%A IN (1,1,%stream_type_total%) DO (
CALL SET "stream_obj[%%A].id=%stream_obj[%%A].id%"
)
)
The command ENDLOCAL does not only restore previous state of delayed environment variable expansion, it discards also the currently active environment variables list and restores previous list of environment variables. Read this answer for details about the commands SETLOCAL and ENDLOCAL.
So the environment variable stream_type_total
as well as all stream_obj[x].id
environment variables do not exist anymore after this command.
I suggest to modify this command block to:
FOR /L %%A IN (1,1,%stream_type_total%) DO CALL SET "stream_obj[%%A].id=%stream_obj[%%A].id%"
ENDLOCAL
Now the FOR loop should work as expected.
But please note that even with this change the modified stream_obj[x].id
environment variables do not exist anymore after command ENDLOCAL.
So better would be to avoid usage of SETLOCAL and ENDLOCAL in this subroutine completely like with using this code:
:extract_stream
FOR /F "delims=" %%A IN ('%media_info% "--output=%stream_count_string%" "%file%"') DO SET "stream_type_total=%%A"
SET "stream_count=1"
FOR /F "tokens=1-4 delims=," %%A IN ('%media_info% "--output=%format_string%" "%file%"') DO (
SET /A "id=%%A-1"
SET "title=%%B"
SET "codec=%%C"
SET "language=%%D"
REM SET "id=!id:~1!"
CALL SET "title=%%title:~1%%"
CALL SET "codec=%%codec:~1%%"
IF DEFINED language CALL SET "language=%%language:~1%%"
IF NOT DEFINED language SET "language=English"
REM IF "!codec!" EQU "V_MPEG4/ISO/AVC" SET "language="
CALL SET "stream_obj[%%stream_count%%].id=%%id%%"
CALL ECHO ID:%%id%% Title=%%title%%, Codec=%%codec%%, Language=%%language%%
SET /A "stream_count+=1"
)
FOR /L %%A IN (1,1,%stream_type_total%) DO CALL SET "stream_obj[%%A].id=%stream_obj[%%A].id%"
GOTO :EOF
The commands commented out with command REM are not modified in code above.
Another solution would be using one more subroutine:
:extract_stream
FOR /F "delims=" %%A IN ('%media_info% "--output=%stream_count_string%" "%file%"') DO SET "stream_type_total=%%A"
SET "stream_count=1"
FOR /F "tokens=1-4 delims=," %%A IN ('%media_info% "--output=%format_string%" "%file%"') DO CALL :UpdateVariables "%%~A" "%%~B" "%%~C" "%%~D"
FOR /L %%A IN (1,1,%stream_type_total%) DO CALL SET "stream_obj[%%A].id=%stream_obj[%%A].id%"
GOTO :EOF
:UpdateVariables
SET /A "id=%~1-1"
SET "title=%~2"
SET "codec=%~3"
SET "language=%~4"
REM SET "id=%id:~1%"
SET "title=%title:~1%"
SET "codec=%codec:~1%"
IF DEFINED language SET "language=%language:~1%"
IF NOT DEFINED language SET "language=English"
REM IF "%codec%" == "V_MPEG4/ISO/AVC" SET "language="
SET "stream_obj[%stream_count%].id=%id%"
ECHO ID:%id% Title=%title%, Codec=%codec%, Language=%language%
SET /A "stream_count+=1"
GOTO :EOF
The commands commented out with command REM are modified in code above too.
One last hint: Don't use comparison operator EQU
on comparing two strings. This operator is designed for comparing 32-bit signed integer values and not for string comparisons. Read the answer on Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files for details about comparing strings or integer values with command IF.