14

I tried different options from forums, but most of them are out of date (ffmpeg tells me about it, like with -sameq option). Im trying to understand the docs, but I can't.

I want to know how to convert recursively with ffmpeg from wma to mp3 with a for example max bitrate of 192kbps in output (but not 192 this if the original was 128kbps)

I have unless 14K wma files spread in many directories. So, I don't want to move them. Just convert them keeping filename and metadata, and delete them, if it would be possible to read the list of the files to convert from a txt file that I can create, one file per line. With this, I would manage to make the recursive search, an paste into it.

Thanks for any help. And still more thanks for any explanation about Ffmpeg.

Caroxo

PS: Soundconverter used to be good, but slow. Now neither one or the other. Doesn't work in 14.04 in many cases, like mine. I'm using Soundkonverter but is very slow. So, all this for preventing this recommendations. And I want to learn to use this powerful ffmpeg! and the CLI

NOTE: The script here below, was working in the first convertions. But for any reason that I cant explain, suddenly deleted the wma's in conversion, without leaving the mp3. So, I changed again to "unsolved" (to prevent occasionally problem to someone's else). The problem seems coming from avconv " Application provided invalid, non monotonically increasing dts to muxer in stream 0: 23606 >= 21720"(there are pastebins in the comments if there is someone interested in developing this bug). So, no avconv in the future.

CaRoXo
  • 153

6 Answers6

34

This is the command I use for ffmpeg all the files in the current directory (works if names have spaces in them) on Mac where brew doesn't have avconv:

for file in *.wma; do ffmpeg -i "${file}"  -acodec libmp3lame -ab 192k "${file/.wma/.mp3}"; done
10

In a terminal, first browse to the folder that contains all of your music using cd, for example:

cd /home/username/music/wma-to-convert

The following will make a list of all files in the current folder and all subfolders ending in "wma" and store the list in a text document called wma-files.txt:

find . -type f | grep wma$ > wma-files.txt

Or you could create the text file manually if you want. Then type the following in a text editor and save it in the same directory of wma-files.txt, for example naming it conv-script:

#!/usr/bin/env bash

readarray -t files < wma-files.txt

for file in "${files[@]}"; do out=${file%.wma}.mp3 probe=avprobe -show_streams &quot;$file&quot; 2&gt;/dev/null rate=echo &quot;$probe&quot; | grep &quot;^bit_rate&quot; | sed &quot;s:.*=\(.*\)[0-9][0-9][0-9][.].*:\1:&quot; | head -1 ffmpeg -i "$file" -ab "$rate"k "$out" done

You probably have to set the executable bit on the script:

chmod +x conv-script

Then just run it:

./conv-script

You also have the option of adding this to the end of the ffmpeg line, but be careful:

 && rm "$file"

For those who don't have access to avprobe, you can use ffprobe which does the equivalent (i.e. getting the bit_rate). To do that:

Replace:

probe=`avprobe -show_streams "$file" 2>/dev/null`
rate=`echo "$probe" | grep "^bit_rate" | sed "s:bit_rate=\([0-9]\+\)[0-9]\{3\}:\1:" | head -1`

with:

rate=`ffprobe -v error -show_entries format=bit_rate -of default=noprint_wrappers=1:nokey=1 "$file"`

Once this is done, all your files should start converting and the wma originals should get deleted! This worked great for me converting flac files to mp3. Unfortunately I don't have any wma to test, but I expect it should do fine for those as well.

NOTE: While I don't foresee any problems, it would be a good idea to copy a few files to a new directory and test it on them.

If you plan to often convert Wma to mp3, the below script automatically convert and delete everything in the folder given as an argument, It improves a bit the above-mentioned. In addition, the ffmpeg command is a bit different than the first proposed, if the first one does not work, use the below one.

#!/usr/bin/env bash

cd "$1" find . type f | grep wma$ > wma-files.txt

readarray -t files < wma-files.txt

for file in "${files[@]}"; do out=${file%.wma}.mp3 ffmpeg -i "$file" -map_metadata 0:s:0 "$out" done rm wma-files.txt

Then, you simply call it by typing in you terminal as:

