Here's a (windows) script …
Maybe someone finds it interesting: I have created a script, too. It also controls ffmpeg avconv. It’s Python 2. It can split a media file (including opus) into parts of a given length. Alternatively, it takes a cuesheet (refering to one media file with multiple tracks) and extract the splitpoints from there.
Please note that there is no awesome error checking or the like. Also I don’t know what happens when title or artist string contains by chance e.g. "INDEX" or "TITLE". But to me, with "sweet-tempered" cuesheets, it’s doing its job.
I’m running it under Linux. I don’t know why it shouldn’t run under Win, as long as the shell execution of ffmpeg is similar.
#!/usr/bin/env python
"""Script in order to split a media file in smaller parts. Either in equal sized
parts with given length or in induvidual sized parts as stated by a cuesheet."""
import subprocess
import re
import math
from optparse import OptionParser
length_regexp = 'Duration: (\d{2}):(\d{2}):(\d{2})\.\d+,'
cue_reffile_regexp = 'FILE\s"(.*)"'
cue_index_regexp = 'INDEX\s01\s(\d{2}):(\d{2}):(\d{2})'
cue_title_regexp = r'TITLE\s"(.*)"'
re_length = re.compile(length_regexp)
re_cue_reffile = re.compile(cue_reffile_regexp)
re_cue_index = re.compile(cue_index_regexp)
re_cue_title = re.compile(cue_title_regexp, re.MULTILINE)
splitbin = "ffmpeg"
splitbin = "avconv"
def main():
(filename, split_length) = parse_options()
if split_length <= 0:
# Cuesheet operation (individual split lengths)
cuefile = open (filename, "U")
cue=cuefile.read ()
cuefile.close ()
filename = re_cue_reffile.search(cue).group(1)
#This finds only the first FILE; there should be only one FILE per cuesheet for this script being and working reasonable.
cue_tracks="\n".join((cue.split("FILE")[1]).split("\n")[1:])
cue_tracks=cue_tracks.split(" TRACK ")[1:]
split_points=[]
try:
for t in cue_tracks:
s=re_cue_index.search(t)
split_points.append((re_cue_title.search(t).group(1), int(s.group(1))*60 + int(s.group(2)) + float(s.group(3))/75))
except AttributeError:
split_points = [(None, int(indx.group(1))*60 + int(indx.group(2)) + float(indx.group(3))/75) for indx in re_cue_index.finditer(cue)]
equal = False
else:
equal = True
output = subprocess.Popen(splitbin+" -i '"+filename+"' 2>&1 | grep 'Duration'",
shell = True,
stdout = subprocess.PIPE
).stdout.read()
print output
matches = re_length.search(output)
if matches:
video_length = int(matches.group(1)) * 3600 + \
int(matches.group(2)) * 60 + \
int(matches.group(3))
print "Video length in seconds: "+str(video_length)
else:
print "Can't determine video length."
raise SystemExit
tmp=filename.split(".")
filenamebase = ".".join(tmp[:-1])
filenameext = tmp[-1]
if equal:
split_count = int(math.ceil(video_length/float(split_length)))
if(split_count == 1):
print "Video length is less then the target split length."
raise SystemExit
split_cmd = splitbin + " -i '"+filename+"' -vcodec copy "
for n in range(0, split_count):
split_str = ""
if n == 0:
split_start = 0
else:
split_start = split_length * n
split_str += " -ss "+str(split_start)+" -t "+str(split_length) + \
" '"+filenamebase + "-" + str(n) + "." + filenameext + \
"'"
print "About to run: "+split_cmd+split_str
output = subprocess.Popen(split_cmd+split_str, shell = True, stdout =
subprocess.PIPE).stdout.read()
else:
if(len (split_points) <= 1):
print "There aren't at least two indices in cuefile."
raise SystemExit
split_cmd = splitbin + " -i '"+filename+"' -codec copy " # Enable audio, too
n = 1
split_points.append(("",-1))
split_start = split_points [0][1]
name = split_points [0][0]
for split_end in split_points[1:]:
try:
neuname = split_end [0]
except NameError:
neuname = ""
split_end=split_end[1]
split_str = " -ss "+str(split_start)+((" -t "+str(split_end - split_start)) if split_end != -1 else "") + \
" '"+filenamebase + "-" + str(n) + ("-" + name if name!=None else "") + "." + filenameext + \
"'" #Omit -t when last piece will be created
print "About to run: "+split_cmd+split_str
output = subprocess.Popen(split_cmd+split_str, shell = True, stdout =
subprocess.PIPE).stdout.read()
n += 1
split_start = split_end
name=neuname
def parse_options():
parser = OptionParser()
parser.add_option("-f", "--file",
dest = "filename",
help = "file to split, for example sample.avi",
type = "string",
action = "store"
)
parser.add_option("-s", "--split-size",
dest = "split_size",
help = "split or chunk size in seconds, for example 10; if 0 is given, -f refers to a cuefile",
type = "int",
action = "store"
)
(options, args) = parser.parse_args()
if options.filename and (options.split_size != None):
return (options.filename, options.split_size)
else:
parser.print_help()
raise SystemExit
if __name__ == '__main__':
try:
main()
except Exception, e:
print "Exception occured running main():"
print str(e)
The cuesheet is like the one proposed by, AFAIR, CDRWIN.
FILE "music.opus" WAVE
TRACK 01 AUDIO
TITLE "Track title A"
INDEX 00 00:00:00
INDEX 01 00:00:20
TRACK 02 AUDIO
TITLE "Track title B"
INDEX 01 05:43:21
…
HTH – Peter