Is there any way to convert a bunch of .ogg files in a folder to .mp3 using ffmpeg?

Is there any way to convert a whole heap of .ogg files in about 30 folders in a folder containing those folders to .mp3 files and put them in another folder using the command ffmpeg? The previous methods I have tried all led to the same error: "*.ogg no such file or directory"

If possible could you please tell me how? I cant find anything relating to this specific question.

Edit: I've tried to edit the command and now it's giving me this error: (this goes for all of the files in the folder)

/Users/Macbook/Downloads/Minecraft+Sound+Pack+1.13/step/wood6.ogg~/Downloads/Minecraft\ Sounds/step/wood6.mp3: No such file or directory

I used this:

$ for file in ~/Downloads/Minecraft+Sound+Pack+1.13/step/*.ogg 
> do
>     fullfilename=$(basename "${file}")
>     filename="${fullfilename%.*}"
>     ffmpeg -i "$file""~/Downloads/Minecraft\ Sounds/step/$filename.mp3"
> done

I think it's trying to link both directories together.


Solution 1:

Isn't it astonishing how such small problems create a bunch of solutions :-)

Download the ZIP file, then run

unzip "Minecraft Sound Pack 1.13.zip" -d mc
cd mc/
find . -type f -iname '*.ogg' -execdir sh -c \
    'ffmpeg -v 8 -i "$1" "${1%.*}.mp3" && rm -- "$1" && echo "$1"' sh {} \;

This will replace all .ogg files with the .mp3 version, deleting the .ogg file in the process. You still have the original data in the ZIP file if needed.

  • -type f ensures that only files get matched (otherwise a directory named foo.ogg would be passed to ffmpeg for processing as well)
  • The -execdir option runs the following command within the directory the file was found (so we don't need to worry about stripping path names)
  • Because -execdir can only run one command we start a new shell and pass the set of commands via -c
  • ffmpeg -v 8 -i "$1" "${1%.*}.mp3" && rm -- "$1" && echo "$1"is the actual command getting executed, with the name of the file to be converted as $1
  • sh {} are the parameters passed to the shell script as $0 and $1 respectively. sh is only required for syntactical reasons (you could put any word there, some people use _ for instance), {} gets replaced by the currently found file
  • \; terminates the -execdir part (actually ; does, but it needs to get escaped from bash who would interpret it as a command terminator otherwise)

PS: If you want to see the details from ffmpeg remove the -v 8 part.

Solution 2:

As an example, I have a bunch of .ogg files in my Downloads directory, so... to batch convert a bunch of .ogg files in a given directory to .mp3 files in the same directory, I did the following in Terminal:

cd Downloads
for f in *.ogg; do ffmpeg -i "$f" "${f%.*}.mp3"; done

This created an .mp3 file for each .ogg file I have in my Downloads directory.

So, using your directory path, do the following:

cd ~/Downloads/Minecraft+Sound+Pack+1.13/step
for f in *.ogg; do ffmpeg -i "$f" "${f%.*}.mp3"; done

That said and considering your dealing with a sound file pack you downloaded from the Internet, Minecraft+Sound+Pack+1.13.zip, which contains 131 directories, some nested 3 or more deep, and 1406 .ogg files, of which some of the filenames are the same, I would handle the situation with the following conditions in mind.

  1. I downloaded the Minecraft+Sound+Pack+1.13.zip file from the Internet.
  2. Expanded the zip archive by double-clicking on it in my Downloads folder in Finder. Note that this is because I do not let the Browser unzip downloaded archive files. This also retains a copy of the zip archive in case I still need it afterwards.

With that done, I used the following example bash script to convert each .ogg file within the hierarchal folder structure to an .mp3 file at the same location. Then delete the .ogg files, as I still have the original zip archive.

#!/bin/bash

    # s="/Path/To/Source/Files"

s="$HOME/Downloads/Minecraft+Sound+Pack+1.13"

for d in $(find "$s" -type f -iname '*.ogg' | sed -E 's|/[^/]+$||' | sort -u); do
    cd "$d"
    for f in *.ogg; do
        ffmpeg -i "$f" "${f%.*}.mp3"
        rm "$f"
    done
done
  • You only need to change the value of s="..." as or if needed and as a general rule I like to use $HOME in place of ~.

Note that this is just how I choose to deal with the situation in the moment and there are many different ways that a script could be written. This however I believe achieves the end goal of having the hierarchal folder structure of the 131 directories intact with the 1406 converted .mp3 files.

By the way... On my old MacBook Pro, (Retina, 15-inch, Early 2013) 2.8 GHz Intel Core i7, it took just under 9 minutes to process the 1406 .ogg files.