./convScript /home/username/music

Thus, all the music folder and its subfolders will have its wma music automatically converted in mp3.

As before, you can add this to end of the ffmpeg line for file removal:

&& rm "$file"

EDIT (2017/06/23): don't make rm the default

Zanna
  • 72,312
TheSchwa
  • 3,860
4

For any version

I found a neat way to do this with mplayer. This script will rename the files to remove all blank spaces in the names of the files and will recursively convert all .wma files in the current directory to .mp3:

#!/bin/bash
for f in *.wma; do
 newname=`echo $f | tr ' ' '_' `
 mv "$f" $newname
 f=$newname
 mplayer $f -novideo -ao pcm:file=tmp.wav
 lame -V 0 -q 0 tmp.wav ${f/.wma/.mp3}
 rm -f tmp.wav
done

Here's a one liner version:

for f in *.wma; do; newname=`echo $f | tr ' ' '_' `; mv "$f" $newname; f=$newname; mplayer $f -novideo -ao pcm:file=tmp.wav; lame -V 0 -q 0 tmp.wav ${f/.wma/.mp3}; rm -f tmp.wav; done
muru
  • 207,228
mchid
  • 44,904
  • 8
  • 102
  • 162
3

I rewrite TheSchwa script (thanks TheSchwa!), with these changes:

  • avprobe detection works (at least on ffprobe version 2.5.2 from current Debian unstable).
  • Don't delete files with rm (convertors usually don't delete files, this can be a big surprise!).
  • Load wma files in script.
  • Help when missing binaries.
#!/bin/bash

which ffmpeg > /dev/null || { echo "Install ffmpeg, with 'sudo apt-get install ffmpeg'" >&2; exit 1; }
which avprobe > /dev/null || { echo "Install libav-tools, with 'sudo apt-get install libav-tools'" >&2; exit 1; }

output_format=mp3
file=`mktemp`
find . -type f | grep -i wma$ > $file

readarray -t files < $file

for file in "${files[@]}"; do
    out=${file%.wma}.$output_format
    probe=`avprobe -show_streams "$file" 2>/dev/null`

    rate=`echo "$probe" | grep "^bit_rate" | sed "s:bit_rate=\([0-9]\+\)[0-9]\{3\}:\1:" | head -1`
    ffmpeg -i "$file" -ab "$rate"k "$out"
done
pevik
  • 483
2

Note: the following does not apply to 15.04, 15.10 or 16.04

First:

ffmpeg is deprecated in 14.04 anyhow and you should now use avconv instead.

sudo apt-get install avconv

Use this command to convert wma files to mp3 recursively:

for i in `find . -type f -name '*.wma'`; do avconv -i "$i" "${i/.wma/.mp3}"; done

Then, once you have verified the quality of the files, you may run this command to remove or delete the original .wma versions recursively:

for i in `find . -type f -name '*.wma'`; do rm "$i"; done

Next:

Here's how to use the command in a script instead (named "wma2mp3":

sudo nano /usr/local/bin/wma2mp3

copy and paste this into the file:

#!/bin/bash
for i in `find . -type f -name '*.wma'`; do avconv -i "$i" "${i/.wma/.mp3}"; done

Press ctrl + o and then press enter to save the file and use ctrl + x to exit.

Then, make the file executable with the following command:

sudo chmod +x /usr/local/bin/wma2mp3

Now you can simply run the command wma2mp3 to recursively covert all wma files to mp3.

Just do the same with the script to erase all wma files and name it whatever you want.


BTW, if you just want to convert all the files in the current directory only (not throughout all other subsequent recursive directories), you can use this command instead:

for i in *.wma; do avconv -i "$i" "${i/.wma/.mp3}"; done

and of course, to remove the wma files in the current directory only, just use this command:

rm *.wma
muru
  • 207,228
mchid
  • 44,904
  • 8
  • 102
  • 162
1

This is a bash script, using parallel:

#!/bin/bash

parallel -i -j$(nproc) ffmpeg -i {} -acodec libmp3lame -ab 192k {}.mp3 ::: ./*.wma
rename 's/.wma//' *.wma.mp3
Aubin
  • 131