jonathanagustin
commited on
Commit
•
644db4b
1
Parent(s):
1a3c8fe
Update app.py
Browse files
app.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
"""
|
2 |
-
This module integrates real-time object detection into live YouTube streams using the YOLO
|
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 |
-
- `
|
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 |
-
|
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 |
-
`
|
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 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
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("
|
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='
|
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",
|
|
|
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",
|
|
|
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",
|
|
|
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 = []
|