Add `change_video_resolution_and_fps`, and use it to parse the input video (if necessary).
Browse files- app.py +10 -2
- video_utils.py +60 -0
app.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import gradio as gr
|
|
|
2 |
import torch
|
3 |
from pytorchvideo.data import make_clip_sampler
|
4 |
from pytorchvideo.data.clip_sampling import ClipInfoList
|
@@ -15,6 +16,8 @@ from torchvision.transforms import (
|
|
15 |
)
|
16 |
from transformers import VideoMAEForVideoClassification, VideoMAEFeatureExtractor
|
17 |
|
|
|
|
|
18 |
MODEL_CKPT = "omermazig/videomae-finetuned-nba-5-class-4-batch-8000-vid-multiclass"
|
19 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
20 |
CLIPS_FROM_SINGLE_VIDEO = 5
|
@@ -52,8 +55,13 @@ labels = list(trained_model.config.label2id.keys())
|
|
52 |
|
53 |
def parse_video_to_clips(video_file):
|
54 |
"""A utility to parse the input videos """
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
clip_sampler = make_clip_sampler("random_multi", clip_duration, CLIPS_FROM_SINGLE_VIDEO)
|
59 |
# noinspection PyTypeChecker
|
|
|
1 |
import gradio as gr
|
2 |
+
import tempfile
|
3 |
import torch
|
4 |
from pytorchvideo.data import make_clip_sampler
|
5 |
from pytorchvideo.data.clip_sampling import ClipInfoList
|
|
|
16 |
)
|
17 |
from transformers import VideoMAEForVideoClassification, VideoMAEFeatureExtractor
|
18 |
|
19 |
+
from video_utils import change_video_resolution_and_fps
|
20 |
+
|
21 |
MODEL_CKPT = "omermazig/videomae-finetuned-nba-5-class-4-batch-8000-vid-multiclass"
|
22 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
23 |
CLIPS_FROM_SINGLE_VIDEO = 5
|
|
|
55 |
|
56 |
def parse_video_to_clips(video_file):
|
57 |
"""A utility to parse the input videos """
|
58 |
+
new_resolution = (320, 256)
|
59 |
+
new_fps = 30
|
60 |
+
with tempfile.NamedTemporaryFile() as new_video:
|
61 |
+
print(new_video.name)
|
62 |
+
change_video_resolution_and_fps(video_file, new_video.name, new_resolution, new_fps)
|
63 |
+
video_path_handler = VideoPathHandler()
|
64 |
+
video: EncodedVideoPyAV = video_path_handler.video_from_path(video_file)
|
65 |
|
66 |
clip_sampler = make_clip_sampler("random_multi", clip_duration, CLIPS_FROM_SINGLE_VIDEO)
|
67 |
# noinspection PyTypeChecker
|
video_utils.py
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import shutil
|
2 |
+
from typing import Optional, Tuple
|
3 |
+
|
4 |
+
import cv2
|
5 |
+
|
6 |
+
|
7 |
+
def change_video_resolution_and_fps(video_path: str, output_path: str,
|
8 |
+
new_resolution: Optional[Tuple[int, int]] = None,
|
9 |
+
new_fps: Optional[int] = None) -> bool:
|
10 |
+
cap = cv2.VideoCapture(video_path)
|
11 |
+
|
12 |
+
try:
|
13 |
+
original_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
14 |
+
original_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
15 |
+
resolution = (original_width, original_height)
|
16 |
+
fps = int(cap.get(cv2.CAP_PROP_FPS))
|
17 |
+
# Specify the new_resolution and new_fps for the cut video
|
18 |
+
new_resolution = new_resolution if new_resolution else resolution
|
19 |
+
new_fps = new_fps if new_fps else fps
|
20 |
+
fps_decrease_factor = fps / new_fps
|
21 |
+
if not fps_decrease_factor.is_integer():
|
22 |
+
raise ValueError(f"New fps ({new_fps}) must be a divisor of the current fps ({fps})")
|
23 |
+
|
24 |
+
if fps == new_fps and (original_width, original_height) == new_resolution:
|
25 |
+
shutil.copy(video_path, output_path)
|
26 |
+
return True
|
27 |
+
|
28 |
+
current_frame = 0
|
29 |
+
|
30 |
+
# Read first frame
|
31 |
+
ret, frame = cap.read()
|
32 |
+
if not ret:
|
33 |
+
# Video has ended, without us recording anything
|
34 |
+
return False
|
35 |
+
|
36 |
+
# Initialize the video writer to save the cut video
|
37 |
+
fourcc = cv2.VideoWriter_fourcc(*'XVID')
|
38 |
+
out = cv2.VideoWriter(output_path, fourcc, new_fps, new_resolution, isColor=True)
|
39 |
+
new_video_current_frame = 0
|
40 |
+
|
41 |
+
while ret:
|
42 |
+
if current_frame % fps_decrease_factor == 0:
|
43 |
+
if resolution != new_resolution:
|
44 |
+
# Resize the frame to the desired new_resolution before writing it
|
45 |
+
frame = cv2.resize(frame, new_resolution, interpolation=cv2.INTER_AREA)
|
46 |
+
# Write the frame to the cut video
|
47 |
+
out.write(frame)
|
48 |
+
new_video_current_frame += 1
|
49 |
+
|
50 |
+
current_frame += 1
|
51 |
+
# Read next frame
|
52 |
+
ret, frame = cap.read()
|
53 |
+
|
54 |
+
# We're done recording
|
55 |
+
out.release()
|
56 |
+
return new_video_current_frame > 0
|
57 |
+
|
58 |
+
finally:
|
59 |
+
# Release the video capture and close all windows
|
60 |
+
cap.release()
|