Update app.py
Browse files
app.py
CHANGED
|
@@ -182,9 +182,7 @@ def generate_xml(sequence_name, segments, source_name, fps=25, start_offset=0.0)
|
|
| 182 |
src_start_val = float(seg.get('src_start', seg.get('start', 0.0)))
|
| 183 |
src_end_val = float(seg.get('src_end', seg.get('end', 0.0)))
|
| 184 |
|
| 185 |
-
#
|
| 186 |
-
# In XML, IN and OUT refer to the absolute zero-based frame of the media file.
|
| 187 |
-
# The <timecode> block tells the software what timecode frame 0 represents.
|
| 188 |
src_in_frames = seconds_to_frames(src_start_val, fps)
|
| 189 |
src_out_frames = seconds_to_frames(src_end_val, fps)
|
| 190 |
duration_frames = src_out_frames - src_in_frames
|
|
@@ -278,6 +276,26 @@ def generate_xml(sequence_name, segments, source_name, fps=25, start_offset=0.0)
|
|
| 278 |
|
| 279 |
return "\n".join(lines)
|
| 280 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 281 |
def call_gemini_for_edl(transcript_data, story_prompt, api_key):
|
| 282 |
if not api_key:
|
| 283 |
st.error("Gemini API Key is missing.")
|
|
@@ -317,7 +335,7 @@ def call_gemini_for_edl(transcript_data, story_prompt, api_key):
|
|
| 317 |
"Content-Type": "application/json"
|
| 318 |
}
|
| 319 |
|
| 320 |
-
#
|
| 321 |
models_to_try = [
|
| 322 |
"gemini-3.1-pro-preview",
|
| 323 |
"gemini-3-flash-preview",
|
|
@@ -541,6 +559,7 @@ if uploaded_file:
|
|
| 541 |
if not safe_filename:
|
| 542 |
safe_filename = "junior_editor_cut"
|
| 543 |
|
|
|
|
| 544 |
if export_format == "EDL":
|
| 545 |
final_output = generate_cmx_edl(final_source_name, edl_segments, final_source_name, fps, offset_sec)
|
| 546 |
ext = "edl"
|
|
@@ -548,12 +567,22 @@ if uploaded_file:
|
|
| 548 |
final_output = generate_xml(final_source_name, edl_segments, final_source_name, fps, offset_sec)
|
| 549 |
ext = "xml"
|
| 550 |
|
|
|
|
|
|
|
|
|
|
| 551 |
st.subheader("Ready for Import")
|
| 552 |
st.success(f"✅ Edit generated successfully using **{used_model}** (via {used_endpoint}).")
|
| 553 |
|
| 554 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 555 |
st.code(final_output, language="xml" if ext == "xml" else "text")
|
| 556 |
|
| 557 |
-
st.
|
| 558 |
-
|
| 559 |
|
|
|
|
| 182 |
src_start_val = float(seg.get('src_start', seg.get('start', 0.0)))
|
| 183 |
src_end_val = float(seg.get('src_end', seg.get('end', 0.0)))
|
| 184 |
|
| 185 |
+
# IN and OUT refer to the absolute zero-based frame of the media file.
|
|
|
|
|
|
|
| 186 |
src_in_frames = seconds_to_frames(src_start_val, fps)
|
| 187 |
src_out_frames = seconds_to_frames(src_end_val, fps)
|
| 188 |
duration_frames = src_out_frames - src_in_frames
|
|
|
|
| 276 |
|
| 277 |
return "\n".join(lines)
|
| 278 |
|
| 279 |
+
def generate_transcript_txt(sequence_name, segments, fps=25, start_offset=0.0):
|
| 280 |
+
"""Generates a human-readable text document of the edit decisions and transcription."""
|
| 281 |
+
lines = [f"Sequence Transcript: {sequence_name}", "=" * 50, ""]
|
| 282 |
+
|
| 283 |
+
for i, seg in enumerate(segments, 1):
|
| 284 |
+
src_start_val = float(seg.get('src_start', seg.get('start', 0.0)))
|
| 285 |
+
src_end_val = float(seg.get('src_end', seg.get('end', 0.0)))
|
| 286 |
+
|
| 287 |
+
src_in = format_timecode(src_start_val + start_offset, fps)
|
| 288 |
+
src_out = format_timecode(src_end_val + start_offset, fps)
|
| 289 |
+
|
| 290 |
+
note = seg.get('note', 'No note provided.')
|
| 291 |
+
|
| 292 |
+
lines.append(f"Clip {i:02} | IN: {src_in} --> OUT: {src_out}")
|
| 293 |
+
lines.append(f"Text: {note}")
|
| 294 |
+
lines.append("") # Blank line to separate clips visually
|
| 295 |
+
|
| 296 |
+
return "\n".join(lines)
|
| 297 |
+
|
| 298 |
+
|
| 299 |
def call_gemini_for_edl(transcript_data, story_prompt, api_key):
|
| 300 |
if not api_key:
|
| 301 |
st.error("Gemini API Key is missing.")
|
|
|
|
| 335 |
"Content-Type": "application/json"
|
| 336 |
}
|
| 337 |
|
| 338 |
+
# Prioritizes Pro models, falls back to Flash. All "lite" versions explicitly removed.
|
| 339 |
models_to_try = [
|
| 340 |
"gemini-3.1-pro-preview",
|
| 341 |
"gemini-3-flash-preview",
|
|
|
|
| 559 |
if not safe_filename:
|
| 560 |
safe_filename = "junior_editor_cut"
|
| 561 |
|
| 562 |
+
# Generate the selected edit format (EDL/XML)
|
| 563 |
if export_format == "EDL":
|
| 564 |
final_output = generate_cmx_edl(final_source_name, edl_segments, final_source_name, fps, offset_sec)
|
| 565 |
ext = "edl"
|
|
|
|
| 567 |
final_output = generate_xml(final_source_name, edl_segments, final_source_name, fps, offset_sec)
|
| 568 |
ext = "xml"
|
| 569 |
|
| 570 |
+
# Generate the companion human-readable transcript
|
| 571 |
+
transcript_txt = generate_transcript_txt(final_source_name, edl_segments, fps, offset_sec)
|
| 572 |
+
|
| 573 |
st.subheader("Ready for Import")
|
| 574 |
st.success(f"✅ Edit generated successfully using **{used_model}** (via {used_endpoint}).")
|
| 575 |
|
| 576 |
+
# Display downloads in a neat row
|
| 577 |
+
col1, col2 = st.columns(2)
|
| 578 |
+
with col1:
|
| 579 |
+
st.download_button(f"Download .{ext.upper()} Sequence", data=final_output, file_name=f"{safe_filename}.{ext}")
|
| 580 |
+
with col2:
|
| 581 |
+
st.download_button(f"Download Reference Transcript (.TXT)", data=transcript_txt, file_name=f"{safe_filename}-Transcript.txt")
|
| 582 |
+
|
| 583 |
+
with st.expander(f"Show {ext.upper()} Code", expanded=False):
|
| 584 |
st.code(final_output, language="xml" if ext == "xml" else "text")
|
| 585 |
|
| 586 |
+
with st.expander("Show Transcript Reference", expanded=False):
|
| 587 |
+
st.text(transcript_txt)
|
| 588 |
|