Skip to content

Instantly share code, notes, and snippets.

@quantixed
Forked from mervick/cue_to_flac.py
Last active November 25, 2023 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quantixed/95bb5cd216f37fef10c0b989ec961d4a to your computer and use it in GitHub Desktop.
Save quantixed/95bb5cd216f37fef10c0b989ec961d4a to your computer and use it in GitHub Desktop.
CUE splitter using ffmpeg (to flac)
#!/usr/bin/python3
import argparse
import os
import subprocess
def main():
parser = argparse.ArgumentParser(description='Split flac file using cue')
parser.add_argument('cue', type=str, help='path to cue file')
parser.add_argument('--cover', type=str, help='path to cover image')
parser.add_argument('--out', type=str, help='output directory')
args = parser.parse_args()
cue_file = args.cue
cover = args.cover
if cue_file is None:
parser.print_help()
return
d = open(cue_file).read().splitlines()
dirpath = os.path.dirname(cue_file)
outpath = dirpath if args.out is None else args.out
if not os.path.isdir(outpath):
os.mkdir(outpath, 0o777)
general = {}
tracks = []
current_file = None
for line in d:
if line.startswith('REM GENRE '):
general['genre'] = ' '.join(line.split(' ')[2:]).replace('"', '')
if line.startswith('REM DATE '):
general['date'] = ' '.join(line.split(' ')[2:])
if line.startswith('PERFORMER '):
general['artist'] = ' '.join(line.split(' ')[1:]).replace('"', '')
if line.startswith('TITLE '):
general['album'] = ' '.join(line.split(' ')[1:]).replace('"', '')
if line.startswith('FILE '):
current_file = ' '.join(line.split(' ')[1:-1]).replace('"', '')
current_file = os.path.join(dirpath, current_file)
if line.startswith(' TRACK '):
track = general.copy()
track['track'] = int(line.strip().split(' ')[1], 10)
tracks.append(track)
if line.startswith(' TITLE '):
tracks[-1]['title'] = ' '.join(line.strip().split(' ')[1:]).replace('"', '')
if line.startswith(' PERFORMER '):
tracks[-1]['artist'] = ' '.join(line.strip().split(' ')[1:]).replace('"', '')
if line.startswith(' INDEX 01 '):
t = list(map(int, ' '.join(line.strip().split(' ')[2:]).replace('"', '').split(':')))
tracks[-1]['start'] = 60 * t[0] + t[1] + t[2] / 100.0
for i in range(len(tracks)):
if i != len(tracks) - 1:
tracks[i]['duration'] = tracks[i + 1]['start'] - tracks[i]['start']
# remove forward slash from track['title'] if it exists
for track in tracks:
if '/' in track['title']:
track['title'] = track['title'].replace('/', '')
for track in tracks:
out_file = os.path.join(outpath, '%.2d. %s.flac' % (track['track'], track['title']))
metadata = {
'artist': track['artist'],
'title': track['title'],
'album': track['album'],
'track': str(track['track']) + '/' + str(len(tracks))
}
if 'genre' in track:
metadata['genre'] = track['genre']
if 'date' in track:
metadata['date'] = track['date']
cmd = 'ffmpeg'
cmd += ' -i "%s"' % current_file
if cover is not None:
cmd += ' -i "%s" -map 0:a -map 1' % cover
cmd += ' -metadata:s:v title="Album cover"' + \
' -metadata:s:v comment="Cover (front)" -disposition:v attached_pic'
cmd += ' -ss %.2d:%.2d:%.2d' % (track['start'] / 60 / 60, track['start'] / 60 % 60, int(track['start'] % 60))
if 'duration' in track:
cmd += ' -t %.2d:%.2d:%.2d' % (track['duration'] / 60 / 60, track['duration'] / 60 % 60, int(track['duration'] % 60))
cmd += ' ' + ' '.join('-metadata %s="%s"' % (k, v) for (k, v) in metadata.items())
cmd += ' "%s"' % out_file
print(cmd)
subprocess.call(cmd, shell=True)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment