eusholli commited on
Commit
cf36ac6
·
1 Parent(s): c5be3c0

add video progress bar and save annotated video button

Browse files
Files changed (3) hide show
  1. .gitignore +1 -0
  2. app.py +49 -27
  3. requirements.txt +2 -1
.gitignore CHANGED
@@ -126,6 +126,7 @@ models/*
126
 
127
  # All cached movie files
128
  *.mp4
 
129
 
130
  # All cached model files
131
  *.pt
 
126
 
127
  # All cached movie files
128
  *.mp4
129
+ *.MOV
130
 
131
  # All cached model files
132
  *.pt
app.py CHANGED
@@ -2,6 +2,8 @@ from ultralytics import YOLO
2
  import time
3
  import os
4
  import logging
 
 
5
 
6
  import av
7
  import cv2
@@ -138,7 +140,7 @@ def analyze_frame(frame: np.ndarray):
138
 
139
  if show_labels in ["Object Detection", "Both"]:
140
  # Run YOLOv8 object detection on the frame
141
- object_results = object_model(frame)
142
 
143
  for i, box in enumerate(object_results[0].boxes):
144
  class_id = int(box.cls)
@@ -151,7 +153,7 @@ def analyze_frame(frame: np.ndarray):
151
 
152
  if show_labels in ["Pose Estimation", "Both"]:
153
  # Run YOLOv8 pose estimation on the frame
154
- pose_results = pose_model(frame)
155
 
156
  for i, box in enumerate(pose_results[0].boxes):
157
  class_id = int(box.cls)
@@ -381,7 +383,7 @@ st.markdown(
381
 
382
 
383
  def analysis_init():
384
- global yt_error, analysis_time, show_labels, labels_placeholder, input_subheader, input_placeholder, output_placeholder
385
 
386
  yt_error.empty() # Placeholder for analysis time
387
 
@@ -397,7 +399,11 @@ def analysis_init():
397
  ("Object Detection", "Pose Estimation", "Both"),
398
  index=2 # Set default to "Both" (index 2)
399
  )
 
 
 
400
  labels_placeholder = st.empty() # Placeholder for labels
 
401
 
402
 
403
  # Function to publish frames and results to the Streamlit UI
@@ -460,8 +466,25 @@ if uploaded_file is not None or image_url:
460
  # Function to process video files
461
  # This function reads frames from a video file, analyzes each frame for face detection and sentiment analysis,
462
  # and updates the Streamlit UI with the current input frame, analyzed frame, and detected labels.
 
463
  def process_video(video_path):
464
  cap = cv2.VideoCapture(video_path) # Open the video file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
  while cap.isOpened():
466
  ret, frame = cap.read() # Read a frame from the video
467
  if not ret:
@@ -472,35 +495,34 @@ def process_video(video_path):
472
 
473
  # Analyze the frame for face detection and sentiment analysis
474
  analyze_frame(rgb_frame)
475
- publish_frame() # Publish the results
476
 
477
- cap.release() # Release the video capture object
 
478
 
 
479
 
480
- # Function to get the video stream URL from YouTube using yt-dlp
 
 
 
 
481
 
482
- def get_youtube_stream_url(youtube_url):
483
- ydl_opts = {
484
- 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
485
- 'quiet': True,
486
- 'no_warnings': True,
487
- }
 
 
 
 
 
 
 
 
488
 
489
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
490
- try:
491
- info_dict = ydl.extract_info(youtube_url, download=False)
492
- if 'url' in info_dict:
493
- return info_dict['url']
494
- elif 'entries' in info_dict:
495
- return info_dict['entries'][0]['url']
496
- else:
497
- yt_error.error(
498
- "Unable to extract video URL. The video might be unavailable or restricted.")
499
- return None
500
- except yt_dlp.utils.DownloadError as e:
501
- yt_error.error(
502
- f"Error: Unable to process the YouTube URL. {str(e)}")
503
- return None
504
 
505
  # Function to get video URL using Cobalt API
506
 
 
2
  import time
3
  import os
4
  import logging
5
+ import tempfile
6
+
7
 
8
  import av
9
  import cv2
 
140
 
141
  if show_labels in ["Object Detection", "Both"]:
142
  # Run YOLOv8 object detection on the frame
143
+ object_results = object_model(frame, conf=0.5)
144
 
145
  for i, box in enumerate(object_results[0].boxes):
146
  class_id = int(box.cls)
 
153
 
154
  if show_labels in ["Pose Estimation", "Both"]:
155
  # Run YOLOv8 pose estimation on the frame
156
+ pose_results = pose_model(frame, conf=0.5)
157
 
158
  for i, box in enumerate(pose_results[0].boxes):
159
  class_id = int(box.cls)
 
383
 
384
 
385
  def analysis_init():
386
+ global progress_bar, status_text, download_button, yt_error, analysis_time, show_labels, labels_placeholder, input_subheader, input_placeholder, output_placeholder
387
 
388
  yt_error.empty() # Placeholder for analysis time
389
 
 
399
  ("Object Detection", "Pose Estimation", "Both"),
400
  index=2 # Set default to "Both" (index 2)
401
  )
402
+ # Create a progress bar
403
+ progress_bar = st.empty()
404
+ status_text = st.empty()
405
  labels_placeholder = st.empty() # Placeholder for labels
406
+ download_button = st.empty() # Placeholder for download button
407
 
408
 
409
  # Function to publish frames and results to the Streamlit UI
 
466
  # Function to process video files
467
  # This function reads frames from a video file, analyzes each frame for face detection and sentiment analysis,
468
  # and updates the Streamlit UI with the current input frame, analyzed frame, and detected labels.
469
+ # Function to process video files
470
  def process_video(video_path):
471
  cap = cv2.VideoCapture(video_path) # Open the video file
472
+
473
+ # Create a temporary file for the annotated video
474
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as temp_video:
475
+ temp_video_path = temp_video.name
476
+
477
+ # save_annotated_video(video_path, temp_video_path)
478
+
479
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
480
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
481
+ fps = int(cap.get(cv2.CAP_PROP_FPS))
482
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
483
+
484
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
485
+ out = cv2.VideoWriter(temp_video_path, fourcc, fps, (width, height))
486
+
487
+ frame_count = 0
488
  while cap.isOpened():
489
  ret, frame = cap.read() # Read a frame from the video
490
  if not ret:
 
495
 
496
  # Analyze the frame for face detection and sentiment analysis
497
  analyze_frame(rgb_frame)
498
+ analyzed_frame = img_container["analyzed"]
499
 
500
+ if analyzed_frame is not None:
501
+ out.write(cv2.cvtColor(analyzed_frame, cv2.COLOR_RGB2BGR))
502
 
503
+ publish_frame() # Publish the results
504
 
505
+ # Update progress
506
+ frame_count += 1
507
+ progress = min(100, int(frame_count / total_frames * 100))
508
+ progress_bar.progress(progress)
509
+ status_text.text(f"Processing video: {progress}% complete")
510
 
511
+ cap.release() # Release the video capture object
512
+ out.release()
513
+
514
+ # Add download button for annotated video
515
+ with open(temp_video_path, "rb") as file:
516
+ download_button.download_button(
517
+ label="Download Annotated Video",
518
+ data=file,
519
+ file_name="annotated_video.mp4",
520
+ mime="video/mp4"
521
+ )
522
+
523
+ # Clean up the temporary file
524
+ os.unlink(temp_video_path)
525
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
 
527
  # Function to get video URL using Cobalt API
528
 
requirements.txt CHANGED
@@ -6,4 +6,5 @@ setuptools
6
  streamlit_webrtc
7
  twilio
8
  ultralytics
9
- watchdog
 
 
6
  streamlit_webrtc
7
  twilio
8
  ultralytics
9
+ watchdog
10
+ tempfile