10

In recent weeks I've gone from a fairly 'hands-on' approach to .flac --> .mp3 transcoding, to one that's far more 'set & forget'.

The first step was to stop using a GUI front end (Audacity with a LAME plug-in) and instead use the method I outlined here.

The second step was to find a bash shell script that would tell that command loop to work recursively, allowing directories with many subdirectories containing .flac files to be transcoded in one simple step. That answer was provided by a user at askubuntu.com.

Now I wish to learn how to further refine things so that ID3 tag information is preserved. The methods linked to above strip ID3 tag data, leaving the bare minimum (i.e. only the title field remains).

Can anyone teach me how to write such a shell script?


The shell script has been updated thus:

#!/bin/bash
file="$1"
flac -cd "$file" | lame --preset fast extreme - "${file%.flac}.mp3"
id3cp "$file" "${file%.flac}.mp3"

Doing find . -name '*.flac' -exec ~/bin/flac2mp3 '{}' \; in ~/Desktop/stack gives the following output:

01 - Amon Tobin - Chomp Samba.flac: done         
LAME 3.98.4 64bits (http://www.mp3dev.org/)
Using polyphase lowpass filter, transition band: 19383 Hz - 19916 Hz
Encoding <stdin> to ./01 - Amon Tobin - Chomp Samba.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III VBR(q=0)
Parsing ./01 - Amon Tobin - Chomp Samba.flac: done.  Copying to ./01 - Amon Tobin - Chomp Samba.mp3: done

id3info for the original .flac and resultant .mp3 gives, respectively:

*** Tag information for 01 - Amon Tobin - Chomp Samba.flac

(i.e. nothing);

*** Tag information for 01 - Amon Tobin - Chomp Samba.mp3
*** mp3 info
MPEG1/layer III
Bitrate: 128KBps
Frequency: 44KHz

The .flac definitely has tag information. I can verify this by opening up EasyTAG. EasyTAG refers to this as 'FLAC Vorbis Tag' but 'ID3 Tag' for the .mp3. Is this the problem?

2
  • Have you tried using ffmpeg?
    – Hello71
    Mar 27, 2011 at 17:56
  • No I haven't. Never really used it before on the CLI to be honest. Someone told me about this Perl script. I'll try that tomorrow and report back as it's late now.
    – boehj
    Mar 27, 2011 at 18:26

4 Answers 4

8
#!/bin/sh

file="$1"
outfile=${file%.flac}.mp3

eval $(metaflac --export-tags-to - "$file" | sed "s/=\(.*\)/='\1'/")

flac -cd "$file" | lame --preset fast extreme \
        --add-id3v2 --tt "$TITLE" --ta "$ARTIST" --tl "$ALBUM" \
        --ty "$DATE" --tn "$TRACKNUMBER" --tg "$GENRE" \
        - "$outfile"
3
  • Thanks Kambus! That pretty much does the trick. The majority of the tags I want are now there, post-transcode: Title, Album, Artist, Year, Track Number. The CD field (1/1, 1/2, etc.) hasn't made it across, and neither has the field for the 'Track Number Of'. But this doesn't really bother me. Interestingly I tried this script on a directory containing 'Trip Hop' music. The tags were kept in tact but the script changed the Genre from 'Trip Hop' to 'Trip-Hop'. So I guess it's relying on a database of known genres there. Thanks very much once again for your input!
    – boehj
    Mar 27, 2011 at 22:28
  • @pedrogent: I'm glad I could help! You can check manually what are the other tags with "metaflac --export-tags-to - file" and use them the same way as $TITLE and the others, but the problem is there are no equivalent fields for them in id3 AFAIK. Maybe you can put them in the comment tag. Yes, there is a predefined list of genres: link
    – Kambus
    Mar 28, 2011 at 9:17
  • Hi Kambus. Yes I think part of the problem here is that there's no clear 'standard' for ID3 tag data. The Comment tag is interpreted very differently from player to player (or not at all). Your script is awesome. Thanks again.
    – boehj
    Mar 29, 2011 at 8:43
2

How to use mp3fs to mass encode flac to mp3

Instead of using a program to convert flac files to mp3, you can use mp3fs to present them as virtual mp3's, and a program that can queue copy jobs. It works wonderfully well for me.

Download and install mp3fs and ultracopier:

sudo apt-get install mp3fs ultracopier

Create a pair of flac and mp3 directories for each mp3fs you want to run. I have a dual core cpu so I run two. If you keep the flac directories on the partition where your flac files are, you can quickly move those. That partition is called "Storage" on my system.

cd /media/Storage
mkdir mp3fs mp3fs/flac_1 mp3fs/mp3_1 mp3fs/flac_2 mp3fs/mp3_2

You can mount the directories from the command line or by adding them to /etc/fstab. You can also configure the bitrate and encoding algorithm of the virtual mp3's at mount time. I want mp3's with a constant bitrate of 320kbps, and lame may take all the time it needs to produce the best mp3 it possibly can.

On the commandline:

mp3fs -b 320 -oquality=0 /media/Storage/mp3fs/flac_1 /media/Storage/mp3fs/mp3_1 -o allow_other,ro
mp3fs -b 320 -oquality=0 /media/Storage/mp3fs/flac_2 /media/Storage/mp3fs/mp3_2 -o allow_other,ro

If fuse complains, like

fusermount: failed to open /etc/fuse.conf: Permission denied
fusermount: option allow_other only allowed if 'user_allow_other' is set in etc/fuse.conf

then uncomment the user_allow_other option in /etc/fuse.conf, and/or make it readable with

sudo chmod 644 /etc/fuse.conf

Or from /etc/fstab:

mp3fs#/media/Storage/mp3fs/flac_1 /media/Storage/mp3fs/mp3_1 fuse user,ro,allow_other,bitrate=320,quality=0 0 0
mp3fs#/media/Storage/mp3fs/flac_2 /media/Storage/mp3fs/mp3_2 fuse user,ro,allow_other,bitrate=320,quality=0 0 0

After adding the directories to /etc/fstab, you can mount them by using

sudo mount -a

Done! Start ultracopier. It'll place an indicator icon in your gnome panel or whatever it is that you use. Click it, select add copy. I did that twice to use two cores. Use your file browser to move some flacs into flac_1. Navigate to the mp3_1 directory, and drag your mp3's to one of the ultracopier windows to start a copy queue. Ultracopier will ask for the destination of the files. You now have one core busy encoding a batch of flacs to mp3.

To use the other core, move flac files to flac_2, and drag the mp3's from mp3_2 to the second ultracopier window.

Update: Instead of ultracopier I'm now using MiniCopier, it's a little easier to use. See comments below.

4
  • There seems to be a bug with the directory listing with recent versions of mp3fs and fuse: sourceforge.net/tracker/…
    – Ophidian
    Nov 18, 2011 at 16:58
  • @Ophidian: Interesting. I ran some tests on some machines using different distributions. I had them running, within a minute each, without any errors. The mp3fs version I've been using is the same, 0.30. I've used kernels 2.3.38, 2.3.39, and 3.0.0, libfuse versions 2.8.4 and 2.8.6. Libfuse mentioned in the bug reports is 2.8.5. That's not nearly enough to conclude fuse is the culprit, however, it might be worth trying a different version if you run into problems while using 2.8.5. Did you perhaps try mp3fs? On which kernel and with which libfuse? Did you encounter any problems? Nov 19, 2011 at 19:23
  • Instead of ultracopier I'm now using MiniCopier, it's a little easier to use. It's a java app, it requires no installation but does need a JRE. It has a basket icon and a box icon. You can drag one or more sources from a file manager onto the basket icon, a destination directory onto the box icon, and that's all you need to do to add a copy job to the queue. MiniCopier has a seperate tab for failed items. MiniCopier uses less cpu cycles than ultracopier, 1% vs 3% on my system. That might just save 12 minutes on a 10 hour queue ;-) Nov 19, 2011 at 19:25
  • If you want a shell based copy queue, I found a solution at superuser. Without adjustments, you won't be able to run 2 queues with it, and I'm not sure what it will do with errors. Nov 19, 2011 at 19:27
0

id3cp can not work since FLAC does not use ID3; it uses Vorbis tags instead.

ffmpeg has an option to maintain tags through conversion. It's kind of fickle, its value depending on the combination of codecs, but it works like this in your case (version 3.4.8):

ffmpeg -i in.flac -map_metadata 0:g:0 out.mp3

Applying this all FLAC files in a folder (recursively) is as easy as this: (using bash)

for f in */**/*.flac; do
  ffmpeg -i "${f}" -map_metadata 0:g:0 "${f%.flac}.mp3";
done

Note that ffmpeg uses lame automatically; further options exist to control quality and whatnot. Check man ffmpeg for detail.

0

Raphael's answer helped me a lot. However to make things work with my set of FLAC files, I had to manually adjust the streams, so that the tags were preserved correctly and audio was the first stream in the mp3 file. I ended up with this line:

$nohup bash -c 'for f in */**/*.flac; do ffmpeg -i "${f}" -map 0:a -map 0:v:0? -map 0:v:1? -c:v copy -codec:a libmp3lame -qscale:a 2 -y "${f%.flac}.mp3"; done' 2>&1 > log.txt &

The question marks allow the related streams to be missing. The qscale parameter defines the mp3 encoding quality of the lame encoder library used within ffmepg.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .