Skip to content

other

Classes:

  • Dar

    A Fraction representing the Display Aspect Ratio.

  • Sar

    A Fraction representing the Sample Aspect Ratio.

  • SceneChangeMode

    Enum for various scene change modes.

Dar

Bases: Fraction

A Fraction representing the Display Aspect Ratio.

This represents the dimensions of the physical display used to view the image. For more information, see https://en.wikipedia.org/wiki/Display_aspect_ratio.

Methods:

  • from_clip

    Get the DAR from the specified clip and SAR.

  • from_res

    Get the DAR from the specified dimensions and SAR.

  • to_sar

    Convert the DAR to a SAR object.

from_clip classmethod

from_clip(clip: VideoNode, sar: bool = True) -> Self

Get the DAR from the specified clip and SAR.

Parameters:

  • clip

    (VideoNode) –

    Clip or frame that holds the frame properties.

  • sar

    (bool, default: True ) –

    Whether to use SAR metadata.

Returns:

  • Self

    A DAR object created using the specified clip and SAR.

Source code in vstools/enums/other.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@classmethod
def from_clip(cls, clip: vs.VideoNode, sar: bool = True) -> Self:
    """
    Get the DAR from the specified clip and SAR.

    Args:
        clip: Clip or frame that holds the frame properties.
        sar: Whether to use SAR metadata.

    Returns:
        A DAR object created using the specified clip and SAR.
    """

    return cls.from_res(clip.width, clip.height, Sar.from_clip(clip) if sar else sar)

from_res classmethod

from_res(width: int, height: int, sar: Sar | Literal[False] = False) -> Self

Get the DAR from the specified dimensions and SAR.

Parameters:

  • width

    (int) –

    The width of the image.

  • height

    (int) –

    The height of the image.

  • sar

    (Sar | Literal[False], default: False ) –

    The SAR object. Optional.

Returns:

  • Self

    A DAR object created using the specified dimensions and SAR.

Source code in vstools/enums/other.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@classmethod
def from_res(cls, width: int, height: int, sar: Sar | Literal[False] = False) -> Self:
    """
    Get the DAR from the specified dimensions and SAR.

    Args:
        width: The width of the image.
        height: The height of the image.
        sar: The SAR object. Optional.

    Returns:
        A DAR object created using the specified dimensions and SAR.
    """

    dar = Fraction(width, height)

    if sar is not False:
        dar /= sar

    return cls(dar)

to_sar

Convert the DAR to a SAR object.

Parameters:

  • active_area

    (int | Fraction) –

    The active image area. For more information, see Sar.from_ar.

  • height

    (int) –

    The height of the image.

Returns:

  • Sar

    A SAR object created using the DAR.

Source code in vstools/enums/other.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def to_sar(self, active_area: int | Fraction, height: int) -> Sar:
    """
    Convert the DAR to a SAR object.

    Args:
        active_area: The active image area. For more information, see ``Sar.from_ar``.
        height: The height of the image.

    Returns:
        A SAR object created using the DAR.
    """

    assert isinstance(active_area, int | Fraction)

    return Sar.from_ar(active_area, height, self)

Sar

Bases: Fraction

A Fraction representing the Sample Aspect Ratio.

This represents the aspect ratio of the pixels or samples of an image. It may also be known as the Pixel Aspect Ratio in certain scenarios. For more information, see https://en.wikipedia.org/wiki/Pixel_aspect_ratio.

Methods:

  • apply

    Apply the SAR values as _SARNum and _SARDen frame properties to a clip.

  • from_ar

    Calculate the SAR using a DAR object & active area. See Dar.to_sar for more information.

  • from_clip

    Get the SAR from the clip's frame properties.

apply

apply(clip: VideoNode) -> VideoNode

Apply the SAR values as _SARNum and _SARDen frame properties to a clip.

Source code in vstools/enums/other.py
122
123
124
125
126
127
def apply(self, clip: vs.VideoNode) -> vs.VideoNode:
    """
    Apply the SAR values as _SARNum and _SARDen frame properties to a clip.
    """

    return vs.core.std.SetFrameProps(clip, _SARNum=self.numerator, _SARDen=self.denominator)

from_ar classmethod

Calculate the SAR using a DAR object & active area. See Dar.to_sar for more information.

For a list of known standards, refer to the following tables: <https://docs.google.com/spreadsheets/d/1pzVHFusLCI7kys2GzK9BTk3w7G8zcLxgHs3DMsurF7g>_

Parameters:

  • active_area

    (int | Fraction) –

    The active image area.

  • height

    (int) –

    The height of the image.

  • dar

    (Dar) –

    The DAR object.

Returns:

  • Self

    A SAR object created using DAR and active image area information.

Source code in vstools/enums/other.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@classmethod
def from_ar(cls, active_area: int | Fraction, height: int, dar: Dar) -> Self:
    """
    Calculate the SAR using a DAR object & active area. See ``Dar.to_sar`` for more information.

    For a list of known standards, refer to the following tables:
    `<https://docs.google.com/spreadsheets/d/1pzVHFusLCI7kys2GzK9BTk3w7G8zcLxgHs3DMsurF7g>`_

    Args:
        active_area: The active image area.
        height: The height of the image.
        dar: The DAR object.

    Returns:
        A SAR object created using DAR and active image area information.
    """

    assert isinstance(active_area, int | Fraction)

    return cls(dar / (Fraction(active_area) / height))

from_clip classmethod

from_clip(clip: HoldsPropValue) -> Self

Get the SAR from the clip's frame properties.

Parameters:

Returns:

  • Self

    A SAR object of the SAR properties from the given clip.

Source code in vstools/enums/other.py
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
@classmethod
def from_clip(cls, clip: HoldsPropValue) -> Self:
    """
    Get the SAR from the clip's frame properties.

    Args:
        clip: Clip or frame that holds the frame properties.

    Returns:
        A SAR object of the SAR properties from the given clip.
    """

    from ..utils import get_prop

    return cls(get_prop(clip, "_SARNum", int, default=1), get_prop(clip, "_SARDen", int, default=1))

SceneChangeMode

Bases: CustomIntEnum

Enum for various scene change modes.

Methods:

Attributes:

SCXVID class-attribute instance-attribute

SCXVID = 2

Get the scene changes using the vapoursynth-scxvid plugin https://github.com/dubhater/vapoursynth-scxvid.

WWXD class-attribute instance-attribute

WWXD = 1

Get the scene changes using the vapoursynth-wwxd plugin https://github.com/dubhater/vapoursynth-wwxd.

WWXD_SCXVID_INTERSECTION class-attribute instance-attribute

WWXD_SCXVID_INTERSECTION = 0

Only get the scene changes if both wwxd and scxvid mark a frame as being a scene change.

WWXD_SCXVID_UNION class-attribute instance-attribute

WWXD_SCXVID_UNION = 3

Get every scene change detected by both wwxd or scxvid.

is_SCXVID property

is_SCXVID: bool

Check whether a mode that uses scxvid is used.

is_WWXD property

is_WWXD: bool

Check whether a mode that uses wwxd is used.

prop_keys property

prop_keys: Iterator[str]

ensure_presence

ensure_presence(clip: VideoNode) -> VideoNode

Ensures all the frame properties necessary for scene change detection are created.

Source code in vstools/enums/other.py
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
def ensure_presence(self, clip: vs.VideoNode) -> vs.VideoNode:
    """
    Ensures all the frame properties necessary for scene change detection are created.
    """
    from ..utils import merge_clip_props

    stats_clip = list[vs.VideoNode]()

    if self.is_SCXVID:
        if not hasattr(vs.core, "scxvid"):
            raise CustomRuntimeError(
                "You are missing scxvid!\n\tDownload it from https://github.com/dubhater/vapoursynth-scxvid",
                self.ensure_presence,
            )
        stats_clip.append(clip.scxvid.Scxvid())

    if self.is_WWXD:
        if not hasattr(vs.core, "wwxd"):
            raise CustomRuntimeError(
                "You are missing wwxd!\n\tDownload it from https://github.com/dubhater/vapoursynth-wwxd",
                self.ensure_presence,
            )
        stats_clip.append(clip.wwxd.WWXD())

    keys = tuple(self.prop_keys)

    expr = " ".join([f"x.{k}" for k in keys]) + (" and" * (len(keys) - 1))

    blank = clip.std.BlankClip(1, 1, vs.GRAY8, keep=True)

    if len(stats_clip) > 1:
        return merge_clip_props(blank, *stats_clip).akarin.Expr(expr)

    return blank.std.CopyFrameProps(stats_clip[0]).akarin.Expr(expr)

from_param classmethod

from_param(value: Any, func_except: FuncExcept | None = None) -> Self

Return the enum value from a parameter.

Parameters:

  • value

    (Any) –

    Value to instantiate the enum class.

  • func_except

    (FuncExcept | None, default: None ) –

    Exception function.

Returns:

  • Self

    Enum value.

Raises:

Source code in jetpytools/enums/base.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
@classmethod
def from_param(cls, value: Any, func_except: FuncExcept | None = None) -> Self:
    """
    Return the enum value from a parameter.

    Args:
        value: Value to instantiate the enum class.
        func_except: Exception function.

    Returns:
        Enum value.

    Raises:
        NotFoundEnumValue: Variable not found in the given enum.
    """
    func_except = func_except or cls.from_param

    try:
        return cls(value)
    except (ValueError, TypeError):
        pass

    if isinstance(func_except, tuple):
        func_name, var_name = func_except
    else:
        func_name, var_name = func_except, repr(cls)

    raise NotFoundEnumValueError(
        'The given value for "{var_name}" argument must be a valid {enum_name}, not "{value}"!\n'
        "Valid values are: [{readable_enum}].",
        func_name,
        var_name=var_name,
        enum_name=cls,
        value=value,
        readable_enum=(f"{name} ({value!r})" for name, value in cls.__members__.items()),
        reason=value,
    ) from None

lambda_cb

lambda_cb() -> Callable[[int, VideoFrame], SentinelT | int]
Source code in vstools/enums/other.py
220
221
def lambda_cb(self) -> Callable[[int, vs.VideoFrame], SentinelT | int]:
    return lambda n, f: Sentinel.check(n, bool(f[0][0, 0]))

prepare_clip

prepare_clip(clip: VideoNode, height: int | Literal[False] = 360) -> VideoNode

Prepare a clip for scene change metric calculations.

The clip will always be resampled to YUV420 8bit if it's not already, as that's what the plugins support.

Parameters:

  • clip

    (VideoNode) –

    Clip to process.

  • height

    (int | Literal[False], default: 360 ) –

    Output height of the clip. Smaller frame sizes are faster to process, but may miss more scene changes or introduce more false positives. Width is automatically calculated. False means no resizing operation is performed. Default: 360.

Returns:

  • VideoNode

    A prepared clip for performing scene change metric calculations on.

Source code in vstools/enums/other.py
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
def prepare_clip(self, clip: vs.VideoNode, height: int | Literal[False] = 360) -> vs.VideoNode:
    """
    Prepare a clip for scene change metric calculations.

    The clip will always be resampled to YUV420 8bit if it's not already,
    as that's what the plugins support.

    Args:
        clip: Clip to process.
        height: Output height of the clip. Smaller frame sizes are faster to process, but may miss more scene
            changes or introduce more false positives. Width is automatically calculated. `False` means no resizing
            operation is performed. Default: 360.

    Returns:
        A prepared clip for performing scene change metric calculations on.
    """
    from ..utils import get_w

    if height:
        clip = clip.resize.Bilinear(get_w(height, clip), height, vs.YUV420P8)
    elif not clip.format or (clip.format and clip.format.id != vs.YUV420P8):
        clip = clip.resize.Bilinear(format=vs.YUV420P8)

    return self.ensure_presence(clip)

value

value() -> int
Source code in jetpytools/enums/base.py
86
87
@enum_property
def value(self) -> int: ...