jonathanagustin commited on
Commit
644db4b
1 Parent(s): 1a3c8fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -25
app.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- This module integrates real-time object detection into live YouTube streams using the YOLO (You Only Look Once) model and provides an interactive user interface through Gradio. It allows users to search for live YouTube streams and apply object detection to these streams in real time.
3
 
4
  Main Features:
5
  - Search for live YouTube streams using specific queries.
@@ -18,7 +18,7 @@ Dependencies:
18
  - NumPy: Utilized for numerical operations on image data.
19
  - Pillow (`PIL`): A Python Imaging Library for opening, manipulating, and saving images.
20
  - Ultralytics YOLO: The YOLO model implementation for object detection.
21
- - `youtube-search-python`: Used for searching YouTube without API keys.
22
  - `imageio`: For reading frames from live streams using FFmpeg.
23
 
24
  Usage:
@@ -36,7 +36,7 @@ import numpy as np
36
  from ultralytics import YOLO
37
  import streamlink
38
  from PIL import Image
39
- from youtubesearchpython import CustomSearch, SearchMode
40
  import imageio.v3 as iio
41
 
42
  logging.basicConfig(level=logging.DEBUG)
@@ -45,10 +45,11 @@ logging.basicConfig(level=logging.DEBUG)
45
  class SearchService:
46
  """
47
  SearchService provides functionality to search for YouTube videos using the
48
- `youtube-search-python` library and retrieve live stream URLs using the Streamlink library.
49
 
50
  Methods:
51
  search: Searches YouTube for videos matching a query and live filter.
 
52
  get_youtube_url: Constructs a YouTube URL for a given video ID.
53
  get_stream: Retrieves the stream URL for a given YouTube video URL.
54
  """
@@ -65,22 +66,43 @@ class SearchService:
65
  :return: A list of search results, each a dictionary with video details.
66
  :rtype: List[Dict[str, Any]]
67
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  results = []
69
- # Apply live filter if needed
70
- if live:
71
- # Use CustomSearch with SearchMode.live to filter live videos
72
- search = CustomSearch(query, SearchMode.live, limit=20)
73
- else:
74
- # Use CustomSearch with default mode for regular videos
75
- search = CustomSearch(query, SearchMode.videos, limit=20)
76
- for result in search.result()['result']:
77
- if 'video' in result:
78
- video = result['video']
79
- results.append({
80
- 'video_id': video['id'],
81
- 'thumbnail_url': video['thumbnails'][-1]['url'],
82
- 'title': video['title'],
83
- })
 
 
 
 
84
  return results
85
 
86
  @staticmethod
@@ -138,7 +160,7 @@ class LiveYouTubeObjectDetector:
138
  def __init__(self):
139
  """Initializes the LiveYouTubeObjectDetector with YOLO model and UI components."""
140
  logging.getLogger().setLevel(logging.DEBUG)
141
- self.model = YOLO("yolov8x.pt")
142
  self.model.fuse()
143
  self.streams = self.get_live_streams("world live cams")
144
 
@@ -173,7 +195,7 @@ class LiveYouTubeObjectDetector:
173
  if not stream_url:
174
  return None
175
  try:
176
- reader = iio.imiter(stream_url, plugin='ffmpeg', fps=1)
177
  loop = asyncio.get_event_loop()
178
  frame = await loop.run_in_executor(None, next, reader, None)
179
  if frame is None:
@@ -243,12 +265,14 @@ class LiveYouTubeObjectDetector:
243
  The Gradio interface allows users to search for live YouTube streams, select a stream,
244
  and run object detection on the selected live stream.
245
  """
246
- with gr.Blocks(title="Object Detection in Live YouTube Streams", css=".gradio-container {background-color: #f5f5f5}", theme=gr.themes.Soft()) as app:
 
247
  gr.HTML("<h1 style='text-align: center; color: #1E88E5;'>Object Detection in Live YouTube Streams</h1>")
248
  with gr.Tabs():
249
  with gr.TabItem("Live Stream Detection"):
250
  with gr.Row():
251
- stream_input = gr.Textbox(label="URL of Live YouTube Video", placeholder="Enter YouTube live stream URL...", interactive=True)
 
252
  submit_button = gr.Button("Detect Objects", variant="primary")
253
  annotated_image = gr.AnnotatedImage(label="Detection Result", height=480)
254
  status_text = gr.Markdown(value="Status: Ready", visible=False)
@@ -268,13 +292,14 @@ class LiveYouTubeObjectDetector:
268
 
269
  with gr.TabItem("Search Live Streams"):
270
  with gr.Row():
271
- search_input = gr.Textbox(label="Search for Live YouTube Streams", placeholder="Enter search query...", interactive=True)
 
272
  search_button = gr.Button("Search", variant="secondary")
273
  gallery = gr.Gallery(label="Live YouTube Streams", show_label=False).style(grid=[4], height="auto")
274
  gallery.style(item_height=150)
275
  status_text_search = gr.Markdown(value="", visible=False)
276
 
277
- def search_live_streams(query):
278
  status_text_search.update(value="Searching...", visible=True)
279
  self.streams = self.get_live_streams(query)
280
  gallery_items = []
 
1
  """
2
+ This module integrates real-time object detection into live YouTube streams using the YOLO model and provides an interactive user interface through Gradio. It allows users to search for live YouTube streams and apply object detection to these streams in real time.
3
 
