Skip to content

props

Functions:

  • get_clip_filepath

    Helper function to get the file path from a clip.

  • get_prop

    Get FrameProp prop from frame frame with expected type t to satisfy the type checker.

  • get_props

    Get multiple frame properties from a clip.

  • merge_clip_props

    Merge frame properties from all provided clips.

CT module-attribute

CT = TypeVar('CT')

DT module-attribute

DT = TypeVar('DT')

get_clip_filepath

get_clip_filepath(
    clip: VideoNode,
    fallback: SPathLike | None = ...,
    strict: Literal[False] = ...,
    *,
    func: FuncExceptT | None = ...
) -> SPath | None
get_clip_filepath(
    clip: VideoNode,
    fallback: SPathLike | None = ...,
    strict: Literal[True] = ...,
    *,
    func: FuncExceptT | None = ...
) -> SPath
get_clip_filepath(
    clip: VideoNode,
    fallback: SPathLike | None = ...,
    strict: bool = ...,
    *,
    func: FuncExceptT | None = ...
) -> SPath | None
get_clip_filepath(
    clip: VideoNode,
    fallback: SPathLike | None = None,
    strict: bool = False,
    *,
    func: FuncExceptT | None = None
) -> SPath | None

Helper function to get the file path from a clip.

This functions checks for the IdxFilePath frame property. It also checks to ensure the file exists, and throws an error if it doesn't.

Parameters:

  • clip

    (VideoNode) –

    The clip to get the file path from.

  • fallback

    (SPathLike | None, default: None ) –

    Fallback file path to use if the prop is not found.

  • strict

    (bool, default: False ) –

    If True, will raise an error if the prop is not found. This makes it so the function will NEVER return False. Default: False.

  • func

    (FuncExceptT | None, default: None ) –

    Function returned for error handling. This should only be set by VS package developers.

Raises:

  • FileWasNotFoundError

    The file path was not found.

  • FramePropError

    The property was not found in the clip.

Source code
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
def get_clip_filepath(
    clip: vs.VideoNode, fallback: SPathLike | None = None, strict: bool = False, *, func: FuncExceptT | None = None
) -> SPath | None:
    """
    Helper function to get the file path from a clip.

    This functions checks for the `IdxFilePath` frame property.
    It also checks to ensure the file exists, and throws an error if it doesn't.

    :param clip:                    The clip to get the file path from.
    :param fallback:                Fallback file path to use if the `prop` is not found.
    :param strict:                  If True, will raise an error if the `prop` is not found.
                                    This makes it so the function will NEVER return False.
                                    Default: False.
    :param func:                    Function returned for error handling.
                                    This should only be set by VS package developers.

    :raises FileWasNotFoundError:   The file path was not found.
    :raises FramePropError:         The property was not found in the clip.
    """

    func = func or get_clip_filepath

    if fallback is not None and not (fallback_path := SPath(fallback)).exists() and strict:
        raise FileWasNotFoundError('Fallback file not found!', func, fallback_path.absolute())

    if not (path := get_prop(clip, 'IdxFilePath', str, default=MISSING if strict else False, func=func)):
        return fallback_path if fallback is not None else None

    if not (spath := SPath(str(path))).exists() and not fallback:
        raise FileWasNotFoundError('File not found!', func, spath.absolute())

    if spath.exists():
        return spath

    if fallback is not None and fallback_path.exists():
        return fallback_path

    raise FileWasNotFoundError('File not found!', func, spath.absolute())

get_prop

get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: type[BoundVSMapValue],
    *,
    func: FuncExceptT | None = None
) -> BoundVSMapValue
get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: tuple[type[BoundVSMapValue], type[BoundVSMapValue_0]],
    *,
    func: FuncExceptT | None = None
) -> BoundVSMapValue | BoundVSMapValue_0
get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: tuple[type[BoundVSMapValue], ...],
    *,
    func: FuncExceptT | None = None
) -> Any
get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: type[BoundVSMapValue] | tuple[type[BoundVSMapValue], ...],
    cast: type[CT] | Callable[[BoundVSMapValue], CT],
    *,
    func: FuncExceptT | None = None
) -> CT
get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: type[BoundVSMapValue] | tuple[type[BoundVSMapValue], ...],
    *,
    default: DT | MissingT = ...,
    func: FuncExceptT | None = None
) -> BoundVSMapValue | DT
get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: type[BoundVSMapValue] | tuple[type[BoundVSMapValue], ...],
    cast: type[CT] | Callable[[BoundVSMapValue], CT],
    default: DT | MissingT = ...,
    func: FuncExceptT | None = None,
) -> CT | DT
get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: type[BoundVSMapValue],
    cast: type[CT] | Callable[[BoundVSMapValue], CT] | None,
    default: DT | MissingT,
    func: FuncExceptT | None = None,
) -> BoundVSMapValue | CT | DT
get_prop(
    obj: HoldsPropValueT,
    key: SupportsString | PropEnum,
    t: type[BoundVSMapValue] | tuple[type[BoundVSMapValue], ...],
    cast: type[CT] | Callable[[BoundVSMapValue], CT] | None = None,
    default: DT | MissingT = MISSING,
    func: FuncExceptT | None = None,
) -> BoundVSMapValue | CT | DT

