Windows Batch – Extract values for ffmpeg processing

Windows batch scripting does not understand the JSON file format, so it is better to use a language natively supports it. It is not the best idea to treat JSON as “normal” text, because only a slight change (for instance, added, deleted, or moved line-breaks) that do not violate the JSON format can still make big troubles then.

That said, given that the JSON file exactly appears as you have shown it and it features Unix- or DOS/Windows-style line-breaks (that is, a carriage-return character followed by a line-feed character), this code could work for you:

for /F "usebackq tokens=1,2 delims={:}, " %%M in ("file.json") do set "%%~M=%%~N"
echo year  = %year%
echo track = %track%

If you have got a huge JSON file you do not want to unnecessarily fully process, you could use this code instead:

set "year=" & set "track="
for /F "usebackq tokens=1,2 delims={:}, " %%M in ("file.json") do (
    set "%%~M=%%~N"
    if defined year if defined track goto :CONT
)
:CONT
echo year  = %year%
echo track = %track%

If the (non-array) values you want to extract may also contain one of the defined delimiters ({, :, }, ,, SPACE), you could extend the code to this, given that the values do not contain the characters *, ?, <, >:

set "year=" & set "track="
for /F "usebackq tokens=1,* delims={:}, " %%M in ("file.json") do (
    for %%K in (%%N) do set "%%~M=%%~K"
    if defined year if defined track goto :CONT
)
:CONT
echo year  = %year%
echo track = %track%

To prevent the script from assigning unwanted superfluous variables, you may try this:

for /F "usebackq tokens=1,2 delims={:}, " %%M in ("file.json") do (
    if "%%~M"=="year" (set "%%~M=%%~N") else if "%%~M"=="track" set "%%~M=%%~N"
)
echo year  = %year%
echo track = %track%

Or this, which prepreocesses the data by the findstr command and filters out the desired lines:

for /F "tokens=1,2 delims={:}, " %%M in ('
    findstr /R /C:"^ *\"year\" *:" /C:"^ *\"track\" *:" "file.json"
') do set "%%~M=%%~N"
echo year  = %year%
echo track = %track%

Based on your edit, let me suggest to use the last of the above methods, because there is no goto :CONT, which cannot be used within loops as it breaks the block context, and it does not assign additional unwanted variables. Since variables are written and read within the loop body, you have to enable and apply delayed variable expansion. I would do all that the following way:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem /* Iterate over the `*.json` files in the current working directory (`%CD%`);
rem    to use the parent directory of this script, use `%~dp0*.json` instead: */
for %%I in ("*.json") do (
    rem // Store name of current JSON file in variable:
    set "name=%%~nI"
    rem // Clear variables for later check for availability:
    set "year=" & set "track="
    rem // Process the current JSON file:
    for /F "tokens=1,2 delims={:}, " %%M in ('
        findstr /R /C:"^ *\"year\" *:" /C:"^ *\"track\" *:" "%%~I"
    ') do (
        rem // Assign year and track variables:
        set "%%~M=%%~N"
        rem // Check of both year and track are available:
        if defined year if defined track (
            rem // Toggle delayed expansion to avoid troubles with `!`:
            setlocal EnableDelayedExpansion
            rem // Eventually execute `ffmpeg` tool using all the derived data:
            ffmpeg -i "!name!.m4a" -metadata:s:a:0 year=!year! -metadata:s:a:0 track=!track! -acodec libmp3lame "!name!.mp3"
            endlocal
        )
    )
)
endlocal
exit /B

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top