Re: [linux-audio-user] ardour and mp3?

From: rob <rob@email-addr-hidden-egg.org>
Date: Sun Feb 04 2007 - 13:29:12 EET

Matt Price wrote:
> convert the files to mp3 one at a time when I want to, but I wonder if
> there's a more fluid way of e.g. converting files when they're uploaded,
> or at least converting all files in a particular folder or something.
> are there other people out there who have to deal with a similar
> situation?
>
I hacked up this python script to transcode from wav/mp3/ogg/flac to
wav/mp3/flac/ogg.

HTH
R

#!/usr/bin/python

# Copyright Rob Fell, 2007.

import sys
import string
import os
import os.path
import string
import shutil
import tempfile

from subprocess import *

best = False

def GetFlacInfo( meta, f ):
        cmd = "metaflac --show-sample-rate --show-tag=artist --show-tag=album --show-tag=title --show-tag=tracknumber --show-tag=date %s"
        p = Popen( cmd % f, shell=True, stdout=PIPE, stderr=PIPE )

        artist = album = year = song = tracknum = rate = None

        for field in p.communicate()[0].split('\n'):
                
                sep = field.find('=')
                if sep > 0:
                        key = field[0:sep].lower().lstrip()
                        value = field[sep+1:]

                        if key == 'artist':
                                artist = value
                        if key == 'album':
                                album = value
                        if key == 'title':
                                song = value
                        if key == 'tracknumber':
                                tracknum = int( value )
                        if key == 'date':
                                year = value
                else:
                        str = ""
                        for ch in field.lstrip():
                                if ch.isdigit():
                                        str += ch
                                else:
                                        break
                        if str:
                                rate = int( str )

        if song: meta['song'].append( song )
        if artist: meta['artist'].append( artist )
        if album: meta['album'].append( album )
        if tracknum: meta['tracknum'].append( tracknum )
        if year: meta['date'].append( year )
        if rate: meta['rate'].append( rate )

def GetOggInfo( meta, f ):
        p = Popen( "ogginfo %s" % f, shell=True, stdout=PIPE )

        artist = album = year = song = tracknum = rate = None

        for field in p.communicate()[0].split('\n'):
                sep = field.find('=')
                if sep > 0:
                        key = field[0:sep].lower().lstrip()
                        value = field[sep+1:]

                        if key == 'artist':
                                artist = value
                        if key == 'album':
                                album = value
                        if key == 'title':
                                song = value
                        if key == 'tracknumber':
                                tracknum = int( value )
                        if key == 'date':
                                year = value
                else:
                        if 'Rate:' in field:
                                rate = int( field.split(' ')[1] )

        if song: meta['song'].append( song )
        if artist: meta['artist'].append( artist )
        if album: meta['album'].append( album )
        if tracknum: meta['tracknum'].append( tracknum )
        if year: meta['date'].append( year )
        if rate: meta['rate'].append( rate )

def GetID3Info( meta, f ):
        p = Popen( "id3info %s" % f, shell=True, stdout=PIPE )

        artist = album = year = song = tracknum = rate = None

        for field in p.communicate()[0].split('\n'):

                if 'Frequency' in field:
                        freq = field.split(':')[-1].lstrip().lower()
                        if '44khz' == freq:
                                rate = 44100
                        elif '48khz' == freq:
                                rate = 48000

                if not field[0:3] == '===':
                        continue

                key = field[4:8]

                if key == 'TIT2':
                        song = field.split(':')[-1].lstrip()
                elif key == 'TPE1':
                        artist = field.split(':')[-1].lstrip()
                elif key == 'TALB':
                        album = field.split(':')[-1].lstrip()
                elif key == 'TRCK':
                        tracknum = int( field.split(':')[-1] )
                elif key == 'TYER':
                        year = int( field.split(':')[-1] )

        if song: meta['song'].append( song )
        if artist: meta['artist'].append( artist )
        if album: meta['album'].append( album )
        if tracknum: meta['tracknum'].append( tracknum )
        if year: meta['date'].append( year )
        if rate: meta['rate'].append( rate )

