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