Get FrameProp prop from frame frame with expected type t to satisfy the type checker.

Parameters:

Returns:

Raises:

  • FramePropError

    key is not found in props.

  • FramePropError

    key is of the wrong type.

Source code
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
def get_prop(
    obj: HoldsPropValueT, key: SupportsString | PropEnum,
    t: type[BoundVSMapValue] | tuple[type[BoundVSMapValue], ...],
    cast: type[CT] | Callable[[BoundVSMapValue], CT] | None = None, default: DT | MissingT = MISSING,
    func: FuncExceptT | None = None
) -> BoundVSMapValue | CT | DT:
    """
    Get FrameProp ``prop`` from frame ``frame`` with expected type ``t`` to satisfy the type checker.

    :param obj:                 Clip or frame containing props.
    :param key:                 Prop to get.
    :param t:                   type of prop.
    :param cast:                Cast value to this type, if specified.
    :param default:             Fallback value.
    :param func:                Function returned for custom error handling.
                                This should only be set by VS package developers.

    :return:                    frame.prop[key].

    :raises FramePropError:     ``key`` is not found in props.
    :raises FramePropError:     ``key`` is of the wrong type.
    """
    props: MutableMapping[str, Any]

    if isinstance(obj, vs.RawNode):
        try:
            props = _get_prop_cache[(obj, 0)]
        except KeyError:
            with obj.get_frame(0) as f:
                props = f.props.copy()

            _get_prop_cache[(obj, 0)] = props
    elif isinstance(obj, vs.RawFrame):
        props = obj.props
    else:
        props = obj

    prop: Any = MISSING

    try:
        if isinstance(key, str):
            prop = props[key]
        elif isinstance(key, type) and issubclass(key, PropEnum):
            key = key.prop_key
        else:
            key = str(key)

        prop = props[key]

        if not isinstance(prop, t):
            ts: tuple[type[BoundVSMapValue], ...] = (t, ) if not isinstance(t, tuple) else t

            if all(issubclass(ty, str) for ty in ts) and isinstance(prop, bytes):
                return prop.decode('utf-8')  # type: ignore[return-value]
            raise TypeError

        if cast is None:
            return prop

        return cast(prop)  # type: ignore
    except BaseException as e:
        if default is not MISSING:
            return default

        func = func or get_prop

        if isinstance(e, KeyError) or prop is MISSING:
            e = FramePropError(func, str(key), 'Key {key} not present in props!')
        elif isinstance(e, TypeError):
            e = FramePropError(
                func, str(key), 'Key {key} did not contain expected type: Expected {t} got {prop_t}!',
                t=t, prop_t=type(prop)
            )
        else:
            e = FramePropError(func, str(key))

        raise e

get_props

get_props(
    obj: HoldsPropValueT,
    keys: Sequence[SupportsString | PropEnum],
    t: type[BoundVSMapValue],
    *,
    func: FuncExceptT | None = None
) -> dict[str, BoundVSMapValue]
get_props(
    obj: HoldsPropValueT,
    keys: Sequence[SupportsString | PropEnum],
    t: type[BoundVSMapValue],
    cast: type[CT] | Callable[[BoundVSMapValue], CT],
    *,
    func: FuncExceptT | None = None
) -> dict[str, CT]
get_props(
    obj: HoldsPropValueT,
    keys: Sequence[SupportsString | PropEnum],
    t: type[BoundVSMapValue],
    *,
    default: DT,
    func: FuncExceptT | None = None
) -> dict[str, BoundVSMapValue | DT]
get_props(
    obj: HoldsPropValueT,
    keys: Sequence[SupportsString | PropEnum],
    t: type[BoundVSMapValue],
    cast: type[CT] | Callable[[BoundVSMapValue], CT],
    default: DT,
    func: FuncExceptT | None = None,
) -> dict[str, CT | DT]
get_props(
    obj: HoldsPropValueT,
    keys: Sequence[SupportsString | PropEnum],
    t: Sequence[type[BoundVSMapValue]],
    cast: Sequence[type[CT] | Callable[[BoundVSMapValue], CT]] | None = None,
    default: DT | Sequence[DT] | MissingT = ...,
    func: FuncExceptT | None = None,
) -> dict[str, Any]
get_props(
    obj: HoldsPropValueT,
    keys: Sequence[SupportsString | PropEnum],
    t: type[BoundVSMapValue] | Sequence[type[BoundVSMapValue]],
    cast: (
        type[CT]
        | Callable[[BoundVSMapValue], CT]
        | Sequence[type[CT] | Callable[[BoundVSMapValue], CT]]
        | None
    ) = None,
    default: DT | Sequence[DT] | MissingT = MISSING,
    func: FuncExceptT | None = None,
) -> dict[str, Any]

