Spaces:
Running
Running
import gradio as gr | |
import random | |
VIDEO_ROSTER = [ | |
("videos/1.mp4", "real"), | |
("videos/2.mp4", "deepfake"), | |
("videos/3.mp4", "deepfake"), | |
("videos/4.mp4", "deepfake"), | |
("videos/5.mp4", "deepfake"), | |
("videos/6.mp4", "deepfake"), | |
("videos/7.mp4", "real"), | |
("videos/8.mp4", "real"), | |
("videos/9.mp4", "real"), | |
("videos/10.mp4", "real"), | |
] | |
def start_game(): | |
vids = VIDEO_ROSTER.copy() | |
random.shuffle(vids) | |
return [vids, 0, 0, []] # [videos, index, score, guesses] | |
def next_video(state, guess): | |
vids, idx, score, guesses = state | |
if idx > 0: | |
guesses.append(guess) | |
if guess == vids[idx - 1][1]: | |
score += 1 | |
if idx >= len(vids): | |
return None, [vids, idx, score, guesses] | |
video_path = vids[idx][0] | |
return video_path, [vids, idx + 1, score, guesses] | |
def show_results(score, vids, guesses): | |
header = gr.update(value=f"### Game over! You got **{score}/10** correct.", | |
visible=True) | |
updates = [header] | |
for (path, label), guess in zip(vids, guesses): | |
correct = guess == label | |
color = "green" if correct else "red" | |
caption = (f"<span style='color:{color}; font-weight:bold;'>" | |
f"{'Correct' if correct else 'Incorrect'}, " | |
f"this video is {label.capitalize()}</span>") | |
updates.append(gr.update(value=path, visible=True)) | |
updates.append(gr.update(value=caption, visible=True)) | |
return updates | |
def hide_results(): | |
return [gr.update(visible=False)] * (1 + 10*2) | |
with gr.Blocks() as demo: | |
gr.Markdown("# Deepfake Game\nDecide whether each verification is **Real** or **Deepfake**") | |
state = gr.State(start_game()) | |
video_box = gr.Video(label="Video", interactive=False) | |
with gr.Row(): | |
btn_real = gr.Button("Real") | |
btn_deepfake = gr.Button("Deepfake") | |
result_header = gr.Markdown(visible=False) | |
result_pairs = [] | |
for _ in range(10): | |
with gr.Column(): | |
v = gr.Video(interactive=False, visible=False, width=360, height=270) | |
c = gr.Markdown(visible=False) | |
result_pairs.append((v, c)) | |
def on_guess(choice, st): | |
vid_path, new_st = next_video(st, choice) | |
if vid_path is None: | |
out = [gr.update(value=None, visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
new_st] | |
out += show_results(new_st[2], new_st[0], new_st[3]) | |
return out | |
out = [gr.update(value=vid_path, visible=True), | |
gr.update(visible=True), | |
gr.update(visible=True), | |
new_st] | |
out += hide_results() | |
return out | |
outputs = [video_box, btn_real, btn_deepfake, state, result_header] | |
for v, c in result_pairs: | |
outputs.extend([v, c]) | |
btn_real.click(lambda s: on_guess("real", s), inputs=state, outputs=outputs) | |
btn_deepfake.click(lambda s: on_guess("deepfake", s), inputs=state, outputs=outputs) | |
def on_load(): | |
init_state = start_game() | |
first_clip = init_state[0][0][0] | |
init_state[1] = 1 | |
return [first_clip, | |
gr.update(visible=True), | |
gr.update(visible=True), | |
init_state] + hide_results() | |
demo.load(on_load, None, outputs) | |
if __name__ == "__main__": | |
demo.launch(share=True) | |