NickVerri commited on
Commit
1c34fec
·
verified ·
1 Parent(s): efc7ad0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -18
app.py CHANGED
@@ -9,6 +9,7 @@ import json
9
  import requests
10
  import gc
11
  import math
 
12
  from datetime import timedelta
13
 
14
  # --- CRITICAL ENVIRONMENT FIXES ---
@@ -113,9 +114,11 @@ def generate_cmx_edl(edl_title, segments, source_name, fps=25):
113
  return "\n".join(edl_lines)
114
 
115
  def generate_xml(sequence_name, segments, source_name, fps=25):
116
- """Constructs a Final Cut Pro 7 XML with Video AND Audio Track 1."""
 
 
 
117
 
118
- # Use append mode to avoid copy-paste line break errors
119
  lines = []
120
  lines.append('<?xml version="1.0" encoding="UTF-8"?>')
121
  lines.append('<!DOCTYPE xmeml>')
@@ -123,7 +126,8 @@ def generate_xml(sequence_name, segments, source_name, fps=25):
123
  lines.append('<sequence>')
124
  lines.append(f'\t<name>{sequence_name}</name>')
125
  lines.append('\t<rate>')
126
- lines.append(f'\t\t<timebase>{fps}</timebase>')
 
127
  lines.append('\t</rate>')
128
  lines.append('\t<media>')
129
 
@@ -131,15 +135,15 @@ def generate_xml(sequence_name, segments, source_name, fps=25):
131
  lines.append('\t\t<video>')
132
  lines.append('\t\t\t<format>')
133
  lines.append('\t\t\t\t<samplecharacteristics>')
134
- lines.append(f'\t\t\t\t\t<rate><timebase>{fps}</timebase></rate>')
135
  lines.append('\t\t\t\t\t<width>1920</width>')
136
  lines.append('\t\t\t\t\t<height>1080</height>')
 
137
  lines.append('\t\t\t\t\t<pixelaspectratio>square</pixelaspectratio>')
138
  lines.append('\t\t\t\t</samplecharacteristics>')
139
  lines.append('\t\t\t</format>')
140
  lines.append('\t\t\t<track>')
141
 
142
- # --- VIDEO LOOP ---
143
  timeline_head_frames = 0
144
  for i, seg in enumerate(segments, 1):
145
  src_in_frames = seconds_to_frames(seg['src_start'], fps)
@@ -153,18 +157,18 @@ def generate_xml(sequence_name, segments, source_name, fps=25):
153
  lines.append(f'\t\t\t\t<clipitem id="clipitem-v-{i}">')
154
  lines.append(f'\t\t\t\t\t<name>{clip_note}</name>')
155
  lines.append(f'\t\t\t\t\t<duration>{duration_frames}</duration>')
156
- lines.append(f'\t\t\t\t\t<rate><timebase>{fps}</timebase></rate>')
157
  lines.append(f'\t\t\t\t\t<start>{tl_start}</start>')
158
  lines.append(f'\t\t\t\t\t<end>{tl_end}</end>')
159
  lines.append(f'\t\t\t\t\t<in>{src_in_frames}</in>')
160
  lines.append(f'\t\t\t\t\t<out>{src_out_frames}</out>')
 
161
 
162
- # File Reference
163
- lines.append(f'\t\t\t\t\t<file id="multicam_file">')
164
  lines.append(f'\t\t\t\t\t\t<name>{source_name}</name>')
165
- lines.append(f'\t\t\t\t\t\t<pathurl>file://localhost/placeholder/{source_name}</pathurl>')
166
- lines.append(f'\t\t\t\t\t\t<rate><timebase>{fps}</timebase></rate>')
167
- lines.append(f'\t\t\t\t\t\t<timecode><string>00:00:00:00</string></timecode>')
168
  lines.append(f'\t\t\t\t\t</file>')
169
  lines.append(f'\t\t\t\t</clipitem>')
170
 
@@ -184,9 +188,8 @@ def generate_xml(sequence_name, segments, source_name, fps=25):
184
  lines.append('\t\t\t\t\t<samplerate>48000</samplerate>')
