|
|
|
import gradio as gr |
|
import cv2 |
|
import numpy as np |
|
import os |
|
|
|
from scenedetect import open_video, SceneManager |
|
from scenedetect.detectors import ContentDetector |
|
|
|
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip |
|
|
|
|
|
|
|
title = "Scene Edit Detection" |
|
description = "Gradio demo of PyScene scenedetect, to automatically find every shots in a video sequence, then save each shots as a splitted mp4 video chunk to download" |
|
|
|
|
|
|
|
|
|
video_input = gr.Video(source="upload", format="mp4", label="Video Sequence"); |
|
|
|
|
|
|
|
def convert_to_tuple(list): |
|
return tuple(list); |
|
|
|
|
|
def find_scenes(video_path, threshold=27.0): |
|
|
|
filename = os.path.splitext(os.path.basename(video_path))[0] |
|
|
|
video = open_video(video_path) |
|
scene_manager = SceneManager() |
|
scene_manager.add_detector( |
|
ContentDetector(threshold=threshold)) |
|
|
|
|
|
scene_manager.detect_scenes(video, show_progress=True) |
|
scene_list = scene_manager.get_scene_list() |
|
|
|
|
|
data_outputs.append(scene_list) |
|
gradio_components_outputs.append("json") |
|
|
|
|
|
timecodes = [] |
|
shots = [] |
|
stills = [] |
|
|
|
|
|
|
|
|
|
for i, shot in enumerate(scene_list): |
|
|
|
|
|
|
|
framerate = shot[0].get_framerate() |
|
shot_in = shot[0].get_frames() / framerate |
|
shot_out = shot[1].get_frames() / framerate |
|
|
|
tc_in = shot[0].get_timecode() |
|
tc_out = shot[1].get_timecode() |
|
|
|
frame_in = shot[0].get_frames() |
|
frame_out = shot[1].get_frames() |
|
|
|
timecodes.append({"title": filename, "fps": framerate}) |
|
timecode = {"tc_in": tc_in, "tc_out": tc_out, "frame_in": frame_in, "frame_out": frame_out} |
|
timecodes.append(timecode) |
|
|
|
|
|
target_name = "shot_" + str(i+1) + "_" + filename + ".mp4" |
|
|
|
|
|
ffmpeg_extract_subclip(video_path, shot_in, shot_out, targetname=target_name) |
|
|
|
|
|
shots.append(target_name) |
|
|
|
|
|
data_outputs.append(target_name) |
|
gradio_components_outputs.append("video") |
|
|
|
|
|
|
|
|
|
|
|
vid = cv2.VideoCapture(video_path) |
|
fps = vid.get(cv2.CAP_PROP_FPS) |
|
print('frames per second =',fps) |
|
|
|
frame_id = shot[0].get_frames() |
|
|
|
vid.set(cv2.CAP_PROP_POS_FRAMES, frame_id) |
|
ret, frame = vid.read() |
|
|
|
|
|
img = str(frame_id) + '_screenshot.png' |
|
cv2.imwrite(img,frame) |
|
|
|
|
|
stills.append(img) |
|
|
|
|
|
data_outputs.append(shots) |
|
gradio_components_outputs.append("file") |
|
|
|
|
|
data_outputs.append(stills) |
|
gradio_components_outputs.append("gallery") |
|
|
|
|
|
|
|
|
|
results = convert_to_tuple(data_outputs) |
|
print(results) |
|
|
|
|
|
|
|
|
|
|
|
|
|
return timecodes, shots, stills |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data_outputs = [] |
|
|
|
|
|
|
|
gradio_components_outputs = [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
outputs = [gr.JSON(label="Shots detected"), gr.File(label="Downloadable Shots"), gr.Gallery(label="Still Images from each shot").style(grid=3)] |
|
|
|
|
|
print('Hello Sylvain') |
|
gr.Interface(fn=find_scenes, inputs=video_input, outputs=outputs, title=title, description=description).launch() |