def GetMetadata( ftype, f ):

        meta = { 'artist' : [],
                 'album' : [],
                 'date' : [],
                 'tracknum' : [],
                 'song' : [],
                 'rate' : [] }

        if ftype == 'riff':
                return None

        if ftype == 'flac':
                GetFlacInfo( meta, f )

        if ftype == 'ogg':
                GetOggInfo( meta, f )

        GetID3Info( meta, f )

        if not meta['tracknum']:
                tracknum = ""
                for ch in os.path.basename( f ):
                        if ch.isdigit():
                                tracknum += ch
                        else:
                                break
                if tracknum:
                        meta['tracknum'].append( int( tracknum ))

        return meta

def DetermineFileType( f ):

        idtable = [ (('MPEG', 'layer III'), ('mp3')),
                        (('RIFF', 'PCM', 'Microsoft'), ('riff')),
                        (('Ogg', 'Vorbis'), ('ogg')) ]

        # 'file' misidentifies flac files as MP3's, so we use metaflac
        # to see if it IS a flac file first
        #
        is_flac = Popen( "metaflac --list %s" % f, shell=True, stdout=PIPE, stderr=PIPE ).wait() == 0

        if is_flac:
                ftype = 'flac'
        else:
                # now fall back to normal 'file' identification
                #
                p = Popen( "file %s" % f, shell=True, stdout=PIPE )

                info = p.communicate()[0]

                ftype = None

                for rule, tag in idtable:
                        ftype = tag
                        for str in rule:
                                if str not in info:
                                        ftype = None
                                        break
                        if ftype:
                                break

        return ftype

def Flac2Wav( src, dst ):
        return Popen( "flac123 --wav=%s %s" % (dst, src), shell=True, stdout=PIPE ).wait()

def Wav2Flac( src, dst, meta ):
        cmd = "flac"
        args = ""

        if meta:
                if meta['song']:
                        args += ' -T "title=%s"' % meta['song'][0]

                if meta['artist']:
                        args += ' -T "artist=%s"' % meta['artist'][0]

                if meta['album']:
                        args += ' -T "album=%s"' % meta['album'][0]

                if meta['date']:
                        args += ' -T "date=%s"' % meta['date'][0]

                if meta['tracknum']:
                        args += ' -T "tracknumber=%d"' % meta['tracknum'][0]

        if args:
                cmd += " %s %s %s" % (args, src, dst)
        else:
                cmd += " %s %s" % (src, dst)

        return Popen( cmd , shell=True, stdout=PIPE ).wait()

def Ogg2Wav( src, dst ):
        return Popen( "oggdec -o %s %s" % (dst, src), shell=True, stdout=PIPE ).wait()

def Wav2Ogg( src, dst, meta ):
        if best:
                cmd = "oggenc -q 10"
        else:
                cmd = "oggenc -q 7"
        args = ""

        if meta:
                if meta['song']:
                        args += ' -t "%s"' % meta['song'][0]

                if meta['artist']:
                        args += ' -a "%s"' % meta['artist'][0]

                if meta['album']:
                        args += ' -l "%s"' % meta['album'][0]

                if meta['date']:
                        args += ' -d "%s"' % meta['date'][0]

                if meta['tracknum']:
                        args += ' -N %d' % meta['tracknum'][0]

        if args:
                cmd += " %s -o %s %s" % (args, dst, src)
        else:
                cmd += " -o %s %s" % (dst, src)

        print cmd
        return Popen( cmd , shell=True, stdout=PIPE ).wait()

def Mp32Wav( src, dst ):
        return Popen( "mpg123 -w %s %s" % (dst, src), shell=True, stdout=PIPE ).wait()