Get multiple frame properties from a clip.

Parameters:

Returns:

  • dict[str, Any]

    Dictionary mapping property names to their values. Values will be of type specified by cast if provided, otherwise of the type(s) specified in t or a default value if provided.

Source code
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
def get_props(
    obj: HoldsPropValueT,
    keys: Sequence[SupportsString | PropEnum],
    t: type[BoundVSMapValue] | Sequence[type[BoundVSMapValue]],
    cast: type[CT] | Callable[[BoundVSMapValue], CT] | Sequence[type[CT] | Callable[[BoundVSMapValue], CT]] | None = None,
    default: DT | Sequence[DT] | MissingT = MISSING,
    func: FuncExceptT | None = None
) -> dict[str, Any]:
    """
    Get multiple frame properties from a clip.

    :param obj:                 Clip or frame containing props.
    :param keys:                List of props to get.
    :param t:                   Type of prop or list of types of props.
                                If fewer types are provided than props,
                                the last type will be used for the remaining props.
    :param cast:                Cast value to this type, if specified.
    :param default:             Fallback value. Can be a single value or a list of values.
                                If a list is provided, it must be the same length as keys.
    :param func:                Function returned for custom error handling.
                                This should only be set by VS package developers.

    :return:                    Dictionary mapping property names to their values.
                                Values will be of type specified by cast if provided,
                                otherwise of the type(s) specified in ``t``
                                or a default value if provided.
    """

    func = func or 'get_props'

    if not keys:
        return {}

    t = normalize_seq(t, len(keys))
    ncast = typing_cast(list[type[CT | Callable[[BoundVSMapValue], CT]]], normalize_seq(cast, len(keys)))
    ndefault = normalize_seq(default, len(keys))

    props = dict[str, Any]()
    exceptions = list[Exception]()

    for k, t_, cast_, default_ in zip(keys, t, ncast, ndefault):
        try:
            prop = get_prop(obj, k, t_, cast_, default_, func)
        except Exception as e:
            exceptions.append(e)
        else:
            props[str(k)] = prop

    if exceptions:
        if sys.version_info >= (3, 11):
            raise ExceptionGroup("Multiple exceptions occurred!", exceptions)  # noqa: F821

        raise Exception(exceptions)

    return props

merge_clip_props

merge_clip_props(
    *clips: ConstantFormatVideoNode, main_idx: int = 0
) -> ConstantFormatVideoNode
merge_clip_props(*clips: VideoNode, main_idx: int = 0) -> VideoNode
merge_clip_props(*clips: VideoNode, main_idx: int = 0) -> VideoNode

Merge frame properties from all provided clips.

The props of the main clip (defined by main_idx) will be overwritten, and all other props will be added to it.

Parameters:

  • clips

    (VideoNode, default: () ) –

    Clips which will be merged.

  • main_idx

    (int, default: 0 ) –

    Index of the main clip to which all other clips props will be merged.

Returns:

  • VideoNode

    First clip with all the frameprops of every other given clip merged into it.

Source code
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def merge_clip_props(*clips: vs.VideoNode, main_idx: int = 0) -> vs.VideoNode:
    """
    Merge frame properties from all provided clips.

    The props of the main clip (defined by main_idx) will be overwritten,
    and all other props will be added to it.

    :param clips:       Clips which will be merged.
    :param main_idx:    Index of the main clip to which all other clips props will be merged.

    :return:            First clip with all the frameprops of every other given clip merged into it.
    """

    if len(clips) == 1:
        return clips[0]

    def _merge_props(f: list[vs.VideoFrame], n: int) -> vs.VideoFrame:
        fdst = f[main_idx].copy()

        for i, frame in enumerate(f):
            if i == main_idx:
                continue

            fdst.props.update(frame.props)

        return fdst

    return clips[0].std.ModifyFrame(clips, _merge_props)