ERGS commited on
Commit
a27b4e4
1 Parent(s): 6d716d7

Upload 2 files

Browse files
Files changed (2) hide show
  1. EdAixml.py +441 -0
  2. usescript.py +4 -0
EdAixml.py ADDED
@@ -0,0 +1,441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import pickle
4
+ import numpy as np
5
+ from keras.models import load_model
6
+ from moviepy.editor import VideoFileClip
7
+ import librosa
8
+ from sklearn.preprocessing import LabelEncoder
9
+ import xml.etree.ElementTree as ET
10
+ import random
11
+
12
+ class VideoAudioFeatureExtractor:
13
+ def __init__(self, video_path, output_path):
14
+ self.video_path = video_path
15
+ self.output_path = output_path
16
+ self.num_frames = 15
17
+ self.height = 224
18
+ self.width = 224
19
+ self.channels = 6
20
+ self.audio_feature_dim = 20
21
+ self.num_actions = 3
22
+ self.classification_model = load_model("EdAi-gamestyle.h5")
23
+ with open("label_encoder.pkl", "rb") as f:
24
+ self.label_encoder = pickle.load(f)
25
+ with open("clip_items.pkl", "rb") as f:
26
+ self.all_clip_items = pickle.load(f)
27
+
28
+ def generate_clipitem_id(self, video_name, num_digits=10):
29
+ random_number = ''.join(random.choices('0123456789', k=num_digits))
30
+ return f"{video_name}{random_number}"
31
+
32
+ def combine_features(self, video_features, audio_features):
33
+ audio_features_resized = cv2.resize(audio_features, (self.height, self.width))
34
+ audio_features_reshaped = np.repeat(audio_features_resized[:, :, np.newaxis], 3, axis=2)
35
+ audio_features_reshaped = np.repeat(audio_features_reshaped[np.newaxis, :, :, :], self.num_frames, axis=0)
36
+ combined_features = np.concatenate([video_features, audio_features_reshaped], axis=-1)
37
+ return combined_features
38
+
39
+ def extract_audio(self, video_path):
40
+ clip = VideoFileClip(video_path)
41
+ audio = clip.audio
42
+ audio_signal = audio.to_soundarray(fps=48000)
43
+ audio_signal = audio_signal.astype(np.float32)
44
+ if len(audio_signal.shape) == 2:
45
+ audio_signal = librosa.to_mono(audio_signal.T)
46
+ return audio_signal
47
+
48
+ def process_audio(self, audio_signal_segment):
49
+ mfccs = librosa.feature.mfcc(y=audio_signal_segment, sr=48000, n_mfcc=self.audio_feature_dim)
50
+ mfccs_fixed_length = librosa.util.fix_length(mfccs, size=self.num_frames)
51
+ return mfccs_fixed_length.T
52
+
53
+ def preprocess_frame(self, frame):
54
+ frame_resized = cv2.resize(frame, (self.width, self.height))
55
+ frame_normalized = (frame_resized / 255.0).astype(np.float32)
56
+ return frame_normalized
57
+
58
+ def extract_clip(self, video, audio_features, decision):
59
+ start_frame = int(decision["in"])
60
+ end_frame = int(decision["out"])
61
+ video.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
62
+ clip_frames = []
63
+ for i in range(start_frame, end_frame, 2):
64
+ ret, frame = video.read()
65
+ if not ret:
66
+ break
67
+ frame_processed = self.preprocess_frame(frame)
68
+ clip_frames.append(frame_processed)
69
+ while len(clip_frames) < self.num_frames:
70
+ clip_frames.append(np.zeros((self.height, self.width, 3), dtype=np.float32))
71
+ clip_frames = np.array(clip_frames[:self.num_frames])
72
+ return clip_frames, audio_features
73
+
74
+ def create_audio_track(self, clip_item_ids, pan_value, link_ids, video_clip_items, video_file_elements):
75
+ track = ET.Element("track")
76
+ for idx, clipitem_id in enumerate(clip_item_ids):
77
+ clipitem_element = ET.Element("clipitem", id=clipitem_id)
78
+ video_clip_item = video_clip_items[idx]
79
+ in_value = video_clip_item['in']
80
+ out_value = video_clip_item['out']
81
+ start_value = video_clip_item['start']
82
+ end_value = video_clip_item['end']
83
+ ET.SubElement(clipitem_element, "name").text = video_clip_item['name']
84
+ ET.SubElement(clipitem_element, "duration").text = video_clip_item['duration']
85
+ rate_elem = ET.SubElement(clipitem_element, "rate")
86
+ ET.SubElement(rate_elem, "ntsc").text = "TRUE"
87
+ ET.SubElement(rate_elem, "timebase").text = "30"
88
+ ET.SubElement(clipitem_element, "in").text = in_value
89
+ ET.SubElement(clipitem_element, "out").text = out_value
90
+ ET.SubElement(clipitem_element, "start").text = start_value
91
+ ET.SubElement(clipitem_element, "end").text = end_value
92
+ ET.SubElement(clipitem_element, "masterclipid").text = os.path.basename(self.video_path)
93
+ sourcetrack = ET.SubElement(clipitem_element, "sourcetrack")
94
+ ET.SubElement(sourcetrack, "mediatype").text = "audio"
95
+ ET.SubElement(sourcetrack, "trackindex").text = str(idx + 1)
96
+ video_file_elem = video_clip_item.get("file")
97
+ if video_file_elem is not None:
98
+ ET.SubElement(clipitem_element, "file", id=video_file_elem.get("id"))
99
+ else:
100
+ ET.SubElement(clipitem_element, "file", id=os.path.basename(self.video_path).split('.')[0])
101
+ filter_elem = ET.SubElement(clipitem_element, "filter")
102
+ effect_elem = ET.SubElement(filter_elem, "effect")
103
+ ET.SubElement(effect_elem, "name").text = "Audio Levels"
104
+ ET.SubElement(effect_elem, "effectid").text = "audiolevels"
105
+ ET.SubElement(effect_elem, "effectcategory").text = "audiolevels"
106
+ ET.SubElement(effect_elem, "effecttype").text = "audiolevels"
107
+ ET.SubElement(effect_elem, "mediatype").text = "audio"
108
+ parameter_elem = ET.SubElement(effect_elem, "parameter")
109
+ ET.SubElement(parameter_elem, "name").text = "Level"
110
+ ET.SubElement(parameter_elem, "parameterid").text = "level"
111
+ ET.SubElement(parameter_elem, "valuemin").text = "0"
112
+ ET.SubElement(parameter_elem, "valuemax").text = "3.98109"
113
+ ET.SubElement(parameter_elem, "value").text = "1"
114
+ filter_elem = ET.SubElement(clipitem_element, "filter")
115
+ effect_elem = ET.SubElement(filter_elem, "effect")
116
+ ET.SubElement(effect_elem, "name").text = "Audio Pan"
117
+ ET.SubElement(effect_elem, "effectid").text = "audiopan"
118
+ ET.SubElement(effect_elem, "effectcategory").text = "audiopan"
119
+ ET.SubElement(effect_elem, "effecttype").text = "audiopan"
120
+ ET.SubElement(effect_elem, "mediatype").text = "audio"
121
+ parameter_elem = ET.SubElement(effect_elem, "parameter")
122
+ ET.SubElement(parameter_elem, "name").text = "Pan"
123
+ ET.SubElement(parameter_elem, "parameterid").text = "pan"
124
+ ET.SubElement(parameter_elem, "valuemin").text = "-1"
125
+ ET.SubElement(parameter_elem, "valuemax").text = "1"
126
+ ET.SubElement(parameter_elem, "value").text = str(pan_value)
127
+ for link_id in link_ids[idx]:
128
+ link_elem = ET.SubElement(clipitem_element, "link")
129
+ ET.SubElement(link_elem, "linkclipref").text = link_id
130
+ track.append(clipitem_element)
131
+ self.adjust_clipitem_start_end(track.findall('clipitem'))
132
+ return track
133
+
134
+ def create_clip_structure(self, video_name, video_path, total_duration):
135
+ clip = ET.Element("clip", id=video_name)
136
+ ET.SubElement(clip, "updatebehavior").text = "add"
137
+ ET.SubElement(clip, "name").text = video_name
138
+ ET.SubElement(clip, "duration").text = str(total_duration)
139
+ rate = ET.SubElement(clip, "rate")
140
+ ET.SubElement(rate, "ntsc").text = "TRUE"
141
+ ET.SubElement(rate, "timebase").text = "30"
142
+ ET.SubElement(clip, "in").text = "-1"
143
+ ET.SubElement(clip, "out").text = "-1"
144
+ ET.SubElement(clip, "masterclipid").text = video_name
145
+ ET.SubElement(clip, "ismasterclip").text = "TRUE"
146
+
147
+ # Logging info
148
+ logginginfo = ET.SubElement(clip, "logginginfo")
149
+ ET.SubElement(logginginfo, "scene")
150
+ ET.SubElement(logginginfo, "shottake")
151
+ ET.SubElement(logginginfo, "lognote")
152
+ ET.SubElement(logginginfo, "good").text = "FALSE"
153
+
154
+ # Labels
155
+ labels = ET.SubElement(clip, "labels")
156
+ ET.SubElement(labels, "label2")
157
+
158
+ # Comments
159
+ comments = ET.SubElement(clip, "comments")
160
+ ET.SubElement(comments, "mastercomment1")
161
+ ET.SubElement(comments, "mastercomment2")
162
+ ET.SubElement(comments, "mastercomment3")
163
+ ET.SubElement(comments, "mastercomment4")
164
+
165
+ # Media
166
+ media = ET.SubElement(clip, "media")
167
+ video = ET.SubElement(media, "video")
168
+ track = ET.SubElement(video, "track")
169
+ clipitem = ET.SubElement(track, "clipitem", id=f"{video_name}1")
170
+ ET.SubElement(clipitem, "name").text = video_name
171
+ ET.SubElement(clipitem, "duration").text = str(total_duration)
172
+ rate = ET.SubElement(clipitem, "rate")
173
+ ET.SubElement(rate, "ntsc").text = "TRUE"
174
+ ET.SubElement(rate, "timebase").text = "30"
175
+ ET.SubElement(clipitem, "in").text = "0"
176
+ ET.SubElement(clipitem, "out").text = str(total_duration)
177
+ ET.SubElement(clipitem, "start").text = "0"
178
+ ET.SubElement(clipitem, "end").text = str(total_duration)
179
+ ET.SubElement(clipitem, "pixelaspectratio").text = "Square"
180
+ ET.SubElement(clipitem, "anamorphic").text = "FALSE"
181
+ ET.SubElement(clipitem, "alphatype").text = "none"
182
+ ET.SubElement(clipitem, "masterclipid").text = video_name
183
+
184
+ # File
185
+ file_id = video_name.split('.')[0] # Extract filename without extension
186
+ file = ET.SubElement(clipitem, "file")
187
+ file.text = f'file id="{file_id}"' # Set the text of the <file> tag to the file ID without the extension
188
+ ET.SubElement(file, "name").text = video_name
189
+ ET.SubElement(file, "pathurl").text = f"file://localhost/{video_path}"
190
+ rate = ET.SubElement(file, "rate")
191
+ ET.SubElement(rate, "timebase").text = "30"
192
+ ET.SubElement(rate, "ntsc").text = "TRUE"
193
+ ET.SubElement(file, "duration").text = str(total_duration)
194
+ timecode = ET.SubElement(file, "timecode")
195
+ ET.SubElement(timecode, "string").text = "00:00:00:00"
196
+ ET.SubElement(timecode, "frame").text = "0"
197
+ ET.SubElement(timecode, "rate").text = "30"
198
+ ET.SubElement(timecode, "displayformat").text = "NDF"
199
+ media = ET.SubElement(file, "media")
200
+ video = ET.SubElement(media, "video")
201
+ audio = ET.SubElement(media, "audio")
202
+
203
+ # Audio
204
+ for i in range(2): # Assuming there are 2 audio tracks as per the example
205
+ track = ET.SubElement(audio, "track")
206
+ clipitem = ET.SubElement(track, "clipitem", id=f"{video_name}{i + 2}")
207
+ ET.SubElement(clipitem, "name").text = video_name
208
+ ET.SubElement(clipitem, "duration").text = str(total_duration)
209
+ rate = ET.SubElement(clipitem, "rate")
210
+ ET.SubElement(rate, "ntsc").text = "TRUE"
211
+ ET.SubElement(rate, "timebase").text = "30"
212
+ ET.SubElement(clipitem, "in").text = "0"
213
+ ET.SubElement(clipitem, "out").text = str(total_duration)
214
+ ET.SubElement(clipitem, "start").text = "0"
215
+ ET.SubElement(clipitem, "end").text = str(total_duration)
216
+ ET.SubElement(clipitem, "masterclipid").text = video_name
217
+ file_id = video_name.split('.')[0] # Extract filename without extension
218
+ file_elem = ET.SubElement(clipitem, "file", id=file_id)
219
+ ET.SubElement(file_elem, "name").text = video_name
220
+ ET.SubElement(file_elem, "pathurl").text = f"file://localhost/{video_path}"
221
+ sourcetrack = ET.SubElement(clipitem, "sourcetrack")
222
+ ET.SubElement(sourcetrack, "mediatype").text = "audio"
223
+ ET.SubElement(sourcetrack, "trackindex").text = str(i + 1)
224
+
225
+ return clip
226
+
227
+ def adjust_clipitem_start_end(self, clipitems):
228
+ last_end = 0
229
+ for clipitem in clipitems:
230
+ in_val = int(clipitem.find('in').text)
231
+ out_val = int(clipitem.find('out').text)
232
+ clipitem.find('start').text = str(last_end)
233
+ clipitem.find('end').text = str(last_end + (out_val - in_val))
234
+ last_end = int(clipitem.find('end').text)
235
+
236
+ def dict_to_xml(self, tag, dictionary):
237
+ attributes = dictionary.pop('attributes', {})
238
+ if tag == "clipitem" or tag == "file":
239
+ attributes["id"] = dictionary.pop("id", None)
240
+ for key, val in attributes.items():
241
+ if val is None:
242
+ attributes[key] = "none"
243
+ elem = ET.Element(tag, **attributes)
244
+ for key, val in dictionary.items():
245
+ if val is None:
246
+ val = "none"
247
+ if isinstance(val, dict):
248
+ child = self.dict_to_xml(key, val)
249
+ elem.append(child)
250
+ elif isinstance(val, list):
251
+ for item in val:
252
+ child = self.dict_to_xml(key, item)
253
+ elem.append(child)
254
+ else:
255
+ child = ET.Element(key)
256
+ child.text = str(val) if val is not None else "none"
257
+ elem.append(child)
258
+ return elem
259
+
260
+ def create_sequence_structure(self, video_name, total_duration):
261
+ sequence = ET.Element("sequence", id="Sequence 1")
262
+ ET.SubElement(sequence, "updatebehavior").text = "add"
263
+ ET.SubElement(sequence, "name").text = "Sequence 1"
264
+ ET.SubElement(sequence, "duration").text = str(total_duration)
265
+ rate = ET.SubElement(sequence, "rate")
266
+ ET.SubElement(rate, "ntsc").text = "TRUE"
267
+ ET.SubElement(rate, "timebase").text = "30"
268
+ timecode = ET.SubElement(sequence, "timecode")
269
+ rate_timecode = ET.SubElement(timecode, "rate")
270
+ ET.SubElement(rate_timecode, "ntsc").text = "TRUE"
271
+ ET.SubElement(rate_timecode, "timebase").text = "30"
272
+ ET.SubElement(timecode, "frame").text = "107891"
273
+ ET.SubElement(timecode, "source").text = "source"
274
+ ET.SubElement(timecode, "displayformat").text = "DF"
275
+ ET.SubElement(sequence, "in").text = "-1"
276
+ ET.SubElement(sequence, "out").text = "-1"
277
+ media = ET.SubElement(sequence, "media")
278
+ video = ET.SubElement(media, "video")
279
+ format_ = ET.SubElement(video, "format")
280
+ samplecharacteristics = ET.SubElement(format_, "samplecharacteristics")
281
+ ET.SubElement(samplecharacteristics, "width").text = "1920"
282
+ ET.SubElement(samplecharacteristics, "height").text = "1080"
283
+ ET.SubElement(samplecharacteristics, "pixelaspectratio").text = "Square"
284
+ ET.SubElement(samplecharacteristics, "anamorphic").text = "FALSE"
285
+ ET.SubElement(samplecharacteristics, "fielddominance").text = "none"
286
+ rate_sample = ET.SubElement(samplecharacteristics, "rate")
287
+ ET.SubElement(rate_sample, "ntsc").text = "TRUE"
288
+ ET.SubElement(rate_sample, "timebase").text = "30"
289
+ ET.SubElement(samplecharacteristics, "colordepth").text = "24"
290
+ track = ET.SubElement(video, "track")
291
+ return sequence, track, media
292
+
293
+ def process_video(self):
294
+ for video_path in [self.video_path]:
295
+ # Extract audio features
296
+ audio_signal = self.extract_audio(video_path)
297
+ audio_frame_features = self.process_audio(audio_signal)
298
+
299
+ # Extract video features
300
+ video = cv2.VideoCapture(video_path)
301
+ ret, frame = video.read()
302
+ if not ret:
303
+ print(f"Failed to read video: {video_path}")
304
+ continue
305
+ clip_frames = []
306
+ while len(clip_frames) < self.num_frames:
307
+ frame_processed = self.preprocess_frame(frame)
308
+ clip_frames.append(frame_processed)
309
+ ret, frame = video.read()
310
+ if not ret:
311
+ break
312
+ clip_frames = np.array(clip_frames[:self.num_frames])
313
+ video.release()
314
+
315
+ # Combine video and audio features for prediction
316
+ combined_features_for_prediction = self.combine_features(clip_frames, audio_frame_features)
317
+
318
+ # Make a prediction
319
+ prediction = self.classification_model.predict(
320
+ [np.array([combined_features_for_prediction]), np.array([audio_frame_features])])
321
+ predicted_label = self.label_encoder.inverse_transform([np.argmax(prediction)])[0]
322
+
323
+ # Retrieve clip items for the predicted label
324
+ if predicted_label in self.all_clip_items:
325
+ clip_items_for_predicted_label = self.all_clip_items[predicted_label]
326
+ print("Clip items for predicted label:", clip_items_for_predicted_label)
327
+
328
+ # Calculate the total duration
329
+ total_duration = sum([int(clip_item["duration"]) for clip_item in clip_items_for_predicted_label])
330
+
331
+ # Create the root element
332
+ root = ET.Element("xmeml", version="5")
333
+
334
+ # Create the project structure
335
+ project = ET.SubElement(root, "project")
336
+ ET.SubElement(project, "name").text = "Untitled Project 1"
337
+ children = ET.SubElement(project, "children")
338
+
339
+ # Create and append the bin element to children
340
+ bin_element = ET.Element("bin")
341
+ ET.SubElement(bin_element, "updatebehavior").text = "add"
342
+ ET.SubElement(bin_element, "name").text = "Custom Bins"
343
+ ET.SubElement(bin_element, "children") # Empty children element for the bin
344
+ children.append(bin_element)
345
+
346
+ # Define video_name_with_extension here
347
+ video_name_with_extension = os.path.basename(video_path)
348
+
349
+ # Append the clip structure directly to children (not inside bin)
350
+ clip_structure = self.create_clip_structure(video_name_with_extension, video_path,
351
+ total_duration) # <-- Added total_duration here
352
+ children.append(clip_structure)
353
+
354
+ # Append the sequence structure to children
355
+ sequence, track, media = self.create_sequence_structure(video_name_with_extension, total_duration)
356
+ children.append(sequence)
357
+
358
+ clip_item_ids = [] # List to store generated IDs
359
+ link_ids_list = [] # List to store link IDs for each clip item
360
+ video_file_elements = [] # List to store <file> elements for each video <clipitem>
361
+
362
+ for clip_item in clip_items_for_predicted_label:
363
+ # Generate three unique IDs: one for video and two for audio
364
+ video_clip_item_id = self.generate_clipitem_id(video_name_with_extension)
365
+ audio_clip_item_id_1 = self.generate_clipitem_id(video_name_with_extension)
366
+ audio_clip_item_id_2 = self.generate_clipitem_id(video_name_with_extension)
367
+
368
+ # Store the generated IDs
369
+ clip_item_ids.append(video_clip_item_id)
370
+ link_ids_list.append([video_clip_item_id, audio_clip_item_id_1, audio_clip_item_id_2])
371
+
372
+ clip_item['id'] = video_clip_item_id
373
+ clip_item['name'] = video_name_with_extension
374
+
375
+ # Convert the modified clip item dictionary to XML and append to track
376
+ clipitem_element = self.dict_to_xml("clipitem", clip_item)
377
+
378
+ # Remove all existing <link> elements from the video <clipitem>
379
+ for link in clipitem_element.findall("link"):
380
+ clipitem_element.remove(link)
381
+
382
+ # Modify the <file> section inside the <clipitem>
383
+ file_element = clipitem_element.find("file")
384
+ file_id_value = os.path.splitext(os.path.basename(video_path))[
385
+ 0] # Use the video name without extension
386
+ if file_element is not None:
387
+ file_element.set("id", file_id_value) # Set the 'id' attribute
388
+ file_element.text = None # Ensure there's no text inside the <file> element
389
+ else:
390
+ # If <file> element doesn't exist, create one with the 'id' attribute
391
+ ET.SubElement(clipitem_element, "file", id=file_id_value)
392
+
393
+ # Temporarily extract the <fielddominance> element
394
+ fielddominance_elem = clipitem_element.find("fielddominance")
395
+ if fielddominance_elem is not None:
396
+ clipitem_element.remove(fielddominance_elem)
397
+
398
+ # Add the correct <linkclipref> elements
399
+ link_elem_self = ET.SubElement(clipitem_element, "link")
400
+ ET.SubElement(link_elem_self, "linkclipref").text = video_clip_item_id
401
+ link_elem_audio1 = ET.SubElement(clipitem_element, "link")
402
+ ET.SubElement(link_elem_audio1, "linkclipref").text = audio_clip_item_id_1
403
+ link_elem_audio2 = ET.SubElement(clipitem_element, "link")
404
+ ET.SubElement(link_elem_audio2, "linkclipref").text = audio_clip_item_id_2
405
+
406
+ # Re-append the <fielddominance> element to the end
407
+ if fielddominance_elem is not None:
408
+ clipitem_element.append(fielddominance_elem)
409
+
410
+ track.append(clipitem_element)
411
+ # Call the adjust_clipitem_start_end function here
412
+ self.adjust_clipitem_start_end(track.findall('clipitem'))
413
+ # Extract the <file> element and store it in the video_file_elements list
414
+ file_element = clipitem_element.find("file")
415
+ if file_element is not None:
416
+ video_file_elements.append(file_element)
417
+
418
+ # Move the audio track creation outside the clip items loop
419
+ video_clip_items_list = clip_items_for_predicted_label
420
+ # Pass the video_file_elements list to the create_audio_track function
421
+ audio_track_left = self.create_audio_track([id_list[1] for id_list in link_ids_list], -1, link_ids_list,
422
+ video_clip_items_list, video_file_elements)
423
+ audio_track_right = self.create_audio_track([id_list[2] for id_list in link_ids_list], 1, link_ids_list,
424
+ video_clip_items_list, video_file_elements)
425
+
426
+ audio = ET.SubElement(media, "audio")
427
+ audio.append(audio_track_left)
428
+ audio.append(audio_track_right)
429
+
430
+ # Save the entire XML tree to a file after processing all clip items
431
+ output_path = os.path.join(os.path.dirname(video_path), f"{os.path.basename(video_path)}_predicted.xml")
432
+ tree = ET.ElementTree(root)
433
+ with open(output_path, 'wb') as f:
434
+ tree.write(f, encoding='utf-8', xml_declaration=True)
435
+ else:
436
+ print(f"Predicted label for {video_path}: {predicted_label} (No clip items found)")
437
+
438
+ # Example usage of the class
439
+ # extractor = VideoAudioFeatureExtractor("path_to_video.mp4", "output_path.xml")
440
+ # extractor.process_video()
441
+
usescript.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from EdAixml import VideoAudioFeatureExtractor
2
+
3
+ extractor = VideoAudioFeatureExtractor("D:\\myscripts\\Edits\\Gaming\\Minecraft\\2ndvideo\\2023-06-21 20-21-56.mp4", "D:\\myscripts\\Edits\\Gaming\\Minecraft\\2ndvideo\\2023-06-21 20-21-56.xml")
4
+ extractor.process_video()