-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathChangeFPS.py
More file actions
37 lines (30 loc) · 1.2 KB
/
Copy pathChangeFPS.py
File metadata and controls
37 lines (30 loc) · 1.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import vapoursynth as vs
import math
import functools
core = vs.core
def ChangeFPS(clip: vs.VideoNode, target_fps_num: int, target_fps_den: int = 1) -> vs.VideoNode:
"""
Convert the framerate of a clip, efficiently for very long clips.
Uses a precomputed lookup table to avoid per-frame calculations.
:param clip: Input clip
:param target_fps_num: Numerator of target framerate
:param target_fps_den: Denominator of target framerate
:return: Clip with framerate converted
"""
# Work out the factor
factor = (target_fps_num / target_fps_den) * (clip.fps_den / clip.fps_num)
new_length = round(len(clip) * factor)
# Precompute a lookup table of the frame indices
lookup = [min(round(n / factor), len(clip) - 1) for n in range(new_length)]
# FrameEval function
def frame_adjuster(n, clip, lookup):
return clip[lookup[n]]
# BlankClip for the new length
attribute_clip = core.std.BlankClip(
clip, length=new_length, fpsnum=target_fps_num, fpsden=target_fps_den
)
# FrameEval with the precomputed lookup
return core.std.FrameEval(
attribute_clip,
functools.partial(frame_adjuster, clip=clip, lookup=lookup)
)