Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -416,7 +416,15 @@ def create_demo():
|
|
| 416 |
with gr.Row():
|
| 417 |
with gr.Column(scale=1):
|
| 418 |
preview_image = gr.Image(label="Preview Image", type="filepath", elem_classes="preview_media", visible=False)
|
| 419 |
-
preview_video = gr.Video(label="Preview Video", elem_classes="preview_media", visible=False, format="mp4")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 420 |
preview_status = gr.Textbox(label="Preview status", interactive=False, lines=2, value="", visible=True)
|
| 421 |
with gr.Column(scale=2):
|
| 422 |
url_input = gr.Textbox(label="Image / Video URL", placeholder="https://...", lines=1)
|
|
@@ -653,7 +661,7 @@ def create_demo():
|
|
| 653 |
# write with a proper video extension
|
| 654 |
tmp_video = _temp_file(raw, suffix=ext_from_src(url) or ".mp4")
|
| 655 |
progress(0.15, desc="Preparing preview")
|
| 656 |
-
preview_path =
|
| 657 |
|
| 658 |
progress(0.25, desc="Running full‑video analysis")
|
| 659 |
result = analyze_video_cohesive(client, tmp_video, prompt, progress=progress)
|
|
@@ -670,7 +678,7 @@ def create_demo():
|
|
| 670 |
raw = fetch_bytes(url, progress=progress)
|
| 671 |
|
| 672 |
# preview image (always JPEG for consistency)
|
| 673 |
-
preview_path =
|
| 674 |
|
| 675 |
progress(0.20, desc="Running image analysis")
|
| 676 |
result = analyze_image_structured(client, raw, prompt, progress=progress)
|
|
@@ -736,7 +744,25 @@ def create_demo():
|
|
| 736 |
"error": "Retry",
|
| 737 |
}
|
| 738 |
return labels.get(s, "Submit") # Default case
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 739 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 740 |
status_state.change(fn=lambda s: _btn_label_for_status(s), inputs=[status_state], outputs=[submit_btn])
|
| 741 |
|
| 742 |
# map status to progress text
|
|
@@ -744,11 +770,29 @@ def create_demo():
|
|
| 744 |
return {"idle":"Idle","busy":"Processing…","done":"Completed","error":"Error — see output"}.get(s, s)
|
| 745 |
status_state.change(fn=status_to_progress_text, inputs=[status_state], outputs=[progress_md])
|
| 746 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 747 |
# when preview_path_state changes, update preview components appropriately
|
| 748 |
# Update preview logic in apply_preview function
|
| 749 |
-
def apply_preview(path: str):
|
|
|
|
| 750 |
if not path:
|
| 751 |
-
return gr.update(
|
| 752 |
|
| 753 |
try:
|
| 754 |
# Check for valid image previews
|
|
|
|
| 416 |
with gr.Row():
|
| 417 |
with gr.Column(scale=1):
|
| 418 |
preview_image = gr.Image(label="Preview Image", type="filepath", elem_classes="preview_media", visible=False)
|
| 419 |
+
preview_video = gr.Video(label="Preview Video", elem_classes="preview_media", visible=False, format="mp4", show_controls=False)
|
| 420 |
+
def _play_pause(video_path):
|
| 421 |
+
# simple JS to toggle playback – Gradio lets you inject JS via `gr.HTML`
|
| 422 |
+
return f'''
|
| 423 |
+
<script>
|
| 424 |
+
const vid = document.querySelector('video[src="{video_path}"]');
|
| 425 |
+
if (vid) vid.paused ? vid.play() : vid.pause();
|
| 426 |
+
</script>
|
| 427 |
+
'''
|
| 428 |
preview_status = gr.Textbox(label="Preview status", interactive=False, lines=2, value="", visible=True)
|
| 429 |
with gr.Column(scale=2):
|
| 430 |
url_input = gr.Textbox(label="Image / Video URL", placeholder="https://...", lines=1)
|
|
|
|
| 661 |
# write with a proper video extension
|
| 662 |
tmp_video = _temp_file(raw, suffix=ext_from_src(url) or ".mp4")
|
| 663 |
progress(0.15, desc="Preparing preview")
|
| 664 |
+
preview_path = _make_preview(url, raw)
|
| 665 |
|
| 666 |
progress(0.25, desc="Running full‑video analysis")
|
| 667 |
result = analyze_video_cohesive(client, tmp_video, prompt, progress=progress)
|
|
|
|
| 678 |
raw = fetch_bytes(url, progress=progress)
|
| 679 |
|
| 680 |
# preview image (always JPEG for consistency)
|
| 681 |
+
preview_path = _make_preview(url, raw)
|
| 682 |
|
| 683 |
progress(0.20, desc="Running image analysis")
|
| 684 |
result = analyze_image_structured(client, raw, prompt, progress=progress)
|
|
|
|
| 744 |
"error": "Retry",
|
| 745 |
}
|
| 746 |
return labels.get(s, "Submit") # Default case
|
| 747 |
+
|
| 748 |
+
# after submit_btn / clear_btn definitions
|
| 749 |
+
cancel_btn = gr.Button("Cancel", variant="secondary")
|
| 750 |
+
|
| 751 |
+
def _cancel():
|
| 752 |
+
# abort any queued jobs
|
| 753 |
+
demo.cancel_all()
|
| 754 |
+
return "idle", "", "", "idle", "Idle", "", ""
|
| 755 |
|
| 756 |
+
cancel_btn.click(
|
| 757 |
+
fn=_cancel,
|
| 758 |
+
inputs=[],
|
| 759 |
+
outputs=[
|
| 760 |
+
status_state, output_md, preview_path_state,
|
| 761 |
+
progress_md, preview_status, preview_image, preview_video,
|
| 762 |
+
],
|
| 763 |
+
queue=False,
|
| 764 |
+
)
|
| 765 |
+
|
| 766 |
status_state.change(fn=lambda s: _btn_label_for_status(s), inputs=[status_state], outputs=[submit_btn])
|
| 767 |
|
| 768 |
# map status to progress text
|
|
|
|
| 770 |
return {"idle":"Idle","busy":"Processing…","done":"Completed","error":"Error — see output"}.get(s, s)
|
| 771 |
status_state.change(fn=status_to_progress_text, inputs=[status_state], outputs=[progress_md])
|
| 772 |
|
| 773 |
+
preview_cache = {} # module‑level dict: url → (preview_path, is_video)
|
| 774 |
+
|
| 775 |
+
def _make_preview(url: str, raw: bytes) -> str:
|
| 776 |
+
# reuse existing preview if we already have one for this URL
|
| 777 |
+
if url in preview_cache:
|
| 778 |
+
return preview_cache[url][0]
|
| 779 |
+
|
| 780 |
+
if determine_media_type(url)[1]: # video
|
| 781 |
+
tmp = _temp_file(raw, suffix=ext_from_src(url) or ".mp4")
|
| 782 |
+
preview = _convert_video_for_preview_if_needed(tmp)
|
| 783 |
+
# keep the raw temp file for later clean‑up
|
| 784 |
+
preview_cache[url] = (preview, True)
|
| 785 |
+
else: # image
|
| 786 |
+
preview = _temp_file(convert_to_jpeg_bytes(raw, base_h=1024), suffix=".jpg")
|
| 787 |
+
preview_cache[url] = (preview, False)
|
| 788 |
+
return preview
|
| 789 |
+
|
| 790 |
# when preview_path_state changes, update preview components appropriately
|
| 791 |
# Update preview logic in apply_preview function
|
| 792 |
+
def apply_preview(path: str, last_path: str):
|
| 793 |
+
if path == last_path:
|
| 794 |
if not path:
|
| 795 |
+
return gr.update(), gr.update(), ""
|
| 796 |
|
| 797 |
try:
|
| 798 |
# Check for valid image previews
|