4
  Main Features:
5
  - Search for live YouTube streams using specific queries.
 
18
  - NumPy: Utilized for numerical operations on image data.
19
  - Pillow (`PIL`): A Python Imaging Library for opening, manipulating, and saving images.
20
  - Ultralytics YOLO: The YOLO model implementation for object detection.
21
+ - `innertube`: Used for interacting with YouTube's internal API.
22
  - `imageio`: For reading frames from live streams using FFmpeg.
23
 
24
  Usage:
 
36
  from ultralytics import YOLO
37
  import streamlink
38
  from PIL import Image
39
+ import innertube
40
  import imageio.v3 as iio
41
 
42
  logging.basicConfig(level=logging.DEBUG)
 
45
  class SearchService:
46
  """
47
  SearchService provides functionality to search for YouTube videos using the
48
+ `innertube` library and retrieve live stream URLs using the Streamlink library.
49
 
50
  Methods:
51
  search: Searches YouTube for videos matching a query and live filter.
52
+ parse: Parses raw search response data into a list of video details.
53
  get_youtube_url: Constructs a YouTube URL for a given video ID.
54
  get_stream: Retrieves the stream URL for a given YouTube video URL.
55
  """
 
66
  :return: A list of search results, each a dictionary with video details.
67
  :rtype: List[Dict[str, Any]]
68
  """
69
+ client = innertube.InnerTube()
70
+ params = "EgJAAQ%3D%3D" if live else None # 'Live' filter code
71
+
72
+ response = client.search(query=query, params=params)
73
+ results = SearchService.parse(response)
74
+ return results
75
+
76
+ @staticmethod
77
+ def parse(response: Dict[str, Any]) -> List[Dict[str, Any]]:
78
+ """
79
+ Parses the raw search response data into a list of video details.
80
+
81
+ :param response: The raw search response data from YouTube.
82
+ :type response: Dict[str, Any]
83
+ :return: A list of parsed video details.
84
+ :rtype: List[Dict[str, Any]]
85
+ """
86
  results = []
87
+ try:
88
+ contents = response["contents"]["twoColumnSearchResultsRenderer"]["primaryContents"]["sectionListRenderer"]["contents"]
89
+ for content in contents:
90
+ items = content.get("itemSectionRenderer", {}).get("contents", [])
91
+ for item in items:
92
+ video_renderer = item.get("videoRenderer")
93
+ if video_renderer:
94
+ video_id = video_renderer.get("videoId")
95
+ thumbnails = video_renderer.get("thumbnail", {}).get("thumbnails", [])
96
+ title_runs = video_renderer.get("title", {}).get("runs", [])
97
+ title = "".join([run.get("text", "") for run in title_runs])
98
+ thumbnail_url = thumbnails[-1].get("url") if thumbnails else ""
99
+ results.append({
100
+ 'video_id': video_id,
101
+ 'thumbnail_url': thumbnail_url,
102
+ 'title': title,
103
+ })
104
+ except Exception as e:
105
+ logging.error(f"Error parsing search results: {e}")
106
  return results
107
 
108
  @staticmethod
 
160
  def __init__(self):
161
  """Initializes the LiveYouTubeObjectDetector with YOLO model and UI components."""
162
  logging.getLogger().setLevel(logging.DEBUG)
163
+ self.model = YOLO("yolov8n.pt")
164
  self.model.fuse()
165
  self.streams = self.get_live_streams("world live cams")
166
 
 
195
  if not stream_url:
196
  return None
197
  try:
198
+ reader = iio.imiter(stream_url, plugin='pyav', thread_type='AUTO')
199
  loop = asyncio.get_event_loop()
200
  frame = await loop.run_in_executor(None, next, reader, None)
201
  if frame is None:
 
265
  The Gradio interface allows users to search for live YouTube streams, select a stream,
266
  and run object detection on the selected live stream.
267
  """
268
+ with gr.Blocks(title="Object Detection in Live YouTube Streams",
269
+ css=".gradio-container {background-color: #f5f5f5}", theme=gr.themes.Soft()) as app:
270
  gr.HTML("<h1 style='text-align: center; color: #1E88E5;'>Object Detection in Live YouTube Streams</h1>")
271
  with gr.Tabs():
272
  with gr.TabItem("Live Stream Detection"):
273
  with gr.Row():
274
+ stream_input = gr.Textbox(label="URL of Live YouTube Video",
275
+ placeholder="Enter YouTube live stream URL...", interactive=True)
276
  submit_button = gr.Button("Detect Objects", variant="primary")
277
  annotated_image = gr.AnnotatedImage(label="Detection Result", height=480)
278
  status_text = gr.Markdown(value="Status: Ready", visible=False)
 
292
 
293
  with gr.TabItem("Search Live Streams"):
294
  with gr.Row():
295
+ search_input = gr.Textbox(label="Search for Live YouTube Streams",
296
+ placeholder="Enter search query...", interactive=True)
297
  search_button = gr.Button("Search", variant="secondary")
298
  gallery = gr.Gallery(label="Live YouTube Streams", show_label=False).style(grid=[4], height="auto")
299
  gallery.style(item_height=150)
300
  status_text_search = gr.Markdown(value="", visible=False)
301
 
302
+ async def search_live_streams(query):
303
  status_text_search.update(value="Searching...", visible=True)
304
  self.streams = self.get_live_streams(query)
305
  gallery_items = []