I need to convert all Ogg Vorbis files in a directory to MP3. I will create a small bash script that uses avconv or FFmpeg to convert the audio files.
Let us assume that we have the following Ogg music files in a directory.
In A Beautiful Place Out In The Country/
|-- 01 - Kid For Today.ogg
|-- 02 - Amo Bishop Roden.ogg
|-- 03 - In A Beautiful Place Out In The Country.ogg
`-- 04 - Zoetrope.ogg
The following command will convert the file 01 - Kid For Today.ogg
to 01 - Kid For Today.mp3
.
ffmpeg
or avconv
command.avconv -i 01\ -\ Kid\ For\ Today.ogg -acodec libmp3lame -map_metadata 0:s:0 01\ -\ Kid\ For\ Today.mp3
avconv version 11.8-6:11.8-1~deb8u1, Copyright (c) 2000-2016 the Libav developers
built on Oct 1 2016 07:16:29 with gcc 4.9.2 (Debian 4.9.2-10)
Input #0, ogg, from '01 - Kid For Today.ogg':
Duration: 00:06:23.00, start: 0.000000, bitrate: 109 kb/s
Stream #0.0: Audio: vorbis, 44100 Hz, stereo, fltp, 160 kb/s
Metadata:
ALBUM : In A Beautiful Place Out In The Country
track : 1
ARTIST : Boards Of Canada
DATE : 2000
TITLE : Kid For Today
Output #0, mp3, to '01 - Kid For Today.mp3':
Metadata:
TSSE : Lavf56.1.0
Stream #0.0: Audio: libmp3lame, 44100 Hz, stereo, fltp
Metadata:
ALBUM : In A Beautiful Place Out In The Country
track : 1
ARTIST : Boards Of Canada
DATE : 2000
TITLE : Kid For Today
encoder : Lavc56.1.0 libmp3lame
Stream mapping:
Stream #0:0 -> #0:0 (vorbis (native) -> mp3 (libmp3lame))
Press ctrl-c to stop encoding
size= 5985kB time=382.99 bitrate= 128.0kbits/s
video:0kB audio:5985kB other streams:0kB global headers:0kB muxing overhead: 0.003067%
We want to loop over all Ogg files in a directory and print the filename with the extension mp3
instead
of ogg
. The following bash script ogg2mp3.bash
placed in the directory with the Ogg files
is doing that.
#!/bin/bash
for i in *.ogg; do
printf "${i:0:(-3)}mp3\n"
done
We can call that script the following way.
bash ogg2mp3.bash
01 - Kid For Today.mp3
02 - Amo Bishop Roden.mp3
03 - In A Beautiful Place Out In The Country.mp3
04 - Zoetrope.mp3
We will combine the avconv
command with the loop script and can execute it the same way as above in the
directory.
#!/bin/bash
for i in *.ogg; do
avconv -i "$i" -acodec libmp3lame -map_metadata 0:s:0 "${i:0:(-3)}mp3"
done
The script should have produced for every Ogg file a MP3 file in the current directory.
In A Beautiful Place Out In The Country/
|-- 01 - Kid For Today.mp3
|-- 01 - Kid For Today.ogg
|-- 02 - Amo Bishop Roden.mp3
|-- 02 - Amo Bishop Roden.ogg
|-- 03 - In A Beautiful Place Out In The Country.mp3
|-- 03 - In A Beautiful Place Out In The Country.ogg
|-- 04 - Zoetrope.mp3
|-- 04 - Zoetrope.ogg
`-- ogg2mp3.bash
Sometimes it is necessary to convert also every file in all subdirectories.
For example if you want to convert your whole music library. Let us assume
that we have the following directories with the some Ogg files and some
image files. The test logo.png
files are just to check if our
script works fine.
Music/
|-- Iron Maiden/
| |-- Futureal/
| | |-- 01. Futureal.ogg
| | |-- 02. The Evil that Men do.ogg
| | `-- 03. Man on the Edge.ogg
| `-- logo.png
`-- Tofu Resistance/
|-- logo.png
|-- Tofu Resistance - Carlindos Way.ogg
|-- Tofu Resistance - Manduka - Brasil 1500 -Edit-.ogg
`-- Tofu Resistance - Soimatoi Part 2.ogg
We are doing the same as above, but in this case with the find
command. The following bash script ogg2mp3rec.bash
in the
Music
directory will list all Ogg files in all subdirectories.
#!/bin/bash
find . -name *.ogg | while read line; do
printf "${line:0:(-3)}mp3\n"
done
Here the execution of the bash script.
bash ogg2mp3rec.bash
./Tofu Resistance/Tofu Resistance - Carlindos Way.mp3
./Tofu Resistance/Tofu Resistance - Soimatoi Part 2.mp3
./Tofu Resistance/Tofu Resistance - Manduka - Brasil 1500 -Edit-.mp3
./Iron Maiden/Futureal/01. Futureal.mp3
./Iron Maiden/Futureal/03. Man on the Edge.mp3
./Iron Maiden/Futureal/02. The Evil that Men do.mp3
The following script will convert all Ogg files in all subdirectories to MP3 files.
</dev/null
is necessary to
prevent that the ffmpeg
command is eating its own output as
input in a loop. I found this solution at
Unix & Linux Stack Exchange.
Without the </dev/null
at the end of the
ffmpeg
command you might get errors like the following one.
#!/bin/bash
find . -name *.ogg | while read line; do
ffmpeg -i "$line" -acodec libmp3lame -map_metadata 0:s:0 "${line:0:(-3)}mp3" </dev/null
done
We can call that bash script as before.