-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoer.py
152 lines (119 loc) · 4.6 KB
/
doer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
from pydub import AudioSegment
segmentSize = 5000000
metadata = {}
file = open('data.txt', 'r')
cur = ''
nextIsFile = False
for line in file:
if line[0] in '/#*\\ \t': # ignore comments
continue
elif line[0] == '-':
print(line) # treat dashes as printed comments, e.g. a todo list
continue
line = line.rstrip()
if line.startswith('[') and line.endswith(']'):
cur = line[1:-1]
if not cur in metadata:
nextIsFile = True
metadata[cur] = {'timestamps': [], 'name': cur}
continue
if nextIsFile:
fileData = line.split(':')
if len(fileData) == 2:
nextIsFile = False
metadata[cur]['filename'] = fileData[0]
metadata[cur]['filetype'] = fileData[1]
else:
data = line.split(':')
if len(data) == 3:
metadata[cur]['timestamps'].append({'start': int(data[0]), 'end': int(data[2]), 'embed': data[1]})
elif len(data) == 4:
metadata[cur]['timestamps'].append({'start': int(data[0]), 'end': int(data[2]), 'embed': data[1], 'cutin': int(data[3])})
file.close()
errored = False
for k in metadata: # check for linking errors now rather than waiting for one to crop up halfway through the process
for cutaway in metadata[k]['timestamps']:
if cutaway['embed'] not in metadata:
print('Error: Cutaway to nonexistant track "' + cutaway['embed'] + '"')
errored = True # don't immediately exit so that all errors can be printed before terminating
if errored:
exit(1)
log = open('log.txt', 'w')
audio = AudioSegment.empty()
nextSegment = 0
def saveFragment():
global audio
global nextSegment
global segmentSize
if len(audio) > segmentSize:
audio[:segmentSize+1].export('outputs/output' + str(nextSegment) + '.wav', format="wav")
audio = audio[segmentSize+1:]
nextSegment = nextSegment + 1
else:
audio.export('outputs/output' + str(nextSegment) + '.wav', format="wav")
audio = AudioSegment.empty()
nextSegment = nextSegment + 1
def writeLog(stack):
global audio
global segmentSize
global nextSegment
if len(stack) == 0:
return # no need for an empty line, trust the process
log.write(str(len(audio) + nextSegment*segmentSize)) # i hope this isn't an off by one or i'm gonna be clowned so unbelievably hard
log.write(': ')
write = ''
for song in stack:
write = write + song + ' > '
write = write[:-3]
log.write(write)
log.write('\n')
print(str(len(audio) + nextSegment*segmentSize) + ': ' + write)
def handleSong(song, playingStack, cutin=0):
global audio # coming from lua, python is so stupid sometimes
global segmentSize
playingStack.append(song)
writeLog(playingStack)
song = metadata[song]
songAudio = AudioSegment.from_file(song['filename'], song['filetype']) #
if len(song['timestamps']) == 0:
audio = audio + songAudio
playingStack.pop()
writeLog(playingStack)
if len(audio) > segmentSize:
saveFragment()
return
i = -1
lastCutaway = -1
for cutaway in song['timestamps']:
i = i + 1
if cutaway['embed'] in playingStack:
continue # avoid recursion
elif cutaway['start'] < cutin:
continue # avoid doing cutaways in a cut part of the song
else:
if lastCutaway == -1: # if first cutaway, start from cutin point (defaults to beginning)
audio = audio + songAudio[cutin:cutaway['start']]
else: # otherwise, start from last dropoff point
if song['timestamps'][lastCutaway]['end'] <= cutaway['start']:
audio = audio + songAudio[song['timestamps'][lastCutaway]['end']:cutaway['start']]
if 'cutin' in cutaway:
handleSong(cutaway['embed'], playingStack, cutaway['cutin'])
else:
handleSong(cutaway['embed'], playingStack)
lastCutaway = i
if lastCutaway == -1:
audio = audio + songAudio[cutin:]
else:
audio = audio + songAudio[song['timestamps'][lastCutaway]['end']:]
playingStack.pop()
writeLog(playingStack)
if len(audio) > segmentSize:
saveFragment()
# main loop
for song in metadata:
handleSong(song, [])
log.write(str(len(audio) + nextSegment*segmentSize))
log.write(': END')
log.close()
while len(audio) > 0:
saveFragment()