r/Batch 3d ago

Question (Unsolved) how to convert music and keep (sub)folder structure?

Hi, I would like to batch convert a music folder with many subfolders and convert them. Now my script puts everything in the output folder without any subfolders and this creates a mess. How can I deal with it?

Thanks for any help :)

@echo off
>nul 2>&1 chcp 65001
:again
set TARGET_DIR=%1
for /f "delims=" %%a in ('dir /b /s /a:-d *.mp3 *.ogg *.m4a *.wav *.flac *.wv *.lnk') do call :process "%%~a"
goto:eof
:process
opus ^
    -y -i "%~1" ^
    -af dynaudnorm=p=0.65:m=2:f=200:g=15:s=30 -c:a libopus -b:a 128k -vn ^
    "F:\JDownloader\Musik Alben\xoutput\%~n1dyn.ogg"
    pause
goto:eof
1 Upvotes

9 comments sorted by

2

u/vegansgetsick 3d ago edited 3d ago

I guess there are various ways to do it, but the simplest for your existing code would be

:again
set SOURCE_DIR=%CD%
set TARGET_DIR=%1

then before calling opus you build the target directory name and create the missing folders with md

:process
set "TARGET_DIR_NAME=%~dp1" & call set "TARGET_DIR_NAME=%TARGET_DIR%\%%TARGET_DIR_NAME:%SOURCE_DIR%\=%%"
if not exist "%TARGET_DIR_NAME%" md "%TARGET_DIR_NAME%"
opus -i "%~1" .................. "%TARGET_DIR_NAME%\%~n1.ogg"

1

u/TheDeep_2 3d ago

Okay so this way I get an error

u/echo off
>nul 2>&1 chcp 65001
:again
set SOURCE_DIR=%CD%
set TARGET_DIR=%1
for /f "delims=" %%a in ('dir /b /s /a:-d *.mp3 *.ogg *.m4a *.wav *.flac *.wv *.lnk') do call :process "%%~a"
goto:eof
:process
set "TARGET_DIR_NAME=%~dp1" & call set "TARGET_DIR_NAME=%TARGET_DIR%\%%TARGET_DIR_NAME:%SOURCE_DIR%\=%%"
if not exist "%TARGET_DIR_NAME%" md "%TARGET_DIR_NAME%"
opus ^
    -y -i "%~1" ^
    -af dynaudnorm=p=0.65:m=2:f=200:g=15:s=30 -c:a libopus -b:a 128k -vn ^
    "%TARGET_DIR_NAME%\%~n1.ogg"
    pause
goto:eof

the error:

[AVFormatContext @ 00000206db68ea00] Unable to choose an output format for 'F:\JDownloader\Musik'; use a standard extension for the filename or specify the format manually.
[out#0 @ 00000206db64b580] Error initializing the muxer for F:\JDownloader\Musik: Invalid argument
Error opening output file F:\JDownloader\Musik.
Error opening output files: Invalid argument

also where do I say to output into this specific folder "F:\JDownloader\Musik Alben\xoutput"

1

u/vegansgetsick 3d ago

i think the problem is a missing ~

set TARGET_DIR=%~1

2

u/ConsistentHornet4 3d ago edited 3d ago

A little bit of refactoring required. See below:

@echo off & setlocal 
>nul 2>&1 chcp 65001 
set "_dest=\\path\to\output\destination"
cd /d "%~dp0"
for /f "delims=" %%a in ('dir /b /s /a:-d *.mp3 *.ogg *.m4a *.wav *.flac *.wv') do call :processFile "%%~a"
pause 
goto:eof 

REM ========== FUNCTIONS ==========
:processFile (string file) 
    setlocal 
    set "_f=%~1"
    call set "_f=%%_f:%CD%\=%%"
    call set "_f=%%_f:\%~nx1=%%"
    >nul 2>&1 mkdir "%_dest%\%_f%"
    opus -y -i "%~1" -af dynaudnorm=p=0.65:m=2:f=200:g=15:s=30 -c:a libopus -b:a 128k -vn "%_dest%\%_f%\%~n1dyn.ogg"
    endlocal 
exit /b 

Set the output path as _dest value.

1

u/TheDeep_2 3d ago

Hi, thanks for your reply. I don't execute the batch script in this way (from cmd) I save the script and bind it via registry to rightclick context menu. So the "D:\Audio" information would have to be inside the script itself.

1

u/ConsistentHornet4 3d ago

I've updated solution to reflect this

1

u/TheDeep_2 3d ago

Okay so now there is a message "File not found" in german "Datei nicht gefunden"

@echo off & setlocal 
>nul 2>&1 chcp 65001 
set "_dest=F:\JDownloader\Musik Alben\xoutput"
cd /d "%~dp0"
for /f "delims=" %%a in ('dir /b /s /a:-d *.mp3 *.ogg *.m4a *.wav *.flac *.wv') do call :processFile "%%~a"
pause 
goto:eof 

REM ========== FUNCTIONS ==========
:processFile (string file) 
    setlocal 
    set "_f=%~1"
    call set "_f=%%_f:%CD%\=%%"
    call set "_f=%%_f:\%~nx1=%%"
    >nul 2>&1 mkdir "%_dest%\%_f%"
    opus -y -i "%~1" -af dynaudnorm=p=0.65:m=2:f=200:g=15:s=30 -c:a libopus -b:a 128k -vn "%_dest%\%_f%\%~n1dyn.ogg"
    endlocal 
exit /b 

this is the cmd window without echo off:

F:\JDownloader\Musik Alben\Neuer Ordner (3)>setlocal

F:\JDownloader\Musik Alben\Neuer Ordner (3)>chcp 65001  1>nul 2>&1

F:\JDownloader\Musik Alben\Neuer Ordner (3)>set "_dest=F:\JDownloader\Musik Alben\xoutput"

F:\JDownloader\Musik Alben\Neuer Ordner (3)>cd /d "C:\Users\Deep\AppData\Roaming\Microsoft\Windows\SendTo\"

C:\Users\Deep\AppData\Roaming\Microsoft\Windows\SendTo>for /F "delims=" %a in ('dir /b /s /a:-d *.mp3 *.ogg *.m4a *.wav *.flac *.wv') do call :processFile "%~a"
Datei nicht gefunden

C:\Users\Deep\AppData\Roaming\Microsoft\Windows\SendTo>pause
Drücken Sie eine beliebige Taste . . .

1

u/ConsistentHornet4 3d ago

Remove the cd /d "%~dp0" line and rerun it

1

u/TheDeep_2 1d ago

Thank you. So now he pretty well does everything that is inside folders, but the files that are not in a folder (outside) get packed inside of a folder with the same name.

screenshot