jonathanagustin commited on
Commit
933222d
1 Parent(s): 1366c9e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -73
app.py CHANGED
@@ -41,37 +41,18 @@ class SearchService:
41
  @staticmethod
42
  def parse(data: Dict[str, Any]) -> List[Dict[str, Any]]:
43
  results = []
44
- items = []
45
-
46
- contents = (
47
- data.get("contents", {})
48
- .get("twoColumnSearchResultsRenderer", {})
49
- .get("primaryContents", {})
50
- .get("sectionListRenderer", {})
51
- .get("contents", [])
52
- )
53
- if contents:
54
- items = contents[0].get("itemSectionRenderer", {}).get("contents", [])
55
-
56
  for item in items:
57
  if "videoRenderer" in item:
58
  renderer = item["videoRenderer"]
59
- video_id = renderer.get("videoId", "")
60
- thumbnail_urls = [
61
- thumb.get("url", "")
62
- for thumb in renderer.get("thumbnail", {}).get("thumbnails", [])
63
- ]
64
- title_text = "".join(
65
- [
66
- run.get("text", "")
67
- for run in renderer.get("title", {}).get("runs", [])
68
- ]
69
- )
70
-
71
  result = {
72
  "video_id": video_id,
73
- "thumbnail_urls": thumbnail_urls,
74
- "title": title_text,
75
  }
76
  results.append(result)
77
 
@@ -104,20 +85,7 @@ class SearchService:
104
  logging.warning(f"An error occurred: {e}")
105
  return None
106
 
107
-
108
- INITIAL_STREAMS = []
109
- for result in SearchService.search("world live cams", SearchFilter.LIVE):
110
- INITIAL_STREAMS.append(
111
- {
112
- "thumbnail_url": result["thumbnail_urls"][-1]
113
- if result["thumbnail_urls"]
114
- else "",
115
- "title": result["title"],
116
- "video_id": result["video_id"],
117
- "label": result["video_id"],
118
- }
119
- )
120
-
121
  class YouTubeObjectDetection:
122
  def __init__(self):
123
  logging.getLogger().setLevel(logging.DEBUG)
@@ -131,21 +99,14 @@ class YouTubeObjectDetection:
131
 
132
  # Gradio UI Elements
133
  initial_gallery_items = [(stream["thumbnail_url"], stream["title"]) for stream in self.streams]
134
- self.gallery = gr.Gallery(
135
- label="Live YouTube Videos",
136
- value=initial_gallery_items,
137
- show_label=True,
138
- columns=[3],
139
- rows=[10],
140
- object_fit="contain",
141
- height="auto",
142
- allow_preview=False,
143
- )
144
  self.search_input = gr.Textbox(label="Search Live YouTube Videos")
145
  self.stream_input = gr.Textbox(label="URL of Live YouTube Video")
146
  self.annotated_image = gr.AnnotatedImage(show_label=False)
147
  self.search_button = gr.Button("Search", size="lg")
148
  self.submit_button = gr.Button("Detect Objects", variant="primary", size="lg")
 
 
149
 
150
  @staticmethod
151
  def download_font(url, save_path):
@@ -157,7 +118,7 @@ class YouTubeObjectDetection:
157
  def capture_frame(self, url):
158
  stream_url = SearchService.get_stream_url(url)
159
  if not stream_url:
160
- return self.create_error_image("No stream found"), []
161
  frame = self.get_frame(stream_url)
162
  if frame is None:
163
  return self.create_error_image("Failed to capture frame"), []
@@ -195,8 +156,7 @@ class YouTubeObjectDetection:
195
  annotations.append((bbox, class_name))
196
  return annotations
197
 
198
- @staticmethod
199
- def create_error_image(message):
200
  error_image = np.zeros((1920, 1080, 3), dtype=np.uint8)
201
  pil_image = Image.fromarray(error_image)
202
  draw = ImageDraw.Draw(pil_image)
