Skip to content

Instantly share code, notes, and snippets.

@JoshStark
Created May 15, 2021 00:37
Show Gist options
  • Save JoshStark/257c7558ca7c6574b8abe431971df7e4 to your computer and use it in GitHub Desktop.
Save JoshStark/257c7558ca7c6574b8abe431971df7e4 to your computer and use it in GitHub Desktop.
Simple script to convert an InAudible CUE sheet into a flat chapters format
#!/usr/bin/env python
# encoding: utf-8
import os
import re
import argparse
import sys
class AudiobookCueSheet():
def __init__(self):
self.title = None
self.in_track = False
self.chapters = []
def set_data(self, data):
self.data = data.split("\n")
def parse(self):
for data_line in self.data:
if not self.title:
match = re.match('^FILE .(.*). (.*)$', data_line)
if match and not self.title:
self.title = match.group(1)
else:
track_match = re.match('^TRACK ([\d]+) .+$', data_line)
title_match = re.match('^\s*TITLE "?([^"]+)"?$', data_line)
index_match = re.match('^\s*INDEX .* (.*)$', data_line)
if track_match:
chapter = Chapter()
chapter.index = track_match.group(1)
self.chapters.append(chapter)
if title_match:
self.chapters[len(self.chapters) - 1].title = title_match.group(1)
if index_match:
self.chapters[len(self.chapters) - 1].timestamp = index_match.group(1)
def get_chapters(self):
return self.chapters
class Chapter():
def __init__(self):
self.title = None
self.timestamp = None
self.index = None
def format(self):
return "{} {}".format(self._as_hour_timestamp(), self.title)
def _as_hour_timestamp(self):
timestamp_match = re.match("(\d+):(\d+):(\d+)", self.timestamp)
minutes = int(timestamp_match.group(1))
seconds = int(timestamp_match.group(2))
millis = timestamp_match.group(3)
converted_hours = minutes // 60
converted_minutes_leftover = minutes % 60
return "{}:{}:{}.{}".format(str(converted_hours).rjust(2, "0"), str(converted_minutes_leftover).rjust(2, "0"), str(seconds).rjust(2, "0"), str(millis).ljust(3, "0"))
def _multiply_millis(self, millis):
if millis < 10:
return millis * 100
if millis < 100:
return millis * 10
return millis
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--file", help="path to cue file")
args = parser.parse_args()
cue_file = args.file
if not os.path.isfile(cue_file):
print("Cannot open file %s" % cue_file)
exit(2)
audiobook_cuesheet = AudiobookCueSheet()
with open(cue_file, "rb") as f:
audiobook_cuesheet.set_data(f.read().decode(sys.stdout.encoding))
audiobook_cuesheet.parse()
for chapter in audiobook_cuesheet.get_chapters():
print(chapter.format())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment