Comfort Eagle
Comfort Eagle

Reputation: 2452

ffmpeg: Batch convert anything in subfolders

I'm new to this and having an hard time:

This is my file structure:

.\input\
.\output\
convert.bat

.\input\ contains subfolders which in their turn contain .wav and other audio-formats. Im trying to get convert.bat to convert all files in those subfolders to .mp3 in .\output\. Furthermore, I need to name to converted files to the name of the subfolder where it originated from + it's original filename.

How do I do this with an batch file using FFMPEG? Big thanks in advance!

Upvotes: 2

Views: 6661

Answers (2)

Mofi
Mofi

Reputation: 49085

Let us assume the folder C:\Temp containing the batch file has following folder structure and files:

  • input
    • Folder.01
      • First File.wav
    • My Folder
      • SecondFile.aac
    • Another.ac3
  • output
  • Convert.bat

The batch file Convert.bat contains following lines:

@echo off
setlocal EnableDelayedExpansion

rem Input and output folder are in same directory as batch file.
set "InputFolder=%~dp0input"
set "OutputFolder=%~dp0output"
echo  Input folder is: %InputFolder%
echo Output folder is: %OutputFolder%
echo/

rem Search in input folder and all subfolders for the specified types
rem of audio files and output what is found with the output file name
rem in output folder. Delayed environment variable expansion is needed
rem for all variables set or modified within the body of the FOR loop.

for /R "%InputFolder%" %%I in (*.aac *.ac3 *.wav) do (
    set "InputFileName=%%~nxI"
    set "InputFilePath=%%~dpI"
    set "OutputFileName=!InputFilePath:~0,-1!"
    call :GetOutputFileName "!OutputFileName!" "%%~nI"
    echo  Input file name is: !InputFileName!
    echo  Input file path is: !InputFilePath!
    echo Output file name is: !OutputFileName!
    echo Output file path is: %OutputFolder%\
    echo --------
)

endlocal
echo/
pause
rem Exit batch processing and return to command process.
exit /B

rem Subroutine to get last folder name from first argument and append an
rem underscore, the file name of the input file without file extension
rem passed as second argument and the file extension MP3. But if the path
rem to the file is identical with input folder path, get just name of file
rem with different file extension.

:GetOutputFileName
if "%~1" == "%InputFolder%" (
    set "OutputFileName=%~2.mp3"
) else (
    set "OutputFileName=%~nx1_%~2.mp3"
)
rem Exit subroutine.
exit /B

Executing this batch file results in the output:

 Input folder is: C:\Temp\input
Output folder is: C:\Temp\output

 Input file name is: Another.ac3
 Input file path is: C:\Temp\input\
Output file name is: Another.mp3
Output file path is: C:\Temp\output\
--------
 Input file name is: SecondFile.aac
 Input file path is: C:\Temp\input\My Folder\
Output file name is: My Folder_SecondFile.mp3
Output file path is: C:\Temp\output\
--------
 Input file name is: First File.wav
 Input file path is: C:\Temp\input\Folder.01\
Output file name is: Folder.01_First File.mp3
Output file path is: C:\Temp\output\
--------

So you can see how to get wanted output file name from input file name. Instead of all the echo commands after the call add the line running ffmpeg.exe with the appropriate parameters for the conversion of the found audio files to MP3 files in output directory. Don't forget the double quotes around input and output file specifications.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • echo /?
  • endlocal /?
  • exit /?
  • for /?
  • if /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

Upvotes: 3

martin
martin

Reputation: 96891

This is a question about bash not ffmpeg:

for f in dir/*.wav; do echo "./output/"$(echo "${f%.yml}.mp4"|tr / _); done

This takes all files in the dir directory ending with .wav, and outputs them as mp3 files prefixed with dir_. For example if you had files:

dir/audio1.wav
dir/whatever.wav

it will print:

./output/dir_audio1.mp3
./output/dir_whatever.mp3

In you case you'll just use ffmpeg instead of echo inside the for loop:

for f in dir/*.wav; do ffmpeg -i "$f" ... "./output/"$(echo "${f%.yml}.mp4"|tr / _); done

Upvotes: 2

Related Questions