File size: 8,689 Bytes
aead09a
 
1ce9878
d82da04
7716718
2255cf1
522ecb9
e8f283e
91fad26
 
51d1028
 
 
 
a1323c8
91fad26
1ce9878
 
 
91fad26
 
 
 
d512ba7
91fad26
 
 
 
 
 
 
 
 
 
 
 
 
6814c3b
91fad26
 
 
 
d82da04
91fad26
 
 
 
 
 
 
102c183
91fad26
 
 
 
599424e
91fad26
 
 
dc9ebd1
91fad26
 
 
 
 
 
 
 
 
51d1028
 
 
 
91fad26
 
102c183
91fad26
 
 
102c183
 
91fad26
 
102c183
91fad26
 
 
 
102c183
91fad26
 
599424e
91fad26
 
d82da04
91fad26
 
 
dc9ebd1
 
 
91fad26
 
dc9ebd1
 
 
 
51d1028
 
 
 
91fad26
c558940
91fad26
dc9ebd1
91fad26
 
 
 
 
51d1028
 
 
 
 
 
91fad26
 
7716718
dc9ebd1
0b4ddd5
91fad26
 
7716718
91fad26
 
283940a
91fad26
 
 
 
283940a
102c183
91fad26
aead09a
91fad26
aead09a
d5ef3b7
d82da04
d5ef3b7
91fad26
 
d82da04
91fad26
dc9ebd1
91fad26
 
 
 
 
 
60fae74
91fad26
 
 
102c183
91fad26
 
102c183
91fad26
 
 
 
458c1fb
91fad26
 
2011185
91fad26
 
 
102c183
 
91fad26
102c183
91fad26
 
 
dc9ebd1
 
b5366ff
91fad26
 
 
 
 
 
 
 
 
547d352
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
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
import subprocess
import html
import imgbbpy  # Adding imgbb to upload images for accessible URLs

# Initialize imgbb client with your API key (you need to provide your key)
imgbb_client = imgbbpy.SyncClient("YOUR_IMGBB_API_KEY")

# Function to download video from a given URL using yt-dlp
def dl(inp):
    out = None
    try:
        # Generate a unique ID for each download to avoid conflicts
        uid = uuid.uuid4()
        # Replace characters in URL to create a valid filename
        inp_out = inp.replace("https://", "").replace("/", "_").replace(".", "_").replace("=", "_").replace("?", "_")
        
        # Construct yt-dlp command to download the video
        command = [
            'yt-dlp', inp, '--trim-filenames', '160',
            '-o', f"{uid}/{inp_out}.mp4", '-S', 'res,mp4', '--recode', 'mp4'
        ]

        # Special handling for Twitter URLs
        if "twitter" in inp:
            command.insert(2, '--extractor-arg')
            command.insert(3, 'twitter:api=syndication')

        # Run the yt-dlp command to download the video
        subprocess.run(command, check=True)
        out = f"{uid}/{inp_out}.mp4"
        print(out)
    except subprocess.CalledProcessError as e:
        print(f"yt-dlp failed: {e}")
    return out, gr.HTML(""), "", ""

# Function to process the video, extracting frames and performing reverse image search
def process_vid(file, cur_frame, every_n):
    uid = uuid.uuid4()  # Unique identifier for each run to avoid conflicts
    capture = cv2.VideoCapture(file)    # Open the video file
    frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))  # Get total number of frames in the video
    rev_img_searcher = ReverseImageSearcher()  # Initialize the reverse image searcher
    html_out = ""
    count = int(every_n)

    # Determine the starting frame based on user input
    start_frame = int(cur_frame) if cur_frame else 0

    try:
        # Iterate over frames from the starting frame to the end
        for i in range(start_frame, frame_count):
            if count >= int(every_n):
                count = 1
                capture.set(cv2.CAP_PROP_POS_FRAMES, i)  # Set the position to the specific frame
                ret, frame_f = capture.read()  # Read the frame
                
                if not ret:
                    continue  # If frame could not be read, continue to the next one

                # Save the current frame as an image file
                frame_path = f"{uid}-vid_tmp{i}.png"
                cv2.imwrite(frame_path, frame_f)
                
                # Upload the frame to imgbb to get a publicly accessible URL
                response = imgbb_client.upload(file=frame_path)
                out_url = response.url  # Get the public URL from imgbb response
                
                # Perform reverse image search on the extracted frame
                res = rev_img_searcher.search(out_url)
                out_cnt = 0

                # If results are found, generate HTML output
                if len(res) > 0:
                    for search_item in res:
                        out_cnt += 1
                        html_out += f"""
                        <div>
                        Title: {html.escape(search_item.page_title)}<br>
                        Site: <a href='{html.escape(search_item.page_url)}' target='_blank' rel='noopener noreferrer'>{html.escape(search_item.page_url)}</a><br>
                        Img: <a href='{html.escape(search_item.image_url)}' target='_blank' rel='noopener noreferrer'>{html.escape(search_item.image_url)}</a><br>
                        <img class='my_im' src='{html.escape(search_item.image_url)}'><br>
                        </div>"""
                    return gr.HTML(f'<h1>Total Found: {out_cnt}</h1><br>{html_out}'), f"Found frame: {i}", i + int(every_n)
            count += 1
    except Exception as e:
        return gr.HTML(f'{e}'), "", ""
    return gr.HTML('No frame matches found.'), "", ""