185
  lines.append('\t\t\t\t</samplecharacteristics>')
186
  lines.append('\t\t\t</format>')
187
- lines.append('\t\t\t<track>') # Audio Track 1
188
 
189
- # --- AUDIO LOOP (Identical Timing to Video) ---
190
  timeline_head_frames = 0
191
  for i, seg in enumerate(segments, 1):
192
  src_in_frames = seconds_to_frames(seg['src_start'], fps)
@@ -200,16 +203,16 @@ def generate_xml(sequence_name, segments, source_name, fps=25):
200
  lines.append(f'\t\t\t\t<clipitem id="clipitem-a-{i}">')
201
  lines.append(f'\t\t\t\t\t<name>{clip_note}</name>')
202
  lines.append(f'\t\t\t\t\t<duration>{duration_frames}</duration>')
203
- lines.append(f'\t\t\t\t\t<rate><timebase>{fps}</timebase></rate>')
204
  lines.append(f'\t\t\t\t\t<start>{tl_start}</start>')
205
  lines.append(f'\t\t\t\t\t<end>{tl_end}</end>')
206
  lines.append(f'\t\t\t\t\t<in>{src_in_frames}</in>')
207
  lines.append(f'\t\t\t\t\t<out>{src_out_frames}</out>')
 
208
 
209
- # File Reference (Same ID as video)
210
- lines.append(f'\t\t\t\t\t<file id="multicam_file"/>')
211
 
212
- # SOURCE TRACK MAPPING (Use Source Track 1)
213
  lines.append('\t\t\t\t\t<sourcetrack>')
214
  lines.append('\t\t\t\t\t\t<mediatype>audio</mediatype>')
215
  lines.append('\t\t\t\t\t\t<trackindex>1</trackindex>')
@@ -276,7 +279,7 @@ st.markdown("""
276
  * Set your timeline FPS and transcription quality.
277
  * Junior Editor will transcribe and separate speakers. You can then instruct it to find engaging bits or construct a narrative.
278
  * It will create an EDL or XML to import back into your editing software (Resolve, Premiere).
279
- * **For Multicam Workflows:** Use the **XML** option in the sidebar and enter the **exact name** of your Multicam Sequence.
280
  """)
281
 
282
  st.divider()
 
9
  import requests
10
  import gc
11
  import math
12
+ import uuid
13
  from datetime import timedelta
14
 
15
  # --- CRITICAL ENVIRONMENT FIXES ---
 
114
  return "\n".join(edl_lines)
115
 
116
  def generate_xml(sequence_name, segments, source_name, fps=25):
117
+ """Constructs a Premiere-Safe Final Cut Pro 7 XML."""
118
+
119
+ # Generate a persistent ID for the source file
120
+ master_id = f"master-{uuid.uuid4()}"
121
 
 
122
  lines = []
123
  lines.append('<?xml version="1.0" encoding="UTF-8"?>')
124
  lines.append('<!DOCTYPE xmeml>')
 
126
  lines.append('<sequence>')
127
  lines.append(f'\t<name>{sequence_name}</name>')
128
  lines.append('\t<rate>')
129
+ lines.append(f'\t\t<timebase>{int(fps)}</timebase>')
130
+ lines.append(f'\t\t<ntsc>{str(fps % 1 != 0).upper()}</ntsc>')
131
  lines.append('\t</rate>')
132
  lines.append('\t<media>')
133
 
 
135
  lines.append('\t\t<video>')
136
  lines.append('\t\t\t<format>')
137
  lines.append('\t\t\t\t<samplecharacteristics>')
138
+ lines.append(f'\t\t\t\t\t<rate><timebase>{int(fps)}</timebase></rate>')
139
  lines.append('\t\t\t\t\t<width>1920</width>')
140
  lines.append('\t\t\t\t\t<height>1080</height>')
141
+ lines.append('\t\t\t\t\t<anamorphic>FALSE</anamorphic>')
142
  lines.append('\t\t\t\t\t<pixelaspectratio>square</pixelaspectratio>')