@@ -214,8 +174,7 @@ class YouTubeObjectDetection:
214
  streams.append(
215
  {
216
  "thumbnail_url": result["thumbnail_urls"][0]
217
- if result["thumbnail_urls"]
218
- else "",
219
  "title": result["title"],
220
  "video_id": result["video_id"],
221
  "label": result["video_id"],
@@ -224,13 +183,8 @@ class YouTubeObjectDetection:
224
  return streams
225
 
226
  def render(self):
227
- with gr.Blocks(
228
- title="Object Detection in Live YouTube Streams",
229
- css="footer {visibility: hidden}",
230
- ) as app:
231
- gr.HTML(
232
- "<center><h1><b>Object Detection in Live YouTube Streams</b></h1></center>"
233
- )
234
  with gr.Column():
235
  with gr.Group():
236
  with gr.Row():
@@ -244,16 +198,12 @@ class YouTubeObjectDetection:
244
  with gr.Row():
245
  self.gallery.render()
246
 
247
- @self.gallery.select(
248
- inputs=None, outputs=[self.annotated_image, self.stream_input]
249
- )
250
  def on_gallery_select(evt: gr.SelectData):
251
  selected_index = evt.index
252
  if selected_index is not None and selected_index < len(self.streams):
253
  selected_stream = self.streams[selected_index]
254
- stream_url = SearchService.get_youtube_url(
255
- selected_stream["video_id"]
256
- )
257
  frame_output = self.capture_frame(stream_url)
258
  return frame_output, stream_url
259
  return None, ""
@@ -261,17 +211,14 @@ class YouTubeObjectDetection:
261
  @self.search_button.click(inputs=[self.search_input], outputs=[self.gallery])
262
  def on_search_click(query):
263
  self.streams = self.fetch_live_streams(query)
264
- gallery_items = [
265
- (stream["thumbnail_url"], stream["title"])
266
- for stream in self.streams
267
- ]
268
  return gallery_items
269
 
270
  @self.submit_button.click(inputs=[self.stream_input], outputs=[self.annotated_image])
271
  def annotate_stream(url):
272
  return self.capture_frame(url)
273
 
274
- return app.queue().launch(show_api=False)
275
 
276
  if __name__ == "__main__":
277
  YouTubeObjectDetection().render()
 
41
  @staticmethod
42
  def parse(data: Dict[str, Any]) -> List[Dict[str, Any]]:
43
  results = []
44
+ contents = data["contents"]["twoColumnSearchResultsRenderer"]["primaryContents"]["sectionListRenderer"]["contents"]
45
+ items = contents[0]["itemSectionRenderer"]["contents"] if contents else []
 
 
 
 
 
 
 
 
 
 
46
  for item in items:
47
  if "videoRenderer" in item:
48
  renderer = item["videoRenderer"]
49
+ video_id = renderer["videoId"]
50
+ title = "".join(run["text"] for run in renderer["title"]["runs"])
51
+ thumbnail_url = renderer["thumbnail"]["thumbnails"][-1]["url"]
 
 
 
 
 
 
 
 
 
52
  result = {
53
  "video_id": video_id,
54
+ "thumbnail_url": thumbnail_url,
55
+ "title": title,
56
  }
57
  results.append(result)
58
 
 
85
  logging.warning(f"An error occurred: {e}")
86
  return None
87
 
88
+ INITIAL_STREAMS = SearchService.search("world live cams", SearchFilter.LIVE)
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  class YouTubeObjectDetection:
90
  def __init__(self):
91
  logging.getLogger().setLevel(logging.DEBUG)
 
99
 
100
  # Gradio UI Elements
101
  initial_gallery_items = [(stream["thumbnail_url"], stream["title"]) for stream in self.streams]
102
+ self.gallery = gr.Gallery(label="Live YouTube Videos", value=initial_gallery_items, show_label=True, columns=[3], rows=[10], object_fit="contain", height="auto", allow_preview=False)
 
 
 
 
 
 
 
 
 
103
  self.search_input = gr.Textbox(label="Search Live YouTube Videos")
104
  self.stream_input = gr.Textbox(label="URL of Live YouTube Video")
105
  self.annotated_image = gr.AnnotatedImage(show_label=False)
106
  self.search_button = gr.Button("Search", size="lg")
107
  self.submit_button = gr.Button("Detect Objects", variant="primary", size="lg")
108
+ self.page_title = gr.HTML("<center><h1><b>Object Detection in Live YouTube Streams</b></h1></center>")
109
+
110
 
111
  @staticmethod
112
  def download_font(url, save_path):
 
118
  def capture_frame(self, url):
119
  stream_url = SearchService.get_stream_url(url)
120
  if not stream_url:
121
+ return [], []
122
  frame = self.get_frame(stream_url)
123
  if frame is None:
124
  return self.create_error_image("Failed to capture frame"), []
 
156
  annotations.append((bbox, class_name))
157
  return annotations
158
 
159
+ def create_error_image(self, message):
 
160
  error_image = np.zeros((1920, 1080, 3), dtype=np.uint8)
161
  pil_image = Image.fromarray(error_image)
162
  draw = ImageDraw.Draw(pil_image)
 
174
  streams.append(
175
  {
176
  "thumbnail_url": result["thumbnail_urls"][0]
177
+ if result["thumbnail_urls"] else "",
 
178
  "title": result["title"],
179
  "video_id": result["video_id"],
180
  "label": result["video_id"],
 
183
  return streams
184
 
185
  def render(self):
186
+ with gr.Blocks(title="Object Detection in Live YouTube Streams", css="footer {visibility: hidden}") as app:
187
+ self.page_title.render()
 
 
 
 
 
188
  with gr.Column():
189
  with gr.Group():
190
  with gr.Row():
 
198
  with gr.Row():
199
  self.gallery.render()
200
 
201
+ @self.gallery.select(inputs=None, outputs=[self.annotated_image, self.stream_input])
 
 
202
  def on_gallery_select(evt: gr.SelectData):
203
  selected_index = evt.index
204
  if selected_index is not None and selected_index < len(self.streams):
205
  selected_stream = self.streams[selected_index]
206
+ stream_url = SearchService.get_youtube_url(selected_stream["video_id"])
 
 
207
  frame_output = self.capture_frame(stream_url)
208
  return frame_output, stream_url
209
  return None, ""
 
211
  @self.search_button.click(inputs=[self.search_input], outputs=[self.gallery])
212
  def on_search_click(query):
213
  self.streams = self.fetch_live_streams(query)
214
+ gallery_items = [(stream["thumbnail_url"], stream["title"]) for stream in self.streams]
 
 
 
215
  return gallery_items
216
 
217
  @self.submit_button.click(inputs=[self.stream_input], outputs=[self.annotated_image])
218
  def annotate_stream(url):
219
  return self.capture_frame(url)
220
 
221
+ return app.queue().launch(show_api=False, debug=True, quiet=False, share=False)
222
 
223
  if __name__ == "__main__":
224
  YouTubeObjectDetection().render()