Nymbo commited on
Commit
2b65731
·
verified ·
1 Parent(s): f77bbf5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -163
app.py CHANGED
@@ -1,226 +1,172 @@
1
  import gradio as gr
2
- import requests
3
  import yt_dlp
4
  import cv2
5
  from google_img_source_search import ReverseImageSearcher
6
  from PIL import Image
7
- import os
8
  import uuid
9
- from pathlib import Path
10
 
11
- def ensure_directory(directory):
12
- Path(directory).mkdir(parents=True, exist_ok=True)
13
- return directory
14
-
15
- # Create a unique working directory for each session
16
- def get_session_dir():
17
- session_id = str(uuid.uuid4())
18
- return ensure_directory(f"temp_{session_id}")
19
 
20
  def dl(inp):
21
- if not inp or not inp.strip():
22
- return None, gr.HTML("Please provide a valid URL"), "", ""
23
-
24
- work_dir = get_session_dir()
25
  out = None
 
26
  try:
27
- # Sanitize input filename
28
  inp_out = inp.replace("https://", "").replace("/", "_").replace(".", "_").replace("=", "_").replace("?", "_")
29
- output_path = os.path.join(work_dir, f"{inp_out}.mp4")
30
-
31
- ydl_opts = {
32
- 'format': 'best[ext=mp4]',
33
- 'outtmpl': output_path,
34
- 'quiet': True,
35
- 'no_warnings': True
36
- }
37
-
38
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
39
- ydl.download([inp])
40
-
41
- if os.path.exists(output_path):
42
- out = output_path
43
- print(f"Successfully downloaded video to: {out}")
44
  else:
45
- raise Exception("Video download failed")
46
-
 
 
47
  except Exception as e:
48
- print(f"Download error: {str(e)}")
49
- return None, gr.HTML(f"Error downloading video: {str(e)}"), "", ""
50
-
51
  return out, gr.HTML(""), "", ""
52
 
53
  def process_vid(file, cur_frame, every_n):
54
- if not file or not os.path.exists(file):
55
- return gr.HTML("No valid video file provided."), "", ""
56
-
57
- work_dir = os.path.dirname(file)
58
- capture = cv2.VideoCapture(file)
59
-
60
- if not capture.isOpened():
61
- return gr.HTML("Failed to open video file."), "", ""
62
-
63
  frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
64
  rev_img_searcher = ReverseImageSearcher()
65
  html_out = ""
66
- count = int(every_n) if every_n else 10
67
- start_frame = int(cur_frame) if cur_frame and cur_frame.strip() else 0
68
-
 
 
69
  try:
70
- for i in range(start_frame, frame_count-1):
71
  if count == int(every_n):
72
  count = 1
73
- print(f"Processing frame {i}")
74
-
75
- # Read frame
76
  capture.set(cv2.CAP_PROP_POS_FRAMES, i)
77
- ret, frame = capture.read()
78
-
79
- if not ret or frame is None:
80
  print(f"Failed to read frame {i}")
81
  continue
82
-
83
- # Save frame
84
- frame_path = os.path.join(work_dir, f"frame_{i}.png")
85
- if not cv2.imwrite(frame_path, frame):
86
- print(f"Failed to write frame {i}")
87
- continue
88
-
89
- # Process frame
90
- out_url = f'https://nymbo-reverse-image.hf.space/file={os.path.abspath(frame_path)}'
91
  res = rev_img_searcher.search(out_url)
92
-
93
- if res:
94
- out_cnt = 0
95
  for search_item in res:
 
96
  out_cnt += 1
97
- html_out += f"""
 
 
 
 
 
 
98
  <div>
99
- <h3>Result {out_cnt}</h3>
100
- <p>Title: {search_item.page_title}</p>
101
- <p>Site: <a href='{search_item.page_url}' target='_blank'>{search_item.page_url}</a></p>
102
- <p>Image: <a href='{search_item.image_url}' target='_blank'>{search_item.image_url}</a></p>
103
- <img class='my_im' src='{search_item.image_url}' alt='Search result'>
104
- </div>
105
- """
106
- return gr.HTML(f'<h2>Total Found: {out_cnt}</h2>{html_out}'), f"Found frame: {i}", i+int(every_n)
107
-
108
  count += 1
109
-
110
  except Exception as e:
111
- import traceback
112
- error_msg = f"Error processing video: {str(e)}\n{traceback.format_exc()}"
113
- print(error_msg)
114
- return gr.HTML(error_msg), "", ""
115
- finally:
116
- capture.release()
117
-
118
- return gr.HTML('No matches found in processed frames.'), "", ""
119
 
120
  def process_im(file, url):
121
  if not url.startswith("https://nymbo"):
122
  return url
123
-
124
- work_dir = get_session_dir()
125
- output_path = os.path.join(work_dir, "processed_image.png")
126
-
127
- try:
128
  read_file = Image.open(file)
129
- read_file.save(output_path)
130
- return f'https://nymbo-reverse-image.hf.space/file={os.path.abspath(output_path)}'
131
- except Exception as e:
132
- print(f"Error processing image: {str(e)}")
133
- return url
134
 
135
  def rev_im(image):
136
- if not image or not os.path.exists(image):
137
- return gr.HTML("No valid image provided.")
138
-
139
- work_dir = get_session_dir()
140
- html_out = ""
141
-
142
- try:
143
- # Read and write image
144
- img = cv2.imread(image)
145
- if img is None:
146
- return gr.HTML("Failed to read image file.")
147
-
148
- output_path = os.path.join(work_dir, "search_image.png")
149
- if not cv2.imwrite(output_path, img):
150
- return gr.HTML("Failed to process image file.")
151
-
152
- # Search image
153
- out_url = f'https://nymbo-reverse-image.hf.space/file={os.path.abspath(output_path)}'
154
- rev_img_searcher = ReverseImageSearcher()
155
- res = rev_img_searcher.search(out_url)
156
-
157
- count = 0
158
- for search_item in res:
159
- count += 1
160
- html_out += f"""
161
- <div>
162
- <h3>Result {count}</h3>
163
- <p>Title: {search_item.page_title}</p>
164
- <p>Site: <a href='{search_item.page_url}' target='_blank'>{search_item.page_url}</a></p>
165
- <p>Image: <a href='{search_item.image_url}' target='_blank'>{search_item.image_url}</a></p>
166
- <img class='my_im' src='{search_item.image_url}' alt='Search result'>
167
- </div>
168
- """
169
-
170
- except Exception as e:
171
- return gr.HTML(f"Error processing image: {str(e)}")
172
-
173
- return gr.HTML(f'<h2>Total Found: {count}</h2>{html_out}')
174
 
175
- # Gradio Interface
176
  with gr.Blocks() as app:
177
  with gr.Row():
178
  gr.Column()
179
  with gr.Column():
180
- source_tog = gr.Radio(choices=["Image", "Video"], value="Image", label="Search Type")
181
-
182
- # Image search interface
183
  with gr.Box(visible=True) as im_box:
184
  inp_url = gr.Textbox(label="Image URL")
185
  load_im_btn = gr.Button("Load Image")
186
  inp_im = gr.Image(label="Search Image", type='filepath')
187
- go_btn_im = gr.Button("Search")
188
-
189
- # Video search interface
190
  with gr.Box(visible=False) as vid_box:
191
  vid_url = gr.Textbox(label="Video URL")
192
  vid_url_btn = gr.Button("Load URL")
193
  inp_vid = gr.Video(label="Search Video")
194
  with gr.Row():
195
- every_n = gr.Number(label="Process every N frames", value=10, minimum=1)
196
  stat_box = gr.Textbox(label="Status")
197
  with gr.Row():
198
- go_btn_vid = gr.Button("Start Search")
199
- next_btn = gr.Button("Next Frame")
200
-
201
  gr.Column()
202
-
203
  with gr.Row():
204
- html_out = gr.HTML()
205
  with gr.Row(visible=False):
206
  hid_box = gr.Textbox()
207
 
208
- # Interface logic
209
- def toggle_interface(tog):
210
- return gr.update(visible=tog == "Image"), gr.update(visible=tog == "Video")
211
-
212
- source_tog.change(
213
- toggle_interface,
214
- [source_tog],
215
- [im_box, vid_box],
216
- cancels=[go_btn_vid.click, go_btn_im.click, load_im_btn.click, vid_url_btn.click]
217
- )
218
-
219
- # Button actions
220
- load_im_btn.click(lambda x: x, inp_url, inp_im)
221
  next_btn.click(process_vid, [inp_vid, hid_box, every_n], [html_out, stat_box, hid_box])