143
  lines.append('\t\t\t\t</samplecharacteristics>')
144
  lines.append('\t\t\t</format>')
145
  lines.append('\t\t\t<track>')
146
 
 
147
  timeline_head_frames = 0
148
  for i, seg in enumerate(segments, 1):
149
  src_in_frames = seconds_to_frames(seg['src_start'], fps)
 
157
  lines.append(f'\t\t\t\t<clipitem id="clipitem-v-{i}">')
158
  lines.append(f'\t\t\t\t\t<name>{clip_note}</name>')
159
  lines.append(f'\t\t\t\t\t<duration>{duration_frames}</duration>')
160
+ lines.append(f'\t\t\t\t\t<rate><timebase>{int(fps)}</timebase></rate>')
161
  lines.append(f'\t\t\t\t\t<start>{tl_start}</start>')
162
  lines.append(f'\t\t\t\t\t<end>{tl_end}</end>')
163
  lines.append(f'\t\t\t\t\t<in>{src_in_frames}</in>')
164
  lines.append(f'\t\t\t\t\t<out>{src_out_frames}</out>')
165
+ lines.append(f'\t\t\t\t\t<masterclipid>{master_id}</masterclipid>')
166
 
167
+ # File Reference (Clean for Premiere/Resolve)
168
+ lines.append(f'\t\t\t\t\t<file id="{master_id}">')
169
  lines.append(f'\t\t\t\t\t\t<name>{source_name}</name>')
170
+ lines.append(f'\t\t\t\t\t\t<rate><timebase>{int(fps)}</timebase></rate>')
171
+ lines.append(f'\t\t\t\t\t\t<timecode><string>00:00:00:00</string><displayformat>NDF</displayformat></timecode>')
 
172
  lines.append(f'\t\t\t\t\t</file>')
173
  lines.append(f'\t\t\t\t</clipitem>')
174
 
 
188
  lines.append('\t\t\t\t\t<samplerate>48000</samplerate>')
189
  lines.append('\t\t\t\t</samplecharacteristics>')
190
  lines.append('\t\t\t</format>')
191
+ lines.append('\t\t\t<track>')
192
 
 
193
  timeline_head_frames = 0
194
  for i, seg in enumerate(segments, 1):
195
  src_in_frames = seconds_to_frames(seg['src_start'], fps)
 
203
  lines.append(f'\t\t\t\t<clipitem id="clipitem-a-{i}">')
204
  lines.append(f'\t\t\t\t\t<name>{clip_note}</name>')
205
  lines.append(f'\t\t\t\t\t<duration>{duration_frames}</duration>')
206
+ lines.append(f'\t\t\t\t\t<rate><timebase>{int(fps)}</timebase></rate>')
207
  lines.append(f'\t\t\t\t\t<start>{tl_start}</start>')
208
  lines.append(f'\t\t\t\t\t<end>{tl_end}</end>')
209
  lines.append(f'\t\t\t\t\t<in>{src_in_frames}</in>')
210
  lines.append(f'\t\t\t\t\t<out>{src_out_frames}</out>')
211
+ lines.append(f'\t\t\t\t\t<masterclipid>{master_id}</masterclipid>')
212
 
213
+ lines.append(f'\t\t\t\t\t<file id="{master_id}"/>')
 
214
 
215
+ # SOURCE TRACK MAPPING
216
  lines.append('\t\t\t\t\t<sourcetrack>')
217
  lines.append('\t\t\t\t\t\t<mediatype>audio</mediatype>')
218
  lines.append('\t\t\t\t\t\t<trackindex>1</trackindex>')
 
279
  * Set your timeline FPS and transcription quality.
280
  * Junior Editor will transcribe and separate speakers. You can then instruct it to find engaging bits or construct a narrative.
281
  * It will create an EDL or XML to import back into your editing software (Resolve, Premiere).
282
+ * **For Multicam Workflows:** Use the **XML** option in the sidebar and enter the **exact name** of your Multicam Sequence. Uncheck "**Automatically import source clips into media pool**" when importing into DaVinci Resolve.
283
  """)
284
 
285
  st.divider()