chenemii commited on
Commit
ed08beb
·
1 Parent(s): bf56017
app/main.py CHANGED
@@ -13,7 +13,7 @@ load_dotenv()
13
  # Add the app directory to the path
14
  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
15
 
16
- from app.utils.video_downloader import download_youtube_video
17
  from app.utils.video_processor import process_video
18
  from app.models.pose_estimator import analyze_pose
19
  from app.models.swing_analyzer import segment_swing, analyze_trajectory
@@ -38,6 +38,7 @@ def main():
38
  if sample_rate_input.isdigit():
39
  sample_rate = max(1, min(10, int(sample_rate_input)))
40
 
 
41
  try:
42
  # Step 3: Download the video
43
  print("\nDownloading video...")
@@ -95,7 +96,11 @@ def main():
95
 
96
  except Exception as e:
97
  print(f"\nError: {str(e)}")
98
- return
 
 
 
 
99
 
100
 
101
  if __name__ == "__main__":
 
13
  # Add the app directory to the path
14
  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
15
 
16
+ from app.utils.video_downloader import download_youtube_video, cleanup_video_file
17
  from app.utils.video_processor import process_video
18
  from app.models.pose_estimator import analyze_pose
19
  from app.models.swing_analyzer import segment_swing, analyze_trajectory
 
38
  if sample_rate_input.isdigit():
39
  sample_rate = max(1, min(10, int(sample_rate_input)))
40
 
41
+ video_path = None # Initialize video_path for cleanup
42
  try:
43
  # Step 3: Download the video
44
  print("\nDownloading video...")
 
96
 
97
  except Exception as e:
98
  print(f"\nError: {str(e)}")
99
+ finally:
100
+ # Clean up the original downloaded video file after processing
101
+ if video_path:
102
+ print("\nCleaning up downloaded video file...")
103
+ cleanup_video_file(video_path)
104
 
105
 
106
  if __name__ == "__main__":
app/streamlit_app.py CHANGED
@@ -19,7 +19,7 @@ load_dotenv()
19
  # Add the app directory to the path
20
  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
21
 
22
- from app.utils.video_downloader import download_youtube_video, download_pro_reference
23
  from app.utils.video_processor import process_video
24
  from app.models.pose_estimator import analyze_pose
25
  from app.models.swing_analyzer import segment_swing, analyze_trajectory
@@ -92,6 +92,7 @@ def main():
92
  """Main Streamlit application"""
93
  st.title("Par-ity Project: Golf Swing Analysis 🏌️‍♀️")
94
  st.write("Founded to address the gender gap in golf participation and access to quality coaching resources, Par-ity Project is a technology-driven initiative empowering girls in golf through innovative AI based swing analysis. This technology uses computer vision and machine learning algorithms to analyze golf swings and provide personalized feedback to improve technique and performance.")
 
95
  # Initialize session state for storing analysis results
96
  if 'video_analyzed' not in st.session_state:
97
  st.session_state.video_analyzed = False
@@ -107,10 +108,32 @@ def main():
107
  }
108
  if 'pro_reference_path' not in st.session_state:
109
  st.session_state.pro_reference_path = None
 
 
 
 
 
 
 
110
 
111
  # Sidebar for configuration
112
  st.sidebar.title("Configuration")
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  # Check available LLM services
115
  llm_services = check_llm_services()
116
  any_service_available = llm_services['ollama'][
@@ -289,6 +312,10 @@ def main():
289
  'prompt': prompt
290
  }
291
 
 
 
 
 
292
  # Present the options after analysis
293
  st.subheader("What would you like to do next?")
294
  options_col1, options_col2, options_col3 = st.columns(3)
@@ -311,6 +338,9 @@ def main():
311
  except Exception as e:
312
  st.error(f"Error during analysis: {str(e)}")
313
  st.session_state.video_analyzed = False
 
 
 
314
 
315
  # Show action buttons and their results (only if analysis is complete)
316
  if st.session_state.video_analyzed:
 
19
  # Add the app directory to the path
20
  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
21
 
22
+ from app.utils.video_downloader import download_youtube_video, download_pro_reference, cleanup_video_file, cleanup_downloads_directory
23
  from app.utils.video_processor import process_video
24
  from app.models.pose_estimator import analyze_pose
25
  from app.models.swing_analyzer import segment_swing, analyze_trajectory
 
92
  """Main Streamlit application"""
93
  st.title("Par-ity Project: Golf Swing Analysis 🏌️‍♀️")
94
  st.write("Founded to address the gender gap in golf participation and access to quality coaching resources, Par-ity Project is a technology-driven initiative empowering girls in golf through innovative AI based swing analysis. This technology uses computer vision and machine learning algorithms to analyze golf swings and provide personalized feedback to improve technique and performance.")
95
+
96
  # Initialize session state for storing analysis results
97
  if 'video_analyzed' not in st.session_state:
98
  st.session_state.video_analyzed = False
 
108
  }
109
  if 'pro_reference_path' not in st.session_state:
110
  st.session_state.pro_reference_path = None
