Zune's new "gapless" (close enough) playback works better with AACs than it does with Lame-encoded mp3s. So, a quick hack script was in order to convert my collection of FLACs into AACs. But, I have four cores, so the script had to take advantage of those! Here's my flac2m4a Python script, that will convert a whole folder hierarchy into m4a files. It uses as many cores as you have available, and copies cover art so Zune can understand it. It's a bit rough, though.
You will need:
Here's the script:
import os
import shutil
import pp
job_server = pp.Server()
jobs = []
def quote(s):
return s.replace('"', '\\"')
def convert_file(input,output):
flac_mapping = {'title': '\xa9nam', 'artist': '\xa9ART', 'album': '\xa9alb', 'genre': '\xa9gen', 'description': '\xa9cmt', 'composer': '\xa9wrt', 'date': '\xa9day'}
command = 'flac -d -c -s "' + quote(input) + '" | neroAacEnc -br 128000 -lc -if - -of "' + quote(output) + '" 2>/dev/null'
os.system(command)
tagsource = mutagen.flac.FLAC(input)
tagdest = mutagen.mp4.MP4(output)
for k, v in flac_mapping.iteritems():
if tagsource.has_key(k):
tagdest[v] = tagsource[k]
if tagsource.has_key('tracknumber'):
tagdest['trkn'] = [(int(tagsource['tracknumber'][0]), 0)]
tagdest['pgap'] = True
tagdest.save()
return "processed " + os.path.basename(output)
def convert_directory(src, dst):
os.mkdir(dst)
srcnames = os.listdir(src)
for name in srcnames:
srcfname = os.path.join(src, name)
dstfname = os.path.join(dst, name)
if (os.path.isdir(srcfname)):
convert_directory(srcfname, os.path.join(dst, name))
elif (name.endswith('.flac')):
newname = name[:-4] + "m4a"
jobs.append(job_server.submit(convert_file, (srcfname, os.path.join(dst, newname)), (quote,), ("mutagen.flac", "mutagen.mp4", "os", "sys")))
elif (name == "cover.jpg"):
shutil.copyfile(srcfname, os.path.join(dst, "ZuneCustomAlbumArt.jpg"))
if __name__ == "__main__":
import sys
if len(sys.argv) == 3:
print "Starting pp with", job_server.get_ncpus(), "workers"
convert_directory(sys.argv[1], sys.argv[2])
for i, job in enumerate(jobs):
print job(), str(i+1) + "/" + str(len(jobs))
job_server.print_stats()
else:
print "usage: flac2m4a <input> <output>"