# Function to process an image file and convert it for reverse image search
def process_im(file, url):
    # Check if the URL starts with the expected prefix
    if not url.startswith("https://omnibus"):
        return url
    else:
        # Save the image to a temporary file
        uid = uuid.uuid4()
        read_file = Image.open(file)
        read_file.save(f"{uid}-tmp.png")
        action_input = f"{uid}-tmp.png"
        out = os.path.abspath(action_input)
        
        # Upload the image to imgbb to get a publicly accessible URL
        response = imgbb_client.upload(file=out)
        out_url = response.url  # Get the public URL from imgbb response
        return out_url

# Function to perform reverse image search on a given image
def rev_im(image):
    uid = uuid.uuid4()  # Generate a unique ID for each run
    html_out = """"""  # Initialize HTML output
    
    # Read the image using OpenCV and save it to a temporary file
    image = cv2.imread(image)
    tmp_image_path = f"{uid}-im_tmp.png"
    cv2.imwrite(tmp_image_path, image)
    
    # Upload the image to imgbb to get a publicly accessible URL
    response = imgbb_client.upload(file=tmp_image_path)
    out_url = response.url  # Get the public URL from imgbb response
    
    # Perform reverse image search
    rev_img_searcher = ReverseImageSearcher()
    res = rev_img_searcher.search(out_url)
    count = 0
    
    # If results are found, generate HTML output
    for search_item in res:
        count += 1
        html_out += f"""
        <div>
        Title: {html.escape(search_item.page_title)}<br>
        Site: <a href='{html.escape(search_item.page_url)}' target='_blank' rel='noopener noreferrer'>{html.escape(search_item.page_url)}</a><br>
        Img: <a href='{html.escape(search_item.image_url)}' target='_blank' rel='noopener noreferrer'>{html.escape(search_item.image_url)}</a><br>
        <img class='my_im' src='{html.escape(search_item.image_url)}'><br>
        </div>"""
        
    return gr.HTML(f'<h1>Total Found: {count}</h1><br>{html_out}')

# Define the Gradio interface for the application
with gr.Blocks() as app:
    with gr.Row():
        gr.Column()
        with gr.Column():
            # Radio button to choose between Image or Video input
            source_tog = gr.Radio(choices=["Image", "Video"], value="Image")
            
            # Box to handle image-related input
            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("Start Image Search")
            
            # Box to handle video-related input
            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="Every /nth frame", value=10)  # Input to select frame extraction frequency
                stat_box = gr.Textbox(label="Status")
                with gr.Row():
                    go_btn_vid = gr.Button("Start Video Search")
                    next_btn = gr.Button("Next Frame Search")
        
        gr.Column()
    with gr.Row():
        html_out = gr.HTML("""
        """)
    with gr.Row(visible=False):
        hid_box = gr.Textbox()

    # Function to shuffle between image and video input boxes based on user selection
    def shuf(tog):
        if tog == "Image":
            return gr.update(visible=True), gr.update(visible=False)
        if tog == "Video":
            return gr.update(visible=False), gr.update(visible=True)    

    # Function to load image from the URL
    def load_image(url):
        return url

    # Gradio button interactions and linking functions
    im_load = load_im_btn.click(load_image, inp_url, inp_im)
    next_btn.click(process_vid, [inp_vid, hid_box, every_n], [html_out, stat_box, hid_box])
    vid_load = vid_url_btn.click(dl, vid_url, [inp_vid, html_out, stat_box, hid_box])
    vid_proc = go_btn_vid.click(process_vid, [inp_vid, hid_box, every_n], [html_out, stat_box, hid_box])
    im_proc = go_btn_im.click(rev_im, inp_im, [html_out])
    source_tog.change(shuf, [source_tog], [im_box, vid_box], cancels=[vid_proc, im_proc, im_load, vid_load])

# Launch the Gradio app with concurrency settings
app.queue(concurrency_count=20).launch()