例如cue和wav文件,用这个解析cue文件转换除独立的mp3文件, 并写上id3 tag。
to mp3:
#!/usr/bin/env python2.7
import subprocess as subp
import sys
import os
from os.path import splitext, basename
import random
import glob
records = []
filename = ""
album=''
alb_artist=''
codec = 'libmp3lame'
ffmpeg_exec = 'ffmpeg'
encodingList = ('utf-8', 'shift-jis', 'cp936')
filecontent = open(sys.argv[1]).read()
for enc in encodingList:
try:
lines = filecontent.decode(enc).split('\n')
encoding = enc
break
except UnicodeDecodeError as e:
if enc == encodingList[-1]:
raise e
else:
pass
for l in lines:
a = l.split()
if not a:
continue
if a[0] == "FILE":
filename = ' '.join(a[1:-1]).strip('\'"')
elif a[0]=='TRACK':
records.append({})
records[-1]['index'] = a[1]
elif a[0]=='TITLE':
if len(records)>0:
records[-1]['title'] = ' '.join(a[1:]).strip('\'"')
else:
album = ' '.join(a[1:]).strip('\'"')
elif a[0]=='INDEX' and a[1]=='01':
timea = a[2].split(':')
if len(timea) == 3 and int(timea[0]) >= 60:
timea.insert(0, str(int(timea[0])/60))
timea[1] = str(int(timea[1])%60)
times = '{0}.{1}'.format(':'.join(timea[:-1]), timea[-1])
records[-1]['start'] = times
elif a[0]=='PERFORMER':
if len(records)>1:
records[-1]['artist'] = ' '.join(a[1:]).strip('\'"')
else:
alb_artist = ' '.join(a[1:]).strip('\'"')
for i, j in enumerate(records):
try:
j['stop'] = records[i+1]['start']
except IndexError:
pass
if not os.path.isfile(filename):
tmpname = splitext(basename(sys.argv[1]))[0]+splitext(filename)[1]
if os.path.exists(tmpname):
filename = tmpname
del tmpname
else:
for ext in ('.ape', '.flac', '.wav', '.mp3'):
tmpname = splitext(filename)[0] + ext
if os.path.exists(tmpname):
filename = tmpname
break
if not os.path.isfile(filename):
raise IOError("Can't not find file: {0}".format(filename))
fstat = os.stat(filename)
atime = fstat.st_atime
mtime = fstat.st_mtime
records[-1]['stop'] = '0'
tmpfile = splitext(filename)[0] + str(random.randint(10000,90000)) + '.mp3'
try:
ret = subp.call([ffmpeg_exec, '-hide_banner', '-y', '-i', filename,
'-acodec', codec, '-q:a', '0', '-abr', '0',
'-compression_level', '0', tmpfile])
if ret != 0:
raise SystemExit('Converting failed.')
for i in records:
output = i['index'] +' - '+ i['title']+'.mp3'
commandline = [ffmpeg_exec, '-hide_banner',
'-y', '-i', tmpfile,
'-c', 'copy',
'-ss', i['start'], '-to', i['stop'],
'-metadata', u'title={0}'.format(i['title']),
'-metadata', u'artist={0}'.format(i.get('artist', '')),
'-metadata', u'performer={0}'.format(i.get('artist', '')),
'-metadata', u'album={0}'.format(album),
'-metadata', 'track={0}/{1}'.format(i['index'], len(records)),
'-metadata', u'album_artist={0}'.format(alb_artist),
'-metadata', u'composer={0}'.format(alb_artist),
'-metadata', 'encoder=Meow',
'-id3v2_version', '3', '-write_id3v1', '1',
output]
subp.call(commandline)
os.utime(output, (atime, mtime))
finally:
if os.path.isfile(tmpfile):
os.remove(tmpfile)
to m4a:
#!/usr/bin/env python2.7
import subprocess as subp
import sys
import os
from os.path import splitext
import random
import glob
import mediainfo
import re
remPtn = re.compile(u'^(\ufeff)?REM ')
records = []
filename = ""
album=''
alb_artist=''
genre=''
year=''
codec = 'libfdk_aac'
ffmpeg_exec = 'ffmpeg'
encodingList = ('utf-8','euc-kr', 'shift-jis', 'cp936', 'big5')
filecontent = open(sys.argv[1]).read()
for enc in encodingList:
try:
lines = filecontent.decode(enc).split('\n')
encoding = enc
break
except UnicodeDecodeError as e:
if enc == encodingList[-1]:
raise e
else:
pass
for l in lines:
if len(records) == 0 and remPtn.match(l):
l = remPtn.sub('', l)
a = l.split()
if not a:
continue
if len(records) == 0:
# if a[0] == "REM" and len(a) > 2:
# a.pop(0)
if a[0] == "FILE":
filename = ' '.join(a[1:-1]).strip('\'"')
elif a[0] == 'TITLE':
album = ' '.join(a[1:]).strip('\'"')
elif a[0]=='PERFORMER':
alb_artist = ' '.join(a[1:]).strip('\'"')
elif a[0] == 'GENRE':
genre = ' '.join(a[1:]).strip('\'"')
elif a[0] == 'DATE':
year = a[1]
elif a[0]=='TRACK':
records.append({})
records[-1]['index'] = a[1]
else:
if a[0]=='TRACK':
records.append({})
records[-1]['index'] = a[1]
elif a[0]=='TITLE':
records[-1]['title'] = ' '.join(a[1:]).strip('\'"')
elif a[0]=='INDEX' and a[1]=='01':
timea = a[2].split(':')
if len(timea) == 3 and int(timea[0]) >= 60:
timea.insert(0, str(int(timea[0])/60))
timea[1] = str(int(timea[1])%60)
times = '{0}.{1}'.format(':'.join(timea[:-1]), timea[-1])
records[-1]['start'] = times
elif a[0]=='PERFORMER':
records[-1]['artist'] = ' '.join(a[1:]).strip('\'"')
# print genre
# print year
# raise SystemExit
for i, j in enumerate(records):
try:
j['stop'] = records[i+1]['start']
except IndexError:
pass
if not os.path.isfile(filename):
for i in glob.glob(splitext(filename)[0] + '.*'):
if splitext(i)[1] in ('.ape', '.flac', '.wav', '.mp3'):
filename = i
break
if not os.path.isfile(filename):
raise IOError("Can't not find file: {0}".format(filename))
fstat = os.stat(filename)
atime = fstat.st_atime
mtime = fstat.st_mtime
#records[-1]['stop'] = '0'
tmpfile = splitext(filename)[0] + str(random.randint(10000,90000)) + '.m4a'
try:
ret = subp.call([ffmpeg_exec, '-hide_banner', '-y', '-i', filename,
'-acodec', codec, '-b:a', '320k','-profile:a', 'aac_low',
'-cutoff', '20000', '-movflags','faststart',
'-f','ipod',tmpfile])
if ret != 0:
raise SystemExit('Converting failed.')
tmpinfo = mediainfo.mediainfo(tmpfile)
records[-1]['stop'] = tmpinfo.get('duration', '0')
for i in records:
output = i['index'] +' - '+ i['title']+'.m4a'
commandline = [ffmpeg_exec, '-hide_banner',
'-y', '-i', tmpfile,
'-c', 'copy', '-movflags','faststart',
'-ss', i['start'], '-to', i['stop'],
'-metadata', u'title={0}'.format(i['title']),
'-metadata', u'date={0}'.format(year),
'-metadata', u'genre={0}'.format(genre),
'-metadata', u'artist={0}'.format(i.get('artist', '')),
'-metadata', u'album_artist={0}'.format(i.get('artist', '')),
'-metadata', u'performer={0}'.format(i.get('artist', '')),
'-metadata', u'album={0}'.format(album),
'-metadata', 'track={0}/{1}'.format(i['index'], len(records)),
'-metadata', u'album_artist={0}'.format(alb_artist),
'-metadata', u'composer={0}'.format(alb_artist),
'-metadata', 'encodedby=Meow',
'-metadata', 'tool=ffmpeg',
'-metadata', 'type=music',
'-f', 'ipod',
output]
subp.call(commandline)
os.utime(output, (atime, mtime))
finally:
if os.path.isfile(tmpfile):
os.remove(tmpfile)
to flac
#!/usr/bin/env python2.7
import subprocess as subp
import sys
import os
from os.path import splitext, basename
import random
import glob
records = []
filename = ""
album=''
alb_artist=''
codec = 'flac'
ffmpeg_exec = 'ffmpeg'
encodingList = ('utf-8', 'shift-jis', 'cp936')
filecontent = open(sys.argv[1]).read()
for enc in encodingList:
try:
lines = filecontent.decode(enc).split('\n')
encoding = enc
break
except UnicodeDecodeError as e:
if enc == encodingList[-1]:
raise e
else:
pass
for l in lines:
a = l.split()
if not a:
continue
if a[0] == "FILE":
filename = ' '.join(a[1:-1]).strip('\'"')
elif a[0]=='TRACK':
records.append({})
records[-1]['index'] = a[1]
elif a[0]=='TITLE':
if len(records)>0:
records[-1]['title'] = ' '.join(a[1:]).strip('\'"')
else:
album = ' '.join(a[1:]).strip('\'"')
elif a[0]=='INDEX' and a[1]=='01':
timea = a[2].split(':')
if len(timea) == 3 and int(timea[0]) >= 60:
timea.insert(0, str(int(timea[0])/60))
timea[1] = str(int(timea[1])%60)
times = '{0}.{1}'.format(':'.join(timea[:-1]), timea[-1])
records[-1]['start'] = times
elif a[0]=='PERFORMER':
if len(records)>1:
records[-1]['artist'] = ' '.join(a[1:]).strip('\'"')
else:
alb_artist = ' '.join(a[1:]).strip('\'"')
for i, j in enumerate(records):
try:
j['stop'] = records[i+1]['start']
except IndexError:
pass
if not os.path.isfile(filename):
tmpname = splitext(basename(sys.argv[1]))[0]+splitext(filename)[1]
if os.path.exists(tmpname):
filename = tmpname
del tmpname
else:
for ext in ('.ape', '.flac', '.wav', '.mp3'):
tmpname = splitext(filename)[0] + ext
if os.path.exists(tmpname):
filename = tmpname
break
if not os.path.isfile(filename):
raise IOError("Can't not find file: {0}".format(filename))
fstat = os.stat(filename)
atime = fstat.st_atime
mtime = fstat.st_mtime
records[-1]['stop'] = '0'
if filename.lower().endswith('.flac'):
tmpfile = filename
else:
tmpfile = splitext(filename)[0] + str(random.randint(10000,90000)) + '.flac'
try:
if filename != tmpfile:
ret = subp.call([ffmpeg_exec, '-hide_banner', '-y', '-i', filename,
'-acodec', codec,'-compression_level','12','-f','flac',tmpfile])
if ret != 0:
raise SystemExit('Converting failed.')
for i in records:
output = i['index'] +' - '+ i['title']+'.flac'
commandline = [ffmpeg_exec, '-hide_banner',
'-y', '-i', tmpfile,
'-c', 'copy',
'-ss', i['start'], '-to', i['stop'],
'-metadata', u'title={0}'.format(i['title']),
'-metadata', u'artist={0}'.format(i.get('artist', '')),
'-metadata', u'performer={0}'.format(i.get('artist', '')),
'-metadata', u'album={0}'.format(album),
'-metadata', 'track={0}/{1}'.format(i['index'], len(records)),
'-metadata', u'album_artist={0}'.format(alb_artist),
'-metadata', u'composer={0}'.format(alb_artist),
'-metadata', 'encoder=Meow',
'-write_id3v1', '1',
output]
subp.call(commandline)
os.utime(output, (atime, mtime))
finally:
if os.path.isfile(tmpfile):
os.remove(tmpfile)
os.exit(1)