111
+
112
+ # Add session cleanup - clean up old files when starting a new session
113
+ if 'session_initialized' not in st.session_state:
114
+ cleanup_result = cleanup_downloads_directory(keep_annotated=True)
115
+ if cleanup_result.get('files_removed', 0) > 0:
116
+ st.info(f"🗑️ Cleaned up {cleanup_result['files_removed']} old files ({cleanup_result['space_freed_mb']} MB freed)")
117
+ st.session_state.session_initialized = True
118
 
119
  # Sidebar for configuration
120
  st.sidebar.title("Configuration")
121
 
122
+ # Add Reset Session button
123
+ st.sidebar.markdown("---")
124
+ if st.sidebar.button("🗑️ Reset Session & Clean Files", help="Clear all session data and remove downloaded files"):
125
+ # Clean up downloads directory
126
+ cleanup_result = cleanup_downloads_directory(keep_annotated=False) # Remove all files including annotated
127
+
128
+ # Clear session state
129
+ for key in list(st.session_state.keys()):
130
+ del st.session_state[key]
131
+
132
+ st.sidebar.success(f"Session reset! Cleaned {cleanup_result.get('files_removed', 0)} files ({cleanup_result.get('space_freed_mb', 0)} MB freed)")
133
+ st.rerun()
134
+
135
+ st.sidebar.markdown("---")
136
+
137
  # Check available LLM services
138
  llm_services = check_llm_services()
139
  any_service_available = llm_services['ollama'][
 
312
  'prompt': prompt
313
  }
314
 
315
+ # Clean up the original video file after processing (keep frames in memory)
316
+ st.info("🗑️ Cleaning up original video file to save space...")
317
+ cleanup_video_file(video_path)
318
+
319
  # Present the options after analysis
320
  st.subheader("What would you like to do next?")
321
  options_col1, options_col2, options_col3 = st.columns(3)
 
338
  except Exception as e:
339
  st.error(f"Error during analysis: {str(e)}")
340
  st.session_state.video_analyzed = False
341
+ # Clean up on error as well
342
+ if video_path and os.path.exists(video_path):
343
+ cleanup_video_file(video_path)
344
 
345
  # Show action buttons and their results (only if analysis is complete)
346
  if st.session_state.video_analyzed:
app/utils/video_downloader.py CHANGED
@@ -6,6 +6,88 @@ import os
6
  import yt_dlp
7
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  def download_youtube_video(url, output_dir="downloads"):
10
  """
11
  Download a YouTube video from the provided URL using yt-dlp
 
6
  import yt_dlp
7
 
8
 
9
+ def cleanup_video_file(video_path):
10
+ """
11
+ Delete a specific video file after processing
12
+
13
+ Args:
14
+ video_path (str): Path to the video file to delete
15
+
16
+ Returns:
17
+ bool: True if file was deleted successfully, False otherwise
18
+ """
19
+ try:
20
+ if os.path.exists(video_path):
21
+ os.remove(video_path)
22
+ print(f"Cleaned up video file: {video_path}")
23
+ return True
24
+ else:
25
+ print(f"Video file not found for cleanup: {video_path}")
26
+ return False
27
+ except Exception as e:
28
+ print(f"Error cleaning up video file {video_path}: {str(e)}")
29
+ return False
30
+
31
+
32
+ def cleanup_downloads_directory(output_dir="downloads", keep_annotated=True):
33
+ """
34
+ Clean up downloaded videos from the downloads directory
35
+
36
+ Args:
37
+ output_dir (str): Directory containing downloaded videos
38
+ keep_annotated (bool): Whether to keep annotated videos (default: True)
39
+
40
+ Returns:
41
+ dict: Cleanup results with files removed and space freed
42
+ """
43
+ try:
44
+ if not os.path.exists(output_dir):
45
+ return {"files_removed": 0, "space_freed_mb": 0}
46
+
47
+ files_removed = 0
48
+ space_freed = 0
49
+
50
+ for filename in os.listdir(output_dir):
51
+ file_path = os.path.join(output_dir, filename)
52
+
53
+ # Skip if not a file
54
+ if not os.path.isfile(file_path):
55
+ continue
56
+
57
+ # Skip annotated videos if keep_annotated is True
58
+ if keep_annotated and "_annotated" in filename:
59
+ continue
60
+
61
+ # Skip pro reference videos (they can be reused)
62
+ if "pro_reference" in filename:
63
+ continue
64
+
65
+ # Get file size before deletion
66
+ try:
67
+ file_size = os.path.getsize(file_path)
68
+ space_freed += file_size
69
+
70
+ # Remove the file
71
+ os.remove(file_path)
72
+ files_removed += 1
73
+ print(f"Cleaned up: {filename}")
74
+
75
+ except Exception as e:
76
+ print(f"Error removing {filename}: {str(e)}")
77
+
78
+ # Convert bytes to MB
79
+ space_freed_mb = space_freed / (1024 * 1024)
80
+
81
+ return {
82
+ "files_removed": files_removed,
83
+ "space_freed_mb": round(space_freed_mb, 2)
84
+ }
85
+
86
+ except Exception as e:
87
+ print(f"Error during cleanup: {str(e)}")
88
+ return {"error": str(e)}
89
+
90
+
91
  def download_youtube_video(url, output_dir="downloads"):
92
  """
93
  Download a YouTube video from the provided URL using yt-dlp