Spaces:
				
			
			
	
			
			
		Running
		
			on 
			
			Zero
	
	
	
			
			
	
	
	
	
		
		
		Running
		
			on 
			
			Zero
	Upload 2 files
Browse filesfixed display issues
- app.py +32 -8
- ui_manager.py +2 -1
    	
        app.py
    CHANGED
    
    | @@ -583,12 +583,13 @@ def handle_video_upload(video_input, video_url, input_type, model_name, | |
| 583 | 
             
                    process_interval: 處理間隔(每N幀處理一次)
         | 
| 584 |  | 
| 585 | 
             
                Returns:
         | 
| 586 | 
            -
                    Tuple: (output_video_path, summary_html, formatted_stats)
         | 
| 587 | 
             
                """
         | 
| 588 | 
             
                if video_processor is None:
         | 
| 589 | 
             
                    error_msg = "Error: Video processor not initialized."
         | 
| 590 | 
             
                    error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 591 | 
            -
                     | 
|  | |
| 592 |  | 
| 593 | 
             
                video_path = None
         | 
| 594 |  | 
| @@ -601,12 +602,14 @@ def handle_video_upload(video_input, video_url, input_type, model_name, | |
| 601 | 
             
                    video_path, error_msg = download_video_from_url(video_url)
         | 
| 602 | 
             
                    if error_msg:
         | 
| 603 | 
             
                        error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 604 | 
            -
                         | 
|  | |
| 605 |  | 
| 606 | 
             
                if not video_path:
         | 
| 607 | 
             
                    error_msg = "Please provide a video file or valid URL."
         | 
| 608 | 
             
                    error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 609 | 
            -
                     | 
|  | |
| 610 |  | 
| 611 | 
             
                print(f"Starting practical video analysis: model={model_name}, confidence={confidence_threshold}, interval={process_interval}")
         | 
| 612 |  | 
| @@ -625,7 +628,8 @@ def handle_video_upload(video_input, video_url, input_type, model_name, | |
| 625 | 
             
                    if output_video_path is None:
         | 
| 626 | 
             
                        error_msg = analysis_results.get("error", "Unknown error occurred during video processing")
         | 
| 627 | 
             
                        error_html = f"<div class='video-summary-content-wrapper'><pre>Processing failed: {error_msg}</pre></div>"
         | 
| 628 | 
            -
                         | 
|  | |
| 629 |  | 
| 630 | 
             
                    # 生成摘要,直接用統計數據
         | 
| 631 | 
             
                    basic_summary = generate_basic_video_summary(analysis_results)
         | 
| @@ -644,14 +648,34 @@ def handle_video_upload(video_input, video_url, input_type, model_name, | |
| 644 | 
             
                    summary_content = '\n'.join(summary_lines)
         | 
| 645 | 
             
                    summary_html = f"<div class='video-summary-content-wrapper'><pre>{summary_content}</pre></div>"
         | 
| 646 |  | 
| 647 | 
            -
                     | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 648 |  | 
| 649 | 
             
                except Exception as e:
         | 
| 650 | 
             
                    print(f"Error in handle_video_upload: {e}")
         | 
| 651 | 
             
                    traceback.print_exc()
         | 
| 652 | 
            -
                    error_msg = f" | 
| 653 | 
             
                    error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 654 | 
            -
                     | 
|  | |
| 655 |  | 
| 656 | 
             
            def main():
         | 
| 657 | 
             
                """主函數,初始化並啟動Gradio"""
         | 
|  | |
| 583 | 
             
                    process_interval: 處理間隔(每N幀處理一次)
         | 
| 584 |  | 
| 585 | 
             
                Returns:
         | 
| 586 | 
            +
                    Tuple: (output_video_path, summary_html, formatted_stats, object_details)
         | 
| 587 | 
             
                """
         | 
| 588 | 
             
                if video_processor is None:
         | 
| 589 | 
             
                    error_msg = "Error: Video processor not initialized."
         | 
| 590 | 
             
                    error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 591 | 
            +
                    empty_object_details = {}
         | 
| 592 | 
            +
                    return None, error_html, {"error": "Video processor not available"}, empty_object_details
         | 
| 593 |  | 
| 594 | 
             
                video_path = None
         | 
| 595 |  | 
|  | |
| 602 | 
             
                    video_path, error_msg = download_video_from_url(video_url)
         | 
| 603 | 
             
                    if error_msg:
         | 
| 604 | 
             
                        error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 605 | 
            +
                        empty_object_details = {}
         | 
| 606 | 
            +
                        return None, error_html, {"error": error_msg}, empty_object_details
         | 
| 607 |  | 
| 608 | 
             
                if not video_path:
         | 
| 609 | 
             
                    error_msg = "Please provide a video file or valid URL."
         | 
| 610 | 
             
                    error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 611 | 
            +
                    empty_object_details = {}
         | 
| 612 | 
            +
                    return None, error_html, {"error": "No video input provided"}, empty_object_details
         | 
| 613 |  | 
| 614 | 
             
                print(f"Starting practical video analysis: model={model_name}, confidence={confidence_threshold}, interval={process_interval}")
         | 
| 615 |  | 
|  | |
| 628 | 
             
                    if output_video_path is None:
         | 
| 629 | 
             
                        error_msg = analysis_results.get("error", "Unknown error occurred during video processing")
         | 
| 630 | 
             
                        error_html = f"<div class='video-summary-content-wrapper'><pre>Processing failed: {error_msg}</pre></div>"
         | 
| 631 | 
            +
                        empty_object_details = {}
         | 
| 632 | 
            +
                        return None, error_html, analysis_results, empty_object_details
         | 
| 633 |  | 
| 634 | 
             
                    # 生成摘要,直接用統計數據
         | 
| 635 | 
             
                    basic_summary = generate_basic_video_summary(analysis_results)
         | 
|  | |
| 648 | 
             
                    summary_content = '\n'.join(summary_lines)
         | 
| 649 | 
             
                    summary_html = f"<div class='video-summary-content-wrapper'><pre>{summary_content}</pre></div>"
         | 
| 650 |  | 
| 651 | 
            +
                    # 提取物體詳情數據用於第四個輸出組件
         | 
| 652 | 
            +
                    timeline_analysis = analysis_results.get("timeline_analysis", {})
         | 
| 653 | 
            +
                    object_appearances = timeline_analysis.get("object_appearances", {})
         | 
| 654 | 
            +
                    
         | 
| 655 | 
            +
                    # 格式化物體詳情數據以便在JSON組件中顯示
         | 
| 656 | 
            +
                    object_details_formatted = {}
         | 
| 657 | 
            +
                    for obj_name, details in object_appearances.items():
         | 
| 658 | 
            +
                        object_details_formatted[obj_name] = {
         | 
| 659 | 
            +
                            "Estimated Count": details.get("estimated_count", 0),
         | 
| 660 | 
            +
                            "First Appearance": details.get("first_appearance", "Unknown"),
         | 
| 661 | 
            +
                            "Last Seen": details.get("last_seen", "Unknown"), 
         | 
| 662 | 
            +
                            "Duration in Video": details.get("duration_in_video", "Unknown"),
         | 
| 663 | 
            +
                            "Detection Confidence": details.get("detection_confidence", 0.0),
         | 
| 664 | 
            +
                            "First Appearance (seconds)": details.get("first_appearance_seconds", 0),
         | 
| 665 | 
            +
                            "Duration (seconds)": details.get("duration_seconds", 0)
         | 
| 666 | 
            +
                        }
         | 
| 667 | 
            +
                    
         | 
| 668 | 
            +
                    print(f"Extracted object details for {len(object_details_formatted)} object types")
         | 
| 669 | 
            +
                    
         | 
| 670 | 
            +
                    return output_video_path, summary_html, analysis_results, object_details_formatted
         | 
| 671 |  | 
| 672 | 
             
                except Exception as e:
         | 
| 673 | 
             
                    print(f"Error in handle_video_upload: {e}")
         | 
| 674 | 
             
                    traceback.print_exc()
         | 
| 675 | 
            +
                    error_msg = f"Video processing failed: {str(e)}"
         | 
| 676 | 
             
                    error_html = f"<div class='video-summary-content-wrapper'><pre>{error_msg}</pre></div>"
         | 
| 677 | 
            +
                    empty_object_details = {}
         | 
| 678 | 
            +
                    return None, error_html, {"error": str(e)}, empty_object_details
         | 
| 679 |  | 
| 680 | 
             
            def main():
         | 
| 681 | 
             
                """主函數,初始化並啟動Gradio"""
         | 
    	
        ui_manager.py
    CHANGED
    
    | @@ -749,6 +749,7 @@ class UIManager: | |
| 749 | 
             
                    outputs=[
         | 
| 750 | 
             
                        video_components['video_output'],
         | 
| 751 | 
             
                        video_components['video_summary_text'],
         | 
| 752 | 
            -
                        video_components['video_stats_json']
         | 
|  | |
| 753 | 
             
                        ]
         | 
| 754 | 
             
                    )
         | 
|  | |
| 749 | 
             
                    outputs=[
         | 
| 750 | 
             
                        video_components['video_output'],
         | 
| 751 | 
             
                        video_components['video_summary_text'],
         | 
| 752 | 
            +
                        video_components['video_stats_json'],
         | 
| 753 | 
            +
                        video_components['video_object_details'] 
         | 
| 754 | 
             
                        ]
         | 
| 755 | 
             
                    )
         | 