222
- vid_url_btn.click(dl, vid_url, [inp_vid, html_out, stat_box, hid_box])
223
- go_btn_vid.click(process_vid, [inp_vid, hid_box, every_n], [html_out, stat_box, hid_box])
224
- go_btn_im.click(rev_im, inp_im, html_out)
 
225
 
226
  app.queue(concurrency_count=20).launch()
 
1
  import gradio as gr
2
+ import requests
3
  import yt_dlp
4
  import cv2
5
  from google_img_source_search import ReverseImageSearcher
6
  from PIL import Image
7
+ import os
8
  import uuid
 
9
 
10
+ uid = uuid.uuid4()
11
+ size_js = """
12
+ function imgSize(){
13
+ var myImg = document.getElementsByClassName("my_im");
14
+ var realWidth = myImg.naturalWidth;
15
+ var realHeight = myImg.naturalHeight;
16
+ alert("Original width=" + realWidth + ", " + "Original height=" + realHeight);
17
+ }"""
18
 
19
  def dl(inp):
 
 
 
 
20
  out = None
21
+ out_file = []
22
  try:
 
23
  inp_out = inp.replace("https://", "").replace("/", "_").replace(".", "_").replace("=", "_").replace("?", "_")
24
+ if "twitter" in inp:
25
+ os.system(f'yt-dlp "{inp}" --extractor-arg "twitter:api=syndication" --trim-filenames 160 -o "{uid}/{inp_out}.mp4" -S res,mp4 --recode mp4')
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  else:
27
+ os.system(f'yt-dlp "{inp}" --trim-filenames 160 -o "{uid}/{inp_out}.mp4" -S res,mp4 --recode mp4')
28
+
29
+ out = f"{uid}/{inp_out}.mp4"
30
+ print(out)
31
  except Exception as e:
32
+ print(e)
 
 
33
  return out, gr.HTML(""), "", ""
34
 
35
  def process_vid(file, cur_frame, every_n):
36
+ new_video_in = str(file)
37
+ capture = cv2.VideoCapture(new_video_in)
 
 
 
 
 
 
 
38
  frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
39
  rev_img_searcher = ReverseImageSearcher()
40
  html_out = ""
41
+ count = int(every_n)
42
+ if cur_frame == "" or cur_frame is None:
43
+ start_frame = 0
44
+ elif cur_frame != "" and cur_frame is not None:
45
+ start_frame = int(cur_frame)
46
  try:
47
+ for i in range(start_frame, frame_count - 1):
48
  if count == int(every_n):
49
  count = 1
50
+ print(i)
 
 
51
  capture.set(cv2.CAP_PROP_POS_FRAMES, i)
52
+ ret, frame_f = capture.read()
53
+ if not ret or frame_f is None:
 
54
  print(f"Failed to read frame {i}")
55
  continue
56
+ cv2.imwrite(f"{uid}-vid_tmp{i}.png", frame_f)
57
+ out = os.path.abspath(f"{uid}-vid_tmp{i}.png")
58
+ out_url = f'https://nymbo-reverse-image.hf.space/file={out}'
59
+ print(out)
 
 
 
 
 
60
  res = rev_img_searcher.search(out_url)
61
+ out_cnt = 0
62
+ if len(res) > 0:
 
63
  for search_item in res:
64
+ print(f'counting {count}')
65
  out_cnt += 1
66
+ out_dict = {
67
+ 'Title': f'{search_item.page_title}',
68
+ 'Site': f'{search_item.page_url}',
69
+ 'Img': f'{search_item.image_url}',
70
+ }
71
+ print(dir(search_item))
72
+ html_out = f"""{html_out}
73
  <div>
74
+ Title: {search_item.page_title}<br>
75
+ Site: <a href='{search_item.page_url}' target='_blank' rel='noopener noreferrer'>{search_item.page_url}</a><br>
76
+ Img: <a href='{search_item.image_url}' target='_blank' rel='noopener noreferrer'>{search_item.image_url}</a><br>
77
+ <img class='my_im' src='{search_item.image_url}'><br>
78
+ </div>"""
79
+ return (gr.HTML(f'<h1>Total Found: {out_cnt}</h1><br>{html_out}'), f"Found frame: {i}", i + int(every_n))
80
+ else:
81
+ pass
 
82
  count += 1
83
+ print(i + 1)
84
  except Exception as e:
85
+ return (gr.HTML(f'{e}'), "", "")
86
+ return (gr.HTML('No frame matches found.'), "", "")
 
 
 
 
 
 
87
 
88
  def process_im(file, url):
89
  if not url.startswith("https://nymbo"):
90
  return url
91
+ else:
 
 
 
 
92
  read_file = Image.open(file)
93
+ read_file.save(f"{uid}-tmp.png")
94
+ action_input = f"{uid}-tmp.png"
95
+ out = os.path.abspath(action_input)
96
+ out_url = f'https://nymbo-reverse-image.hf.space/file={out}'
97
+ return (out_url)
98
 
99
  def rev_im(image):
100
+ out_list = []
101
+ out_im = []
102
+ html_out = """"""
103
+ image = cv2.imread(image)
104
+ cv2.imwrite(f"{uid}-im_tmp.png", image)
105
+ out = os.path.abspath(f"{uid}-im_tmp.png")
106
+ out_url = f'https://nymbo-reverse-image.hf.space/file={out}'
107
+ rev_img_searcher = ReverseImageSearcher()
108
+ res = rev_img_searcher.search(out_url)
109
+ count = 0
110
+ for search_item in res:
111
+ count += 1
112
+ out_dict = {
113
+ 'Title': f'{search_item.page_title}',
114
+ 'Site': f'{search_item.page_url}',
115
+ 'Img': f'{search_item.image_url}',
116
+ }
117
+ print(dir(search_item))
118
+ html_out = f"""{html_out}
119
+ <div>
120
+ Title: {search_item.page_title}<br>
121
+ Site: <a href='{search_item.page_url}' target='_blank' rel='noopener noreferrer'>{search_item.page_url}</a><br>
122
+ Img: <a href='{search_item.image_url}' target='_blank' rel='noopener noreferrer'>{search_item.image_url}</a><br>
123
+ <img class='my_im' src='{search_item.image_url}'><br>
124
+ </div>"""
125
+
126
+ return (gr.HTML(f'<h1>Total Found: {count}</h1><br>{html_out}'))
 
 
 
 
 
 
 
 
 
 
 
127
 
 
128
  with gr.Blocks() as app:
129
  with gr.Row():
130
  gr.Column()
131
  with gr.Column():
132
+ source_tog = gr.Radio(choices=["Image", "Video"], value="Image")
 
 
133
  with gr.Box(visible=True) as im_box:
134
  inp_url = gr.Textbox(label="Image URL")
135
  load_im_btn = gr.Button("Load Image")
136
  inp_im = gr.Image(label="Search Image", type='filepath')
137
+ go_btn_im = gr.Button()
 
 
138
  with gr.Box(visible=False) as vid_box:
139
  vid_url = gr.Textbox(label="Video URL")
140
  vid_url_btn = gr.Button("Load URL")
141
  inp_vid = gr.Video(label="Search Video")
142
  with gr.Row():
143
+ every_n = gr.Number(label="Every /nth frame", value=10)
144
  stat_box = gr.Textbox(label="Status")
145
  with gr.Row():
146
+ go_btn_vid = gr.Button("Start")
147
+ next_btn = gr.Button("Next")
148
+
149
  gr.Column()
150
+
151
  with gr.Row():
152
+ html_out = gr.HTML("""""")
153
  with gr.Row(visible=False):
154
  hid_box = gr.Textbox()
155
 
156
+ def shuf(tog):
157
+ if tog == "Image":
158
+ return gr.update(visible=True), gr.update(visible=False)
159
+ if tog == "Video":
160
+ return gr.update(visible=False), gr.update(visible=True)
161
+
162
+ def load_image(url):
163
+ return url
164
+
165
+ im_load = load_im_btn.click(load_image, inp_url, inp_im)
 
 
 
166
  next_btn.click(process_vid, [inp_vid, hid_box, every_n], [html_out, stat_box, hid_box])
167
+ vid_load = vid_url_btn.click(dl, vid_url, [inp_vid, html_out, stat_box, hid_box])
168
+ vid_proc = go_btn_vid.click(process_vid, [inp_vid, hid_box, every_n], [html_out, stat_box, hid_box])
169
+ im_proc = go_btn_im.click(rev_im, inp_im, [html_out])
170
+ source_tog.change(shuf, [source_tog], [im_box, vid_box], cancels=[vid_proc, im_proc, im_load, vid_load])
171
 
172
  app.queue(concurrency_count=20).launch()