Showing posts with label zune. Show all posts
Showing posts with label zune. Show all posts

20 May 2008

flac2m4a.py

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>"