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
|