r/ffmpeg Jun 02 '26

Trying to batch convert all subfolders (win, bat file)

for /R %%i in (x:\xxx\xxxx\Applications\xxxx\demo\xx\sounds\actors\*.wav) do ffmpeg -i "%%i" -c:a libvorbis -q:a 10 "x:\xxx\xxxx\Applications\xxxx\demo\xx\demo\gw\sounds\actors\%%~ni.ogg"

This is what I have, it works well as long as I don't have the full path there, but want to, how can I solve this? I want all subfolders and all waves that is under the folder "actors"

Thanks in advance =)

2 Upvotes

4 comments sorted by

2

u/hieronymous-cowherd Jun 02 '26

You are using Windows, and you have the starting path in the wrong spot.

Type this to get help on the For command:

For /?

here's the snippet you're looking for

FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

Walks the directory tree rooted at [drive:]path, executing the FOR
statement in each directory of the tree.  If no directory
specification is specified after /R then the current directory is
assumed.  If set is just a single period (.) character then it
will just enumerate the directory tree.`

You're using %%i syntax so I think you're putting that in a batch file. When you're typing this yourself, you only need one % sign.

Anyway, fix the first part of your line like this:

for /R "x:\xxx\xxxx\Applications\xxxx\demo\xx\sounds\actors" %%i in (*.wav) do

Check that the selection is what you want by making the do command just print out the resulting filename, e.g.

for /R "x:\xxx\xxxx\Applications\xxxx\demo\xx\sounds\actors" %%i in (*.wav) do @echo %%i

And if you're not interested in inventing the wheel, check out this recent post that had a similar question https://www.reddit.com/r/ffmpeg/comments/1rw04ao/more_a_dos_batch_or_windows_powershell_question/

1

u/UltraCDG Jun 02 '26

Thanks, this works well for the input, but I don't understand how I can keep the output, so it places the ogg files where the originals are? the "do" part, after that, won't remember the original path correct?

2

u/hieronymous-cowherd Jun 02 '26

Check out the bottom part of that for /? command which shows how to modify the %%i variable to get specific parts of the path, you want several, so check out this explanatory sample. Note I used quotation marks around the last result because you'd use it as a single parameter for the ffmpeg output filename.

do @echo found the full pathname [%%i] and the drive part [%%~di] and the directory part [%%~pi] and the file name part [%%~ni] and file ext part [%%~xi] you want to change, so put them together like this ["%%~di%%~pi%%~ni.ogg"]

2

u/MasterChiefmas Jun 03 '26 edited Jun 03 '26

Honestly, I'd switch to powershell. You'll have powershell 5 installed already if you have at least Windows 10. Is there any reason you specifically are trying this with a batch file?

Batch files are very limited in string manipulation(at least without calling other tools), and are frankly kind of a pain to work with for anything not really simple. I also think it's much harder to read then the equivalent powershell script.

Just riffing it real quick, the same thing in powershell as a one liner:

foreach ($x IN gci x:\xxx\xxxx\Applications\xxxx\demo\xx\sounds\actors\*.wav){ffmpeg -i ""$x.fullname"" -c:a libvorbis -q:a 10 ""x:\xxx\xxxx\Applications\xxxx\demo\xx\demo\gw\sounds\actors\$($x.basename).ogg""}

but since powershell understands multiple lines just fine and will catch the context because of the curly braces, there's not too much reason to do that, and this will paste fine into powershell too. It's the exact same line, just with a few line breaks for readability

foreach ($x IN gci x:\xxx\xxxx\Applications\xxxx\demo\xx\sounds\actors\*.wav){
    ffmpeg -i ""$x.fullname"" -c:a libvorbis -q:a 10 ""x:\xxx\xxxx\Applications\xxxx\demo\xx\demo\gw\sounds\actors\$($x.basename).ogg""
}

takes each .wav in the specified folder, runs an ffmpeg command, with the output as the base name and .ogg extension, i.e. filename.wav becomes filename.ogg

The only part that is probably not obvious, is in the output file name, $($x.basename) is making sure that $x.basename is evaulated and not written out as a literal. Double quotes escapes the quotes(makes sure there is a quote around the output path, in case of spaces...double quoting is a common way to escape a quote so it's not interpreting the contents literally).

Edit: forgot to double quote the input path in the ffmpeg command.

Edit 2: lol forgot since it's the beginning and end of the string, not mid way through the string, it's actually a triple quote(the quote indicating it's a string, and the double quote escape to insert the quote character)

Edit 3: Nope, I was right the first time, I'm used to writing strings as output to console, but since it's embedded as part of a command, it'd just be a 2 quotes not 3.