Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -453,11 +453,62 @@ def get_video_info(video_path):
|
|
| 453 |
except:
|
| 454 |
return None, None, None, None
|
| 455 |
|
| 456 |
-
# Function to
|
| 457 |
-
def
|
| 458 |
-
"""
|
| 459 |
if video is None:
|
| 460 |
-
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 461 |
|
| 462 |
try:
|
| 463 |
# Create a copy of the video file with a timestamp
|
|
@@ -470,11 +521,44 @@ def save_recorded_video(video):
|
|
| 470 |
shutil.copy2(video, temp_output.name)
|
| 471 |
temp_output.close()
|
| 472 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
print(f"📹 Video saved: {output_filename}")
|
| 474 |
-
return temp_output.name
|
|
|
|
| 475 |
except Exception as e:
|
| 476 |
print(f"⚠️ Failed to save video: {str(e)}")
|
| 477 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 478 |
|
| 479 |
# Define the core processing function (separate from GPU wrapper)
|
| 480 |
def process_video_core(video, resize_option, assessor):
|
|
@@ -629,7 +713,7 @@ with gr.Blocks(title="CICE 2.0 Healthcare Assessment Tool", theme=gr.themes.Soft
|
|
| 629 |
**Analyze healthcare team interactions using specific behavioral cues from the 18-point CICE 2.0 framework**
|
| 630 |
|
| 631 |
This tool evaluates critical team behaviors including:
|
| 632 |
-
-
|
| 633 |
- Roles/responsibilities
|
| 634 |
- Interprofessional communication
|
| 635 |
- Teams and teamwork
|
|
@@ -664,6 +748,13 @@ with gr.Blocks(title="CICE 2.0 Healthcare Assessment Tool", theme=gr.themes.Soft
|
|
| 664 |
autoplay=False, # Disable autoplay for faster loading
|
| 665 |
show_download_button=True # Show download button immediately
|
| 666 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 667 |
|
| 668 |
# Add download component for recorded videos
|
| 669 |
recorded_video_download = gr.File(
|
|
@@ -750,16 +841,29 @@ with gr.Blocks(title="CICE 2.0 Healthcare Assessment Tool", theme=gr.themes.Soft
|
|
| 750 |
**Powered by Google Gemini 2.0 Flash | GPU-Accelerated with HuggingFace L405**
|
| 751 |
""")
|
| 752 |
|
| 753 |
-
# Auto-save video when recording stops
|
| 754 |
video_input.stop_recording(
|
| 755 |
-
fn=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 756 |
inputs=[video_input],
|
| 757 |
-
outputs=[recorded_video_download],
|
| 758 |
api_name="save_video"
|
| 759 |
).then(
|
| 760 |
fn=lambda x: gr.update(visible=True if x else False),
|
| 761 |
inputs=[recorded_video_download],
|
| 762 |
outputs=[recorded_video_download]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 763 |
)
|
| 764 |
|
| 765 |
# Connect the analyze button
|
|
|
|
| 453 |
except:
|
| 454 |
return None, None, None, None
|
| 455 |
|
| 456 |
+
# Function to show immediate status when recording stops
|
| 457 |
+
def show_saving_status(video):
|
| 458 |
+
"""Show immediate status bar when recording stops"""
|
| 459 |
if video is None:
|
| 460 |
+
return gr.update(visible=False), None
|
| 461 |
+
|
| 462 |
+
# Create animated status HTML
|
| 463 |
+
status_html = """
|
| 464 |
+
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px; margin: 20px 0; animation: pulse 1.5s ease-in-out infinite;">
|
| 465 |
+
<style>
|
| 466 |
+
@keyframes pulse {
|
| 467 |
+
0%, 100% { opacity: 1; }
|
| 468 |
+
50% { opacity: 0.8; }
|
| 469 |
+
}
|
| 470 |
+
@keyframes slide {
|
| 471 |
+
0% { transform: translateX(-100%); }
|
| 472 |
+
100% { transform: translateX(100%); }
|
| 473 |
+
}
|
| 474 |
+
.progress-bar {
|
| 475 |
+
position: relative;
|
| 476 |
+
height: 6px;
|
| 477 |
+
background: rgba(255, 255, 255, 0.3);
|
| 478 |
+
border-radius: 3px;
|
| 479 |
+
overflow: hidden;
|
| 480 |
+
margin-top: 15px;
|
| 481 |
+
}
|
| 482 |
+
.progress-bar::after {
|
| 483 |
+
content: '';
|
| 484 |
+
position: absolute;
|
| 485 |
+
top: 0;
|
| 486 |
+
left: 0;
|
| 487 |
+
width: 40%;
|
| 488 |
+
height: 100%;
|
| 489 |
+
background: white;
|
| 490 |
+
animation: slide 1.5s ease-in-out infinite;
|
| 491 |
+
}
|
| 492 |
+
</style>
|
| 493 |
+
<div style="text-align: center; color: white;">
|
| 494 |
+
<div style="font-size: 24px; font-weight: bold; margin-bottom: 10px;">
|
| 495 |
+
📹 Processing Your Recording...
|
| 496 |
+
</div>
|
| 497 |
+
<div style="font-size: 16px; opacity: 0.95;">
|
| 498 |
+
Saving video file • Preparing for download
|
| 499 |
+
</div>
|
| 500 |
+
<div class="progress-bar"></div>
|
| 501 |
+
</div>
|
| 502 |
+
</div>
|
| 503 |
+
"""
|
| 504 |
+
|
| 505 |
+
return gr.update(value=status_html, visible=True), video
|
| 506 |
+
|
| 507 |
+
# Enhanced save function with status updates
|
| 508 |
+
def save_recorded_video_with_status(video):
|
| 509 |
+
"""Save the recorded video with status updates"""
|
| 510 |
+
if video is None:
|
| 511 |
+
return None, gr.update(value="", visible=False)
|
| 512 |
|
| 513 |
try:
|
| 514 |
# Create a copy of the video file with a timestamp
|
|
|
|
| 521 |
shutil.copy2(video, temp_output.name)
|
| 522 |
temp_output.close()
|
| 523 |
|
| 524 |
+
# Success status
|
| 525 |
+
success_html = """
|
| 526 |
+
<div style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); padding: 15px; border-radius: 10px; margin: 20px 0;">
|
| 527 |
+
<div style="text-align: center; color: white;">
|
| 528 |
+
<div style="font-size: 20px; font-weight: bold;">
|
| 529 |
+
✅ Video Saved Successfully!
|
| 530 |
+
</div>
|
| 531 |
+
<div style="font-size: 14px; margin-top: 5px; opacity: 0.95;">
|
| 532 |
+
Ready for download • Click "Analyze Video" to assess
|
| 533 |
+
</div>
|
| 534 |
+
</div>
|
| 535 |
+
</div>
|
| 536 |
+
"""
|
| 537 |
+
|
| 538 |
print(f"📹 Video saved: {output_filename}")
|
| 539 |
+
return temp_output.name, gr.update(value=success_html, visible=True)
|
| 540 |
+
|
| 541 |
except Exception as e:
|
| 542 |
print(f"⚠️ Failed to save video: {str(e)}")
|
| 543 |
+
error_html = """
|
| 544 |
+
<div style="background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); padding: 15px; border-radius: 10px; margin: 20px 0;">
|
| 545 |
+
<div style="text-align: center; color: white;">
|
| 546 |
+
<div style="font-size: 20px; font-weight: bold;">
|
| 547 |
+
⚠️ Error Saving Video
|
| 548 |
+
</div>
|
| 549 |
+
<div style="font-size: 14px; margin-top: 5px;">
|
| 550 |
+
Please try recording again
|
| 551 |
+
</div>
|
| 552 |
+
</div>
|
| 553 |
+
</div>
|
| 554 |
+
"""
|
| 555 |
+
return None, gr.update(value=error_html, visible=True)
|
| 556 |
+
|
| 557 |
+
# Function to hide status after a delay
|
| 558 |
+
def hide_status_after_delay():
|
| 559 |
+
"""Hide the status bar after showing success"""
|
| 560 |
+
time.sleep(3) # Wait 3 seconds
|
| 561 |
+
return gr.update(value="", visible=False)
|
| 562 |
|
| 563 |
# Define the core processing function (separate from GPU wrapper)
|
| 564 |
def process_video_core(video, resize_option, assessor):
|
|
|
|
| 713 |
**Analyze healthcare team interactions using specific behavioral cues from the 18-point CICE 2.0 framework**
|
| 714 |
|
| 715 |
This tool evaluates critical team behaviors including:
|
| 716 |
+
- Values/ethics for interprofessional practice
|
| 717 |
- Roles/responsibilities
|
| 718 |
- Interprofessional communication
|
| 719 |
- Teams and teamwork
|
|
|
|
| 748 |
autoplay=False, # Disable autoplay for faster loading
|
| 749 |
show_download_button=True # Show download button immediately
|
| 750 |
)
|
| 751 |
+
|
| 752 |
+
# Status bar for immediate feedback
|
| 753 |
+
status_bar = gr.HTML(
|
| 754 |
+
value="",
|
| 755 |
+
visible=False,
|
| 756 |
+
elem_id="status-bar"
|
| 757 |
+
)
|
| 758 |
|
| 759 |
# Add download component for recorded videos
|
| 760 |
recorded_video_download = gr.File(
|
|
|
|
| 841 |
**Powered by Google Gemini 2.0 Flash | GPU-Accelerated with HuggingFace L405**
|
| 842 |
""")
|
| 843 |
|
| 844 |
+
# Auto-save video when recording stops with immediate status feedback
|
| 845 |
video_input.stop_recording(
|
| 846 |
+
fn=show_saving_status,
|
| 847 |
+
inputs=[video_input],
|
| 848 |
+
outputs=[status_bar, video_input],
|
| 849 |
+
api_name="show_status"
|
| 850 |
+
).then(
|
| 851 |
+
fn=save_recorded_video_with_status,
|
| 852 |
inputs=[video_input],
|
| 853 |
+
outputs=[recorded_video_download, status_bar],
|
| 854 |
api_name="save_video"
|
| 855 |
).then(
|
| 856 |
fn=lambda x: gr.update(visible=True if x else False),
|
| 857 |
inputs=[recorded_video_download],
|
| 858 |
outputs=[recorded_video_download]
|
| 859 |
+
).then(
|
| 860 |
+
fn=lambda: time.sleep(3),
|
| 861 |
+
inputs=[],
|
| 862 |
+
outputs=[]
|
| 863 |
+
).then(
|
| 864 |
+
fn=lambda: gr.update(value="", visible=False),
|
| 865 |
+
inputs=[],
|
| 866 |
+
outputs=[status_bar]
|
| 867 |
)
|
| 868 |
|
| 869 |
# Connect the analyze button
|