Abraham E. Tavarez
commited on
Commit
Β·
56225c5
1
Parent(s):
9358900
youtube video scan
Browse files- app.py +43 -10
- utils/youtube_utils.py +21 -0
app.py
CHANGED
@@ -3,6 +3,7 @@ from detector.face import verify_faces, analyze_face
|
|
3 |
from detector.voice import verify_voices
|
4 |
from detector.video import verify_faces_in_video
|
5 |
from reports.pdf_report import generate_pdf_report
|
|
|
6 |
|
7 |
# Holds latest results
|
8 |
last_face_result = None
|
@@ -50,9 +51,16 @@ def compare_voices(audio1, audio2):
|
|
50 |
return result_text
|
51 |
|
52 |
|
53 |
-
def scan_video(
|
54 |
global last_video_results
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
report = ""
|
57 |
last_video_results = results
|
58 |
for r in results:
|
@@ -66,6 +74,23 @@ def scan_video(video_path, ref_img):
|
|
66 |
# last_video_results.append(report)
|
67 |
return report
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
def generate_report():
|
70 |
return generate_pdf_report(last_face_result, last_voice_result, last_video_results)
|
71 |
|
@@ -75,7 +100,6 @@ with gr.Blocks(title="Deepfake Watchdog") as demo:
|
|
75 |
gr.Markdown("## Upload your image and/or voice to scan for deepfake misuse online.")
|
76 |
|
77 |
# Face Verification
|
78 |
-
gr.Markdown("### π· Face Verification")
|
79 |
with gr.Tab("Face Verification"):
|
80 |
image1 = gr.Image(label="Upload your face", type="filepath")
|
81 |
# audio = gr.Audio(label="Upload your voice (optional)", type="filepath")
|
@@ -92,7 +116,6 @@ with gr.Blocks(title="Deepfake Watchdog") as demo:
|
|
92 |
)
|
93 |
|
94 |
# Voice Verification
|
95 |
-
gr.Markdown("### π€ Voice Verification")
|
96 |
with gr.Tab("π€ Voice Verification"):
|
97 |
gr.Markdown("Upload two audio files to check if the voices match.")
|
98 |
|
@@ -105,19 +128,29 @@ with gr.Blocks(title="Deepfake Watchdog") as demo:
|
|
105 |
voice_btn.click(compare_voices, inputs=[audio1, audio2], outputs=voice_output)
|
106 |
|
107 |
# Video DeepFake Scan
|
108 |
-
gr.Markdown("### πΉ Video Deepfake Scan")
|
109 |
-
with gr.Tab("πΉ Video Deepfake Scan"):
|
110 |
-
|
|
|
|
|
|
|
|
|
|
|
111 |
|
|
|
|
|
|
|
|
|
|
|
112 |
ref_img = gr.Image(type="filepath", label="Reference Face")
|
113 |
-
video_input = gr.Video(label="Video File")
|
|
|
114 |
scan_btn = gr.Button("Scan Video")
|
115 |
scan_output = gr.Textbox(label="Scan Results", lines=10)
|
116 |
|
117 |
-
scan_btn.click(scan_video, inputs=[video_input, ref_img], outputs=scan_output)
|
118 |
|
119 |
|
120 |
-
gr.Markdown("### π Generate Report")
|
121 |
with gr.Tab("π Generate Report"):
|
122 |
report_btn = gr.Button("Generate PDF Report")
|
123 |
report_output = gr.File(label="Download Report")
|
|
|
3 |
from detector.voice import verify_voices
|
4 |
from detector.video import verify_faces_in_video
|
5 |
from reports.pdf_report import generate_pdf_report
|
6 |
+
from utils.youtube_utils import download_youtube_video
|
7 |
|
8 |
# Holds latest results
|
9 |
last_face_result = None
|
|
|
51 |
return result_text
|
52 |
|
53 |
|
54 |
+
def scan_video(video_file, ref_img, youtube_url=""):
|
55 |
global last_video_results
|
56 |
+
|
57 |
+
if youtube_url:
|
58 |
+
try:
|
59 |
+
video_file = download_youtube_video(youtube_url)
|
60 |
+
except Exception as e:
|
61 |
+
return f"β Error downloading YouTube video: {str(e)}"
|
62 |
+
|
63 |
+
results = verify_faces_in_video(video_file, ref_img)
|
64 |
report = ""
|
65 |
last_video_results = results
|
66 |
for r in results:
|
|
|
74 |
# last_video_results.append(report)
|
75 |
return report
|
76 |
|
77 |
+
|
78 |
+
# def scan_video(video_path, ref_img):
|
79 |
+
# global last_video_results
|
80 |
+
# results = verify_faces_in_video(video_path, ref_img)
|
81 |
+
# report = ""
|
82 |
+
# last_video_results = results
|
83 |
+
# for r in results:
|
84 |
+
# if "error" in r:
|
85 |
+
# report += f"\nβ οΈ Frame {r['frame']}: {r['error']}"
|
86 |
+
# # last_video_results.append(report)
|
87 |
+
# else:
|
88 |
+
# status = "β
Match" if r["verified"] else "β Mismatch"
|
89 |
+
# report += f"\nπΌ Frame {r['frame']}: {status} (Distance: {r['distance']})"
|
90 |
+
|
91 |
+
# # last_video_results.append(report)
|
92 |
+
# return report
|
93 |
+
|
94 |
def generate_report():
|
95 |
return generate_pdf_report(last_face_result, last_voice_result, last_video_results)
|
96 |
|
|
|
100 |
gr.Markdown("## Upload your image and/or voice to scan for deepfake misuse online.")
|
101 |
|
102 |
# Face Verification
|
|
|
103 |
with gr.Tab("Face Verification"):
|
104 |
image1 = gr.Image(label="Upload your face", type="filepath")
|
105 |
# audio = gr.Audio(label="Upload your voice (optional)", type="filepath")
|
|
|
116 |
)
|
117 |
|
118 |
# Voice Verification
|
|
|
119 |
with gr.Tab("π€ Voice Verification"):
|
120 |
gr.Markdown("Upload two audio files to check if the voices match.")
|
121 |
|
|
|
128 |
voice_btn.click(compare_voices, inputs=[audio1, audio2], outputs=voice_output)
|
129 |
|
130 |
# Video DeepFake Scan
|
131 |
+
# gr.Markdown("### πΉ Video Deepfake Scan")
|
132 |
+
# with gr.Tab("πΉ Video Deepfake Scan"):
|
133 |
+
# gr.Markdown("Upload a video and a reference image. We'll scan for deepfake face mismatches.")
|
134 |
+
|
135 |
+
# ref_img = gr.Image(type="filepath", label="Reference Face")
|
136 |
+
# video_input = gr.Video(label="Video File")
|
137 |
+
# scan_btn = gr.Button("Scan Video")
|
138 |
+
# scan_output = gr.Textbox(label="Scan Results", lines=10)
|
139 |
|
140 |
+
# scan_btn.click(scan_video, inputs=[video_input, ref_img], outputs=scan_output)
|
141 |
+
|
142 |
+
with gr.Tab("πΉ Video Deepfake Scan"):
|
143 |
+
gr.Markdown("π Upload a video or paste a YouTube link and we'll analyze it for deepfake face swaps.")
|
144 |
+
|
145 |
ref_img = gr.Image(type="filepath", label="Reference Face")
|
146 |
+
video_input = gr.Video(label="Video File (optional)")
|
147 |
+
youtube_url = gr.Textbox(label="YouTube URL (optional)")
|
148 |
scan_btn = gr.Button("Scan Video")
|
149 |
scan_output = gr.Textbox(label="Scan Results", lines=10)
|
150 |
|
151 |
+
scan_btn.click(scan_video, inputs=[video_input, ref_img, youtube_url], outputs=scan_output)
|
152 |
|
153 |
|
|
|
154 |
with gr.Tab("π Generate Report"):
|
155 |
report_btn = gr.Button("Generate PDF Report")
|
156 |
report_output = gr.File(label="Download Report")
|
utils/youtube_utils.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import yt_dlp
|
2 |
+
import os
|
3 |
+
import uuid
|
4 |
+
|
5 |
+
|
6 |
+
def download_youtube_video(url: str, output_dir: str = "/tmp"):
|
7 |
+
"""Downloads the YouTube video and returns the local file path."""
|
8 |
+
video_id = str(uuid.uuid4())[:8]
|
9 |
+
output_path = os.path.join(output_dir, f"{video_id}.mp4")
|
10 |
+
|
11 |
+
ydl_opts = {
|
12 |
+
"format": "best[ext=mp4]/best",
|
13 |
+
"outtmpl": output_path,
|
14 |
+
"quiet": True,
|
15 |
+
"noplaylist": True,
|
16 |
+
}
|
17 |
+
|
18 |
+
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
19 |
+
ydl.download([url])
|
20 |
+
|
21 |
+
return output_path
|