#!/usr/bin/python import os import sys import getopt import shutil from mutagen.id3 import ID3 from mutagen.flac import FLAC from mutagen.oggvorbis import OggVorbis #encoders and decoders MP3_ENCODER = "lame --silent -r -x --vbr-new -m s -V 7 --tt $TITLE$ --ta $ARTIST$ --tl $ALBUM$ --ty $DATE$ --tn $TRACK$ --tg $GENRE$ - $FILE$ 2>/dev/null" OGGVORBIS_ENCODER = "oggenc -Q -r -q 3 -t $TITLE$ -a $ARTIST$ -l $ALBUM$ -d $DATE$ -N $TRACK$ -G $GENRE$ - -o $FILE$ 2>/dev/null" FLAC_DECODER = "flac -s -d --force-raw-format --sign=signed --endian=little $FILE$ -o - 2>/dev/null" OGGVORBIS_DECODER = "oggdec -Q -s 1 -e 0 -R $FILE$ 2>/dev/null" MP3_DECODER = "madplay -q -o raw:- $FILE$ 2>/dev/null" #associated formats FLAC_FORMAT = "flac" OGGVORBIS_FORMAT = "ogg" MP3_FORMAT = "mp3" SUPPORTED_TARGETS = [MP3_FORMAT,OGGVORBIS_FORMAT] SUPPORTED_SOURCES = [MP3_FORMAT,OGGVORBIS_FORMAT,FLAC_FORMAT] #set option defaults target_format = MP3_FORMAT target_encoder = MP3_ENCODER source = os.getcwd() target = os.getcwd() verbose = False def reencode(source_file,target_file): if (verbose): print("Found "+source_file); source_format = source_file.split(".").pop() target_file = target_file.replace(source_format,target_format) #if the file exists at the destination already we'll skip it if (os.path.isfile(target_file)): if (verbose): print("Target exists."); return if (source_format in SUPPORTED_SOURCES): #if the formats are the same, why reencode? if ((target_format in SUPPORTED_TARGETS) and (source_format == target_format)): shutil.copyfile(source_file,target_file) if (verbose): print("Copying to "+target_file); return #retrieve the metadata and set the decoder appropriately if (source_format == FLAC_FORMAT): audio = FLAC(source_file) source_decoder = FLAC_DECODER if (source_format == MP3_FORMAT): audio = ID3(source_file) source_decoder = MP3_DECODER if (source_format == OGGVORBIS_FORMAT): audio = OggVorbis(source_file) source_decoder = OGGVORBIS_DECODER command = target_encoder.replace("$FILE$","\""+target_file+"\"") command = command.replace("$TITLE$","\""+audio["title"].pop()+"\"") command = command.replace("$ARTIST$","\""+audio["artist"].pop()+"\"") command = command.replace("$ALBUM$","\""+audio["album"].pop()+"\"") command = command.replace("$GENRE$","\""+audio["genre"].pop()+"\"") command = command.replace("$DATE$","\""+audio["date"].pop()+"\"") command = command.replace("$TRACK$","\""+audio["tracknumber"].pop()+"\"") command = source_decoder.replace("$FILE$","\""+source_file+"\"")+" | "+command if (verbose): print("Reencoding to "+target_file); os.popen(command) else: if (verbose): print("Unsupported format."); #recursively walk through directories, in turn walking through #subdirectories and processing files accordingly def recursive_walk(running_directory=""): subfolders = os.listdir(os.path.join(source,running_directory)) subfolders.sort(key=str.lower) for abstract_source_object in subfolders: source_object = os.path.join(os.path.join(source,running_directory),abstract_source_object) if os.path.isfile(source_object): reencode(source_object,os.path.join(os.path.join(target,running_directory),abstract_source_object)) else: if os.path.isdir(source_object): target_directory = os.path.join(os.path.join(target,running_directory),abstract_source_object) if not (os.access(target_directory,os.F_OK+os.W_OK+os.X_OK)): os.mkdir(target_directory,0755) recursive_walk(os.path.join(running_directory,abstract_source_object)) #get arguments and set options try: opts, args = getopt.getopt(sys.argv[1:], "s:d:t:v", ["source=", "destination=","target=","verbose"]) for opt,arg in opts: if (opt in ("-v","--verbose")): verbose = True if (opt in ("-s","--source")): source = arg if (opt in ("-d","--destination")): target = arg if (opt in ("-t","--target")): target_format = arg #set the encoder if (target_format == FLAC_FORMAT): target_encoder = FLAC_ENCODER if (target_format == MP3_FORMAT): target_encoder = MP3_ENCODER if (target_format == OGGVORBIS_FORMAT): target_encoder = OGGVORBIS_ENCODER except getopt.GetoptError: sys.exit(str(getopt.GetoptError)) #check to make sure the directories we're going to use are OK if not (os.access(source,os.F_OK+os.R_OK+os.X_OK)): sys.exit("Source directory doesn't exist or isn't accesible!") if not (os.access(target,os.F_OK+os.W_OK+os.X_OK)): sys.exit("Destination directory doesn't exist or isn't accesible!") if not (target_format in SUPPORTED_TARGETS): sys.exit("Invalid target format!") #start our walk recursive_walk()