Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -262,6 +262,13 @@ def process_recorded_video(video_data_base64):
|
|
| 262 |
debug_msg += f"data length: {len(video_data_base64) if video_data_base64 else 0}"
|
| 263 |
print(debug_msg)
|
| 264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 265 |
# Check for empty data
|
| 266 |
if not video_data_base64:
|
| 267 |
print("DEBUG: No video data received")
|
|
@@ -349,6 +356,7 @@ def create_video_recorder_html():
|
|
| 349 |
var fileStatusDiv = document.querySelector('#fileStatus');
|
| 350 |
var videoDataInput = document.querySelector('#videoDataInput');
|
| 351 |
var hiddenAnalyzeBtn = document.querySelector('#hiddenAnalyzeBtn');
|
|
|
|
| 352 |
|
| 353 |
var mediaRecorder;
|
| 354 |
var recordedBlobs = [];
|
|
@@ -553,23 +561,82 @@ def create_video_recorder_html():
|
|
| 553 |
|
| 554 |
// Use setTimeout to ensure the value is set before clicking
|
| 555 |
setTimeout(function() {
|
| 556 |
-
console.log('Triggering
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
|
| 558 |
-
//
|
| 559 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 560 |
|
| 561 |
-
//
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 568 |
}
|
| 569 |
-
} catch(e) {
|
| 570 |
-
console.error('Error with form submission:', e);
|
| 571 |
}
|
| 572 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 573 |
|
| 574 |
fileStatusDiv.textContent = '🤖 Analysis in progress... This may take 1-2 minutes.';
|
| 575 |
} catch (error) {
|
|
@@ -723,9 +790,18 @@ def create_gradio_app():
|
|
| 723 |
|
| 724 |
# Hidden components for JavaScript communication
|
| 725 |
with gr.Row(visible=False):
|
| 726 |
-
video_data_hidden = gr.Textbox(elem_id="videoDataInput")
|
| 727 |
analyze_hidden_btn = gr.Button("Hidden Analyze", elem_id="hiddenAnalyzeBtn")
|
| 728 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 729 |
# Assessment results from recording
|
| 730 |
with gr.Row():
|
| 731 |
with gr.Column(scale=2):
|
|
@@ -874,11 +950,22 @@ def create_gradio_app():
|
|
| 874 |
)
|
| 875 |
|
| 876 |
# Event handler for recorded video analysis
|
|
|
|
|
|
|
|
|
|
|
|
|
| 877 |
analyze_hidden_btn.click(
|
| 878 |
-
fn=
|
| 879 |
inputs=[video_data_hidden],
|
| 880 |
outputs=[recording_assessment_output, recording_summary_output, recording_audio_output],
|
| 881 |
-
api_name="analyze_recording"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 882 |
)
|
| 883 |
|
| 884 |
# Q&A handlers
|
|
|
|
| 262 |
debug_msg += f"data length: {len(video_data_base64) if video_data_base64 else 0}"
|
| 263 |
print(debug_msg)
|
| 264 |
|
| 265 |
+
# Also log to a file for persistent debugging
|
| 266 |
+
try:
|
| 267 |
+
with open('/tmp/cice_debug.log', 'a') as f:
|
| 268 |
+
f.write(f"{datetime.now()}: {debug_msg}\n")
|
| 269 |
+
except:
|
| 270 |
+
pass
|
| 271 |
+
|
| 272 |
# Check for empty data
|
| 273 |
if not video_data_base64:
|
| 274 |
print("DEBUG: No video data received")
|
|
|
|
| 356 |
var fileStatusDiv = document.querySelector('#fileStatus');
|
| 357 |
var videoDataInput = document.querySelector('#videoDataInput');
|
| 358 |
var hiddenAnalyzeBtn = document.querySelector('#hiddenAnalyzeBtn');
|
| 359 |
+
var manualAnalyzeBtn = document.querySelector('#manualAnalyzeBtn');
|
| 360 |
|
| 361 |
var mediaRecorder;
|
| 362 |
var recordedBlobs = [];
|
|
|
|
| 561 |
|
| 562 |
// Use setTimeout to ensure the value is set before clicking
|
| 563 |
setTimeout(function() {
|
| 564 |
+
console.log('Triggering analysis with data length:', videoDataInput.value.length);
|
| 565 |
+
|
| 566 |
+
// Try multiple methods to trigger the analysis
|
| 567 |
+
var success = false;
|
| 568 |
+
|
| 569 |
+
// Method 1: Hidden button click
|
| 570 |
+
if (hiddenAnalyzeBtn) {
|
| 571 |
+
try {
|
| 572 |
+
console.log('Method 1: Clicking hidden analyze button...');
|
| 573 |
+
hiddenAnalyzeBtn.click();
|
| 574 |
+
success = true;
|
| 575 |
+
} catch(e) {
|
| 576 |
+
console.error('Method 1 failed:', e);
|
| 577 |
+
}
|
| 578 |
+
}
|
| 579 |
|
| 580 |
+
// Method 2: Manual button click (if available)
|
| 581 |
+
if (!success && manualAnalyzeBtn) {
|
| 582 |
+
try {
|
| 583 |
+
console.log('Method 2: Clicking manual analyze button...');
|
| 584 |
+
manualAnalyzeBtn.click();
|
| 585 |
+
success = true;
|
| 586 |
+
} catch(e) {
|
| 587 |
+
console.error('Method 2 failed:', e);
|
| 588 |
+
}
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
// Method 3: Trigger change event
|
| 592 |
+
if (!success) {
|
| 593 |
+
try {
|
| 594 |
+
console.log('Method 3: Dispatching change event...');
|
| 595 |
+
var changeEvent = new Event('change', { bubbles: true });
|
| 596 |
+
videoDataInput.dispatchEvent(changeEvent);
|
| 597 |
+
success = true;
|
| 598 |
+
} catch(e) {
|
| 599 |
+
console.error('Method 3 failed:', e);
|
| 600 |
+
}
|
| 601 |
+
}
|
| 602 |
|
| 603 |
+
// Method 4: Direct API call as last resort
|
| 604 |
+
if (!success) {
|
| 605 |
+
try {
|
| 606 |
+
console.log('Method 4: Direct API call...');
|
| 607 |
+
fetch('/api/analyze_recording', {
|
| 608 |
+
method: 'POST',
|
| 609 |
+
headers: {
|
| 610 |
+
'Content-Type': 'application/json',
|
| 611 |
+
},
|
| 612 |
+
body: JSON.stringify({
|
| 613 |
+
data: [base64Data]
|
| 614 |
+
})
|
| 615 |
+
}).then(response => {
|
| 616 |
+
if (response.ok) {
|
| 617 |
+
console.log('API call successful');
|
| 618 |
+
success = true;
|
| 619 |
+
} else {
|
| 620 |
+
console.error('API call failed:', response.status);
|
| 621 |
+
}
|
| 622 |
+
}).catch(e => {
|
| 623 |
+
console.error('API call error:', e);
|
| 624 |
+
});
|
| 625 |
+
} catch(e) {
|
| 626 |
+
console.error('Method 4 failed:', e);
|
| 627 |
}
|
|
|
|
|
|
|
| 628 |
}
|
| 629 |
+
|
| 630 |
+
if (!success) {
|
| 631 |
+
console.error('All analysis trigger methods failed!');
|
| 632 |
+
fileStatusDiv.textContent = '❌ Failed to trigger analysis. Please try again.';
|
| 633 |
+
fileStatusDiv.style.color = 'red';
|
| 634 |
+
analyzeBtn.disabled = false;
|
| 635 |
+
analyzeBtn.style.opacity = '1';
|
| 636 |
+
} else {
|
| 637 |
+
console.log('Analysis triggered successfully');
|
| 638 |
+
}
|
| 639 |
+
}, 300);
|
| 640 |
|
| 641 |
fileStatusDiv.textContent = '🤖 Analysis in progress... This may take 1-2 minutes.';
|
| 642 |
} catch (error) {
|
|
|
|
| 790 |
|
| 791 |
# Hidden components for JavaScript communication
|
| 792 |
with gr.Row(visible=False):
|
| 793 |
+
video_data_hidden = gr.Textbox(elem_id="videoDataInput", label="Video Data")
|
| 794 |
analyze_hidden_btn = gr.Button("Hidden Analyze", elem_id="hiddenAnalyzeBtn")
|
| 795 |
|
| 796 |
+
# Alternative visible button for debugging
|
| 797 |
+
with gr.Row():
|
| 798 |
+
manual_analyze_btn = gr.Button(
|
| 799 |
+
"🔍 Manual Analyze Recording",
|
| 800 |
+
variant="secondary",
|
| 801 |
+
visible=False,
|
| 802 |
+
elem_id="manualAnalyzeBtn"
|
| 803 |
+
)
|
| 804 |
+
|
| 805 |
# Assessment results from recording
|
| 806 |
with gr.Row():
|
| 807 |
with gr.Column(scale=2):
|
|
|
|
| 950 |
)
|
| 951 |
|
| 952 |
# Event handler for recorded video analysis
|
| 953 |
+
def analyze_recorded_video(video_data):
|
| 954 |
+
print(f"DEBUG: analyze_recorded_video called with data length: {len(video_data) if video_data else 0}")
|
| 955 |
+
return store_assessment_state(None, *process_recorded_video(video_data))
|
| 956 |
+
|
| 957 |
analyze_hidden_btn.click(
|
| 958 |
+
fn=analyze_recorded_video,
|
| 959 |
inputs=[video_data_hidden],
|
| 960 |
outputs=[recording_assessment_output, recording_summary_output, recording_audio_output],
|
| 961 |
+
api_name="analyze_recording"
|
| 962 |
+
)
|
| 963 |
+
|
| 964 |
+
# Manual analyze button for debugging
|
| 965 |
+
manual_analyze_btn.click(
|
| 966 |
+
fn=analyze_recorded_video,
|
| 967 |
+
inputs=[video_data_hidden],
|
| 968 |
+
outputs=[recording_assessment_output, recording_summary_output, recording_audio_output]
|
| 969 |
)
|
| 970 |
|
| 971 |
# Q&A handlers
|