def Wav2Mp3( src, dst, meta ):
        if best:
                cmd = "lame -V 0 -h "
        else:
                cmd = "lame -V 4 -h"
        args = ""

        if meta:
                if meta['song']:
                        args += ' --tt "%s"' % meta['song'][0]

                if meta['artist']:
                        args += ' --ta "%s"' % meta['artist'][0]

                if meta['album']:
                        args += ' --tl "%s"' % meta['album'][0]

                if meta['date']:
                        args += ' --ty "%s"' % meta['date'][0]

                if meta['tracknum']:
                        args += ' --tn %d' % meta['tracknum'][0]

        if args:
                cmd += " %s %s %s" % (args, src, dst)
        else:
                cmd += " %s %s" % (src, dst)

        return Popen( cmd , shell=True, stdout=PIPE ).wait()

def NewName( f, meta, type ):

        types = { 'riff':'wav', 'flac':'flac', 'ogg':'ogg', 'mp3':'mp3' }

        if type not in types.keys():
                return None

        if meta and meta['song']:
                if meta['tracknum']:
                        song = "".join( [ x for x in meta['song'][0].split(' ')] )
                        name = "%02d%s" % (meta['tracknum'][0], song)
                        trans = string.maketrans( '', '' )
                        return ".".join( [string.translate( name, trans, ':,\\/.!\"$%^&*()+=-\'_ ' ), types[type]] )
        else:
                name = os.path.splitext( os.path.basename( f ))[0]
                trans = string.maketrans( '', '' )
                return ".".join( [string.translate( name, trans, ':,\\/.!\"$%^&*()+=\' ' ), types[type]] )

def Transcode( src, dst, meta ):
        srcFmt, srcFile = src
        dstFmt, dstFile = dst

        decoders = { 'flac': Flac2Wav,
                        'ogg' : Ogg2Wav,
                        'mp3' : Mp32Wav,
                        'riff': None }

        encoders = { 'flac': Wav2Flac,
                        'ogg' : Wav2Ogg,
                        'mp3' : Wav2Mp3,
                        'riff': None }

        if os.path.isfile( dstFile ):
                raise "refusing to overwrite %s" % dstFile

        if not os.path.isdir( os.path.dirname( dstFile )):
                raise "directory %s does not exist" % os.path.dirname( dstFile )

        if srcFmt == dstFmt:
                # only a copy required
                #
                print "Copying %s to %s" % ( srcFile, dstFile )
                shutil.copyfile( srcFile, dstFile )
        else:
                handle, tempname = tempfile.mkstemp( '.wav', 'pyxcode', '/tmp' )
                os.close(handle)
                decode = decoders[srcFmt]
                encode = encoders[dstFmt]

                if not decode:
                        shutil.copyfile( srcFile, tempname )
                else:
                        decode( srcFile, tempname )

                if not encode:
                        shutil.copyfile( tempname, dstFile )
                else:
                        encode( tempname, dstFile, meta )

                os.remove(tempname)

        print "Converted %s" % os.path.basename( srcFile )

def Usage():
        print """
exec.py --odir=path --fmt=[flac|wav|riff|ogg|mp3] [--best] file [file...]
"""
        sys.exit(1)

if __name__ == "__main__":

        files = []
        odir = None
        fmt = None

        args = sys.argv[1:]
        for arg in args:
                if arg[0:2] == '--':
                        opt = arg[2:]
                        sep = opt.find('=')
                        if sep > 0:
                                key = opt[0:sep]
                                value = opt[sep+1:]
                                if key == 'odir':
                                        odir = value
                                elif key == 'fmt':
                                        if value == 'wav':
                                                value = 'riff'
                                        fmt = value
                                else:
                                        Usage()
                        else:
                                if opt == 'best':
                                        best = True
                                else:
                                        Usage()
                else:
                        files.append( arg )

        if not odir or not fmt:
                Usage()

        for f in files:
                if os.path.isfile( f ):
                        ftype = DetermineFileType( f )
                        if ftype:
                                meta = GetMetadata( ftype, f )

                                src = ( ftype, f )
                                dst = ( fmt, os.path.join( odir, NewName( f, meta, fmt ) ) )

                                ret = Transcode( src, dst, meta )
                                if ret:
                                        print ret
Received on Sun Feb 4 16:15:02 2007

This archive was generated by hypermail 2.1.8 : Sun Feb 04 2007 - 16:15:02 EET