#!/usr/bin/python # (This is obsolete; use portree instead.) # Encode audio files with sensible tags, figuring out as much information as # possible from the filenames. # Adam Sampson import optparse, sys, os, re, subprocess class Encoder: def command(self, cmd, options): if options.dryrun: print >>sys.stderr, "Would run: %s" % " ".join(cmd) else: rc = subprocess.call(cmd) if rc != 0: print >>sys.stderr, "Failed (%d): %s" % (rc, " ".join(cmd)) sys.exit(rc) class OggEncoder(Encoder): name = "ogg" def encode(self, fn, dest_fn, number, title, artist, album, options): cmd = [ "oggenc", "-q4", "-o", dest_fn, "-t", title, "-l", album, ] if artist is not None: cmd += ["-a", artist] if number is not None: cmd += ["-N", number] cmd += [fn] self.command(cmd, options) class MP3Encoder(Encoder): name = "mp3" def encode(self, fn, dest_fn, number, title, artist, album, options): cmd = [ "lame", "-h", "--preset", "standard", "--add-id3v2", "--tt", title, "--tl", album, ] if artist is not None: cmd += ["--ta", artist] if number is not None: cmd += ["--tn", number] cmd += [fn, dest_fn] self.command(cmd, options) class FlacEncoder(Encoder): name = "flac" def encode(self, fn, dest_fn, number, title, artist, album, options): cmd = [ "flac", "-o", dest_fn, "--best", "--tag=TITLE=" + title, "--tag=ALBUM=" + album, ] if artist is not None: cmd += ["--tag=ARTIST=" + artist] if number is not None: cmd += ["--tag=TRACKNUMBER=" + number] cmd += [fn] self.command(cmd, options) encoders = [ OggEncoder(), MP3Encoder(), FlacEncoder(), ] def transcode(fn, encoder, options): full_fn = os.path.splitext(os.path.abspath(fn))[0] dest_fn = full_fn + "." + encoder.name base_fn = os.path.basename(full_fn) artist = options.artist album = os.path.basename(os.path.dirname(full_fn)) l = album.rsplit(" - ", 1) if len(l) == 2: (album, artist) = (l[0], l[1]) if options.album: album = options.album m = re.match(r'^(\d-)?(\d\d) (.*)$', base_fn) if m is None: number = None else: (number, base_fn) = m.group(2, 3) l = base_fn.rsplit(" - ", 1) if len(l) == 2: (title, artist) = (l[0], l[1]) else: title = base_fn encoder.encode(fn, dest_fn, number, title, artist, album, options) def main(): parser = optparse.OptionParser(usage="%prog [options] FILE ...") parser.add_option("-n", action="store_true", dest="dryrun", help="Show what will be done, rather than doing it") parser.add_option("-a", metavar="ARTIST", dest="artist", help="Default artist name") parser.add_option("-l", metavar="ALBUM", dest="album", help="Override album name") encoder_list = "/".join([e.name for e in encoders]) default_encoder = encoders[0].name parser.add_option("-f", metavar="FORMAT", dest="format", help="Output format (%s, default %s)" % (encoder_list, default_encoder), default=default_encoder) (options, args) = parser.parse_args() encoder = None for e in encoders: if e.name == options.format: encoder = e break for fn in args: transcode(fn, encoder, options) if __name__ == "__main__": main()