Skip to content

Instantly share code, notes, and snippets.

@epochblue
Created August 2, 2021 12:00
Show Gist options
  • Save epochblue/70609ec25a4f535af2fa6b972ef47209 to your computer and use it in GitHub Desktop.
Save epochblue/70609ec25a4f535af2fa6b972ef47209 to your computer and use it in GitHub Desktop.
A simple Python script for splitting an audio file using ffmpeg and a set list.
#!/usr/bin/env python3
"""
Split an audio file based on the timestamps in a file containing set information.
Expected format for the setfile is:
HH:MM:SS Track #1
HH:MM:SS Track #2
HH:MM:SS Track #3
Note: "HH:MM:SS" is the timestamp in the file where the given track starts.
Artist and album information can be given to the script as well and metadata
will automatically be filled out for the generated files.
"""
import argparse
import itertools
import os
import subprocess
import sys
DEFAULT_ARTIST = 'Unknown Artist'
DEFAULT_ALBUM = 'Unknown Album'
def get_metadata(track_num, track, artist, album):
"""
Builds metadata args for basic tagging.
"""
metadata = {
'title': track,
'artist': artist,
'album_artist': artist,
'album': album,
'track': track_num,
}
return itertools.chain(*[('-metadata', f'{k}={v}') for k, v in metadata.items()])
def main(args):
lines = [l.strip() for l in args.setfile]
num_tracks = len(lines)
for track_num, line in enumerate(lines, start=1):
start, track = line.split(maxsplit=1)
_, ext = os.path.splitext(args.infile)
command = ['ffmpeg', '-i', args.infile, '-acodec', 'copy', '-ss', start]
if track_num < num_tracks:
end, _ = lines[track_num].split(maxsplit=1)
command.extend(['-to', end])
command.extend(get_metadata(track_num, track, args.artist, args.album))
command.append(f'{args.outdir}/{track_num:02d}-{track}{ext}')
try:
ret = subprocess.run(command, check=True, capture_output=True)
except subprocess.CalledProcessError as cpe:
error = cpe.stderr.decode("utf-8")
print(f'Error:\n{error}', file=sys.stderr)
return cpe.returncode
return 0
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--infile', '-i', required=True,
help='The audio file to split')
parser.add_argument('--outdir', '-o', required=True,
help='The directory to write split files to')
parser.add_argument('--setfile', '-s', type=argparse.FileType('r'), required=True,
help='The file containing set information')
parser.add_argument('--artist', default=DEFAULT_ARTIST,
help='The artist to use in the generated metadata')
parser.add_argument('--album', default=DEFAULT_ALBUM,
help='The album name to use in the generated metadata')
args = parser.parse_args()
if not os.path.exists(args.outdir):
os.mkdir(os.path.expanduser(args.outdir))
raise SystemExit(main(args))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment