/
Import_MagixVPX_EDL_02.py
581 lines (456 loc) · 21.2 KB
/
Import_MagixVPX_EDL_02.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
# * Imports a Magix VPX Edl into the Vegas Timeline
# *
# * Revision Date: Jan 15,2019
# * Version: 1.0
# * Copyright: Harold Linke
#
import clr
clr.AddReference('ScriptPortal.Vegas')
import ScriptPortal.Vegas
from ScriptPortal.Vegas import *
clr.AddReference('System.Windows.Forms')
import System.Windows.Forms
import os
pyVEGAS: Vegas
# List directories where missing media should be searched
searchDirList = ["F:\\data_archiv\\Videos1\\Original Videos", "E:\data_archiv\Video_Projekte\_all_video_projects", "E:\\MMserver_NAS3\\Musik"]
searchMissingMedia = True # set to TRUE if you want that VEGAS is looking for missing media
searchStringFilenameListStart = "Source Table Entries:"
searchStringFilenameListEnd = "Track"
searchStringTrackListStart = "Track"
searchStringTrackListEnd = "#Vol"
def check_filename(filename: str):
""" checks if the filename is correct and adapts it if necessary
Parameters:
filename - media filename
return:
string: updated filename
"""
# delete all invaild characters from filename
filename = filename.strip() # remove leading and training blanks
filename=filename.replace("\n","")
filename=filename.replace("\r","")
filename=filename.replace(">","")
filename=filename.replace("'"," ")
filename=filename.replace('"',' ')
filename = filename.strip() # remove leading and training blanks
#-----------------------------------------
# check if filename needs to be adapted to new naming convention
#
# e.g. old naming convention: " DV_D0017'20051022 16.44.03.avi "
# new naming convention: "20051022164403_D0017.avi"
#
#-----------------------------------------
testfilename = filename.lower()
test1 = testfilename.find("dv_") # test for old filenames of DV files and correct them
test2 = testfilename.find("d8_") # test for old filenames of DV files and correct them
test3 = testfilename.find("video_") # test for old filenames of files with video_xx and correct them
if test1 == 0 or test2 == 0 or test3 == 0:
filename_comp = filename.split(" ")
if len(filename_comp) >=2:
filename_descr = filename_comp[0]
filename_date = filename_comp[1]
filename_time = filename_comp[2]
filename_time_comp = filename_time.split(".")
filename = filename_date + filename_time_comp[0] + filename_time_comp[1] + filename_time_comp[2] + "_" + filename_descr + ".avi"
return filename
class EDLFile:
Filename = ""
File = None
fileIsOpen = False
lastLineRead = ""
filenamelist = [[0,"",0]] # list of filename items [id,filename,type]
trackListEnd = False
trackEventList = [[]]
timeFactor = 48
searchDirName = ""
searchFileList = []
def __init__(self):
self.trackListEnd = False
def openFile (self,newfilename):
""" open the edl file
Parameters:
newfilename - name of the file to open
return:
True: File is open
False: File could not be opened
Post condition:
text file with name newfilename is open for reading
"""
self.File = open(newfilename)
if (self.File != None):
self.fileIsOpen = True
self.filename = newfilename
else:
self.fileIsOpen = False
return self.fileIsOpen
def closeFile(self):
""" close the edl file
Parameters:
none
return:
none
Pre condition
file was open for reading
Post condition:
text file with name newfilename is closed
"""
self.File.close()
def readNextNELine(self):
""" read next not empty line from edl file
Parameters:
none
return:
String: next not empty line from edl file
Pre condition
file was open for reading
Post condition:
file read pointer points to begin of line after the read line
"""
line = self.File.readline()
if line:
while line =="" or line == "\n":
line = self.File.readline()
if line == None:
line = ""
break
return line
def findStartEventFilenameList(self):
""" find the start of the event filename list in the edl file
Parameters:
none
return:
Bool: True - start of the event filename list in the edl file found
Pre condition
file was open for reading
Post condition:
file read pointer points to begin of event filename list
"""
line=self.readNextNELine()
self.lastLineRead = line
while line !="":
if searchStringFilenameListStart in line:
return True
line=self.readNextNELine()
return False
def findNextEventFilename(self):
""" find the next event filename in the edl file
Parameters:
none
return:
Bool: True - event filename list continues
False - end of event file name list found
Pre condition
file was open for reading
file read pointer points to lines in event file list (findStartEventFilenameList was executed before)
Post condition:
file read pointer points to end of event filename list and the begin of the Track list
lastLineRead contains the last line read - needed at the end of the list, as this line starts the "Track" list
"""
line=self.readNextNELine()
self.lastLineRead = line
if line != "":
if line.find(searchStringFilenameListEnd) == 0: # "Track" at start of line
return False
else:
itemstrings = line.split('"') # 1: id 2: filename 3:eventtype (Video,Audio)
id = int(itemstrings[0])
filenameelem=[id,itemstrings[1],itemstrings[2]]
self.filenamelist.append(filenameelem)
return True
def createEventFilenameList(self):
""" create the event filename list from the edl file
Parameters:
none
return:
none
Pre condition
file was open for reading
file read pointer points to lines before the event file list
Post condition:
file read pointer points to end of event filename list and the begin of the Track list
lastLineRead contains the last line read - needed at the end of the list, as this line starts the "Track event list
filenamelist contains the complete list of all mediafiles used in the edl file
"""
nextLine = self.findStartEventFilenameList()
while nextLine:
nextLine = self.findNextEventFilename()
return
def searchFile(self,filePathName):
""" search File
Parameters:
filePathName: Path and name of the file to search
when the file was not found and searchMissingMedia = True the procedure looks in all subdirectories of the directories specified in searchDirList
return:
original filePathName or updated filePathName with new path
"" when file was not found
Pre condition
searchDirName and searchFileList contain the directry name and the file list of the last found filename or None
Post condition:
searchDirName and searchFileList contain the directry name and the file list of the found filename
"""
fname = os.path.basename(filePathName)
if os.path.isfile(filePathName):
return filePathName
elif searchMissingMedia and filePathName !="":
fname = os.path.basename(filePathName)
if fname.lower() in (name.lower() for name in self.searchFileList): # search in last directoy found
return os.path.join(self.searchDirName, fname)
for rootDir in searchDirList:
print ("Search for ", fname, " in ", rootDir)
for lookupDirName,subdirList, self.searchFileList in os.walk(rootDir):
if fname.lower() in (name.lower() for name in self.searchFileList):
self.searchDirName = lookupDirName
return os.path.join(self.searchDirName, fname)
print (fname, " not found")
openFileDialog2 = System.Windows.Forms.OpenFileDialog();
openFileDialog2.Filter = "All files (*.*)|*.*";
openFileDialog2.FilterIndex = 1;
openFileDialog2.RestoreDirectory = True;
openFileDialog2.AddExtension = True;
# openFileDialog2.InitialDirectory = self.searchDirName;
openFileDialog2.FileName = fname
openFileDialog2.Title = "Select File and Directory for : " + filePathName;
if (openFileDialog2.ShowDialog() == System.Windows.Forms.DialogResult.OK):
print (fname , "->", openFileDialog2.FileName)
return openFileDialog2.FileName
return filePathName
def checkFileList(self):
""" check if file exists
Parameters:
filePathName: Path and name of the file to check
when the file was not found and searchMissingMedia = True the procedure looks in all subdirectories of the directories specified in searchDirList
return:
original filePathName or updated filePathName with new path
"" when file was not found
Pre condition
searchDirName and searchFileList contain the directry name and the file list of the last found filename or None
Post condition:
searchDirName and searchFileList contain the directry name and the file list of the found filename
"""
for i, filePathName in enumerate(self.filenamelist):
self.filenamelist[i][1] = self.searchFile(filePathName[1]) # search for file
return
def findStartTrackList(self):
""" find the start of a track list in the edl file
Parameters:
none
return:
Bool: True - track list start found
False - no tracklist found anymore
Pre condition
file was open for reading
file read pointer points after the first line in the track event list with the "Track" keyword
lastLineRead contains the last line read with the "Track" keyword
Post condition:
file read pointer points to first event in the event list for the track
lastLineRead contains the last line read
"""
if self.lastLineRead.find(searchStringFilenameListEnd) == 0: # "Track" at start of line
line=self.readNextNELine()
self.lastLineRead = line
#skip the source and the header lines
if line.find("#Source") == 0:
line=self.readNextNELine()
self.lastLineRead = line
if line.find("#------") == 0:
return True
return False
def findNextTrackEvent(self):
""" find the next event in the track list in the edl file
Parameters:
none
return:
Bool: True - next event found
False - end of event list for this track reached
Pre condition
file was open for reading
file read pointer points on the first line in the track event list
lastLineRead contains the last line read
Post condition:
file read pointer points to next event in the event list for the track
lastLineRead contains the last line read
the event properties read from the edl file are appended to the trackEventList
"""
line=self.readNextNELine()
self.lastLineRead = line
if line != "":
if line.find(searchStringTrackListStart) == 0 or line.find(searchStringTrackListEnd) == 0: # # "Track" at start of line "#Volume" at start of line - end of tracklist
return False
else:
itemstrings = line.split() # 0: id 1:track 2:Play-In 3: Play-Out 4:Record-In 5:Record-Out 6:Vol 7:MT 8:LK 9:FadeIn 10:% 11:CurveType 12:FadeOut 13:% 14:CurveType 15:Name
# the definition of play-in play-out record-in and record out in the edl is different than in other edl files
# play and record need to be exchanged to be standard complient
# correct definition: 0: File-id 1:tracknumber 2:Record-In 3: Record-Out 4:Play-In 5:Play-Out 6:Vol 7:MT 8:LK 9:FadeIn 10:% 11:CurveType 12:FadeOut 13:% 14:CurveType 15:Name
if len(itemstrings)>12:
fileProperties = self.filenamelist[int(itemstrings[0])]
trackType = "Video"
if "AUDIO" in fileProperties[2]:
trackType = "Audio"
P_MediaType = trackType
P_Filename = fileProperties[1]
P_Tracknumber = int(itemstrings[1])
P_trackName = "Track "+itemstrings[1]
P_RecordIn = int(itemstrings[2])/self.timeFactor
P_PlayIn = int(itemstrings[4])/self.timeFactor
P_Length = int(itemstrings[5])/self.timeFactor - P_PlayIn
P_FadeIn = int(itemstrings[9])/self.timeFactor
P_FadeOut = int(itemstrings[12])/self.timeFactor
eventProperties = [P_MediaType, P_Filename, P_Tracknumber, P_trackName, P_RecordIn, P_PlayIn, P_Length, P_FadeIn, P_FadeOut]
self.trackEventList.append(eventProperties)
return True
else:
return False
def getTrackEventList(self):
""" get the track event list from the edl file
Parameters
none
return:
trackEventList with all events and all tracks defined in the edl file
Pre condition
file was open for reading
file read pointer points the start of the edl file
Post condition:
file read pointer points to theend event list for the last track
lastLineRead contains the last line read
all event properties read from the edl file are appended to the trackEventList for all tracks
"""
trackEventList = []
while self.findStartTrackList():
while self.findNextTrackEvent():
pass
return self.trackEventList
#*** Class EDLFile end *********
def checkFileExists(filePathName):
""" check if file exists
Parameters:
filePathName: Path and name of the file to check
when the file was not found
return:
original filePathName or updated filePathName with new path
"" when file was not found
"""
fname = os.path.basename(filePathName)
if os.path.isfile(filePathName):
return filePathName
else:
return ""
def addTrackEvent(eventProp, track, mediaType,searchFile):
""" add a video event to the track
Parameters:
eventProp: list of event properties
0:Audio/Video
1:pathfilename
2:Track number
3:Track name
4:RecordIn (in ms) - start of clip on timeline
5:PlayIn (in ms) - start of event relativ to media start
6:Length (in ms) - total length of Clip (includng fades and dissolve)
7:FadeIn (in ms) - length of FadeIn
8:FadeOut (in ms) - length of FadeOut
track: track, to which the event should be added
mediaType: Video or Audio
return:
none
Pre condition
track exists in VEGAS timeline
Post condition:
new video event with properties defined in eventProp is added to the track in the timeline
if the mediafile is not existing dummy media is create
"""
mediafilename = eventProp[1]
if mediafilename != "":
if track.MediaType != mediaType:
print("ERROR:", track.Name, ":", mediaType , "not valid")
else:
RecordIn = Timecode.FromMilliseconds(eventProp[4]) # RecIn
PlayIn = Timecode.FromMilliseconds(eventProp[5]) # PlayIn
eventLength = Timecode.FromMilliseconds(eventProp[6])
FadeIn = Timecode.FromMilliseconds(eventProp[7]) # FadeIn
FadeOut = Timecode.FromMilliseconds(eventProp[8]) # FadeOut
curveType = CurveType.Slow # Standard Curve type for FadeIn, Fadeout
checkedmediafilename = ""
if searchFile:
checkedmediafilename = checkFileExists(mediafilename)
if checkedmediafilename == "":
media = Media.CreateInstance(pyVEGAS.Project,mediafilename)
mediastream = Media.CreateOfflineStream(media,mediaType)
maxlength = eventLength
else:
media = Media.CreateInstance(pyVEGAS.Project,checkedmediafilename)
if mediaType == MediaType.Video:
mediastream = media.GetVideoStreamByIndex(0)
else:
mediastream = media.GetAudioStreamByIndex(0)
maxlength = media.Length
if mediastream != None:
if mediaType == MediaType.Video:
Event = track.AddVideoEvent(RecordIn,maxlength) #add complete VideoClip on the timeline
else:
Event = track.AddAudioEvent(RecordIn,maxlength) #add complete AudioClip on the timeline
take = Event.AddTake(mediastream) # add mediastream to event
dStart = Event.Start + PlayIn
Event.AdjustStartLength(dStart, eventLength, True) # cut begin and/or end of Clip
Event.Start = RecordIn # move clip to RecordIn timeline position
Event.FadeIn.Curve=curveType
Event.FadeOut.Curve=curveType
Event.FadeIn.Length = FadeIn
Event.FadeOut.Length = FadeOut
return
def createTimeline(trackEventList):
""" creates the timeline from the trackEventList entries
Parameters:
trackEventList
return:
none
Pre condition
trackEventList contains all events from the edl file
Post condition:
all tracks and events defined in the edl file are added to the timeline
"""
lastTrackNo = 0
# print(trackEventList)
for eventFileProp in trackEventList:
searchFile = True
if eventFileProp != []:
curTrackNo = eventFileProp[2]
if curTrackNo != lastTrackNo:
# new track
trackName = eventFileProp[3]
print ("Track No:", curTrackNo)
lastTrackNo = curTrackNo
if eventFileProp[0] == "Audio":
mediaType = MediaType.Audio
eventTrack = pyVEGAS.Project.AddAudioTrack()
else:
mediaType = MediaType.Video
eventTrack = pyVEGAS.Project.AddVideoTrack()
if eventFileProp[0] != "Video" and eventFileProp[0] != "Audio":
searchFile = False
eventTrack.Name = trackName
addTrackEvent(eventFileProp, eventTrack, mediaType,searchFile)
def FromVegas (myVegas: Vegas):
global pyVEGAS
pyVEGAS = myVegas
edlfile = EDLFile()
openFileDialog1 = System.Windows.Forms.OpenFileDialog();
openFileDialog1.Filter = "Magix VPX EDL(*.edl)|*.edl|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 1;
openFileDialog1.RestoreDirectory = True;
openFileDialog1.AddExtension = True;
# openFileDialog1.InitialDirectory = "\\VEGASPython";
openFileDialog1.Title = "Load Magix VPX EDL";
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK):
if edlfile.openFile(openFileDialog1.FileName):
print("Create Filename list")
edlfile.createEventFilenameList()
print("Filename list created")
print("Check Files")
edlfile.checkFileList()
print("Create Track Event list")
trackEventList = edlfile.getTrackEventList()
edlfile.closeFile()
print("Track Event list created")
print("Create Timeline")
createTimeline(trackEventList)
print("Timeline created")