Skip to content

misc

Classes:

BestSource

BestSource(
    *,
    cachemode: int = ABSOLUTE,
    rff: int | None = True,
    showprogress: int | None = True,
    show_pretty_progress: bool | Callable[[float], None] | None = False,
    **kwargs: Any,
)

Bases: CacheIndexer

BestSource indexer.

Unlike the plugin's default behavior, the indexer cache file will be stored in .vsjet/vssource next to the script file.

When cachemode is 0, 1, or 2 (NEVER, CACHE_PATH, or CACHE_PATH_WRITE) or cachepath=None, the behavior falls back to the default cache handling defined by the BestSource plugin itself.

Note

You will need to call setup_logging or basicConfig to show progress.

Parameters:

  • cachemode

    (int, default: ABSOLUTE ) –

    The cache mode. See here and here for more explanation.

  • rff

    (int | None, default: True ) –

    Apply RFF flags to the video. If the video doesn't have or use RFF flags, the output is unchanged.

  • showprogress

    (int | None, default: True ) –

    Print indexing progress as VapourSynth information level log messages.

  • show_pretty_progress

    (bool | Callable[[float], None] | None, default: False ) –

    Display a rich-based progress bar if showprogress is also set to True.

Classes:

Methods:

Attributes:

Source code in vssource/indexers/misc.py
 99
100
101
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
def __init__(
    self,
    *,
    cachemode: int = CacheMode.ABSOLUTE,
    rff: int | None = True,
    showprogress: int | None = True,
    show_pretty_progress: bool | Callable[[float], None] | None = False,
    **kwargs: Any,
) -> None:
    """

    Note:
        You will need to call [setup_logging][vsjetpack.setup_logging] or [basicConfig][logging.basicConfig]
        to show progress.

    Args:
        cachemode: The cache mode. See [here][vssource.BestSource] and [here][vssource.BestSource.CacheMode]
            for more explanation.
        rff: Apply RFF flags to the video. If the video doesn't have or use RFF flags, the output is unchanged.
        showprogress: Print indexing progress as VapourSynth information level log messages.
        show_pretty_progress: Display a rich-based progress bar if `showprogress` is also set to True.
    """
    super().__init__(
        cachemode=cachemode,
        rff=rff,
        showprogress=showprogress,
        show_pretty_progress=show_pretty_progress,
        **kwargs,
    )

force instance-attribute

force = force

indexer_kwargs instance-attribute

indexer_kwargs = kwargs

CacheMode

Bases: CustomIntEnum

Cache mode.

Methods:

Attributes:

  • ABSOLUTE

    Always try to read index but only write index to disk when it will make a noticeable difference

  • ABSOLUTE_WRITE

    Always try to read and write index to disk and store index files

  • CACHE_PATH

    Always try to read index but only write index to disk when it will make a noticeable difference

  • CACHE_PATH_WRITE

    Always try to read and write index to disk and store index files in a subtree of cachepath.

  • NEVER

    Never read or write index to disk.

ABSOLUTE class-attribute instance-attribute

ABSOLUTE = 3

Always try to read index but only write index to disk when it will make a noticeable difference on subsequent runs and store index files in the absolute path in cachepath with track number and index extension appended.

ABSOLUTE_WRITE class-attribute instance-attribute

ABSOLUTE_WRITE = 4

Always try to read and write index to disk and store index files in the absolute path in cachepath with track number and index extension appended.

CACHE_PATH class-attribute instance-attribute

CACHE_PATH = 1

Always try to read index but only write index to disk when it will make a noticeable difference on subsequent runs and store index files in a subtree of cachepath.

CACHE_PATH_WRITE class-attribute instance-attribute

CACHE_PATH_WRITE = 2

Always try to read and write index to disk and store index files in a subtree of cachepath.

NEVER class-attribute instance-attribute

NEVER = 0

Never read or write index to disk.

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!s})" for name, value in cls.__members__.items()),
        reason=value,
    ) from None

value

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

asource

asource(
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> AudioNode

Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.

Source code in vssource/indexers/base.py
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
@inject_self
def asource(
    self,
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> vs.AudioNode:
    """
    Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.
    """
    if not self.has_audio:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support audio indexing!", self.asource)

    nfiles = self.normalize_filenames(file)
    call_kwargs = self.indexer_kwargs | kwargs
    if self._audio_track_arg_name not in call_kwargs and track is not None:
        call_kwargs[self._audio_track_arg_name] = track

    clips = [self._asource_file(f.to_str(), **call_kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.AudioSplice(clips)

    if sample_rate is not None or channels is not None or bits is not None:
        clip = core.std.AudioResample(clip, samplerate=sample_rate, channels=channels, bits=bits)

    return clip

ensure_obj classmethod

ensure_obj(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> Self

Ensure that the input is a indexer instance, resolving it if necessary.

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

  • Self

    Indexer instance.

Source code in vssource/indexers/base.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
@classmethod
def ensure_obj(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> Self:
    """
    Ensure that the input is a indexer instance, resolving it if necessary.

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Indexer instance.
    """
    return _base_ensure_obj(cls, indexer, func_except)

from_param classmethod

from_param(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> type[Self]

Resolve and return an Indexer type from a given input (string, type, or instance).

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

Source code in vssource/indexers/base.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@classmethod
def from_param(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> type[Self]:
    """
    Resolve and return an Indexer type from a given input (string, type, or instance).

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Resolved indexer type.
    """
    return _base_from_param(cls, indexer, func_except)

get_cache_path staticmethod

get_cache_path(
    source_path: SPathLike,
    ext: str | None = None,
    track: int | None = None,
    is_audio: bool = False,
) -> SPath
Source code in vssource/indexers/base.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
@staticmethod
def get_cache_path(
    source_path: SPathLike,
    ext: str | None = None,
    track: int | None = None,
    is_audio: bool = False,
) -> SPath:
    source_file = SPath(source_path).resolve()
    hashed_path = hashlib.blake2s(source_file.to_str().encode("utf-8"), digest_size=4).hexdigest()
    cache_filename = f"{source_file.name}_{hashed_path}"

    if is_audio and ext:
        tr_suffix = f"_a{track if track is not None else 0}"
        cache_filename = f"{cache_filename}{tr_suffix}"

    if ext:
        cache_filename = f"{cache_filename}.{ext.lstrip('.')}"

    storage = _get_indexer_cache_storage()
    return storage.get_file(cache_filename)

get_progress staticmethod

get_progress(*, console: Console | None = None) -> Progress
Source code in vssource/indexers/misc.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
@staticmethod
def get_progress(*, console: Console | None = None) -> Progress:
    from rich.console import Console
    from rich.progress import BarColumn, Progress, TextColumn, TimeElapsedColumn, TimeRemainingColumn

    return Progress(
        TextColumn("[progress.description]{task.description}"),
        BarColumn(),
        TextColumn("{task.percentage:>3.0f}%"),
        TimeElapsedColumn(),
        TimeRemainingColumn(),
        console=console or Console(stderr=True),
        transient=True,
    )

has_audio classmethod

has_audio() -> bool

Whether this indexer supports audio sourcing.

Source code in vssource/indexers/base.py
69
70
71
72
73
@classproperty
@classmethod
def has_audio(cls) -> bool:
    """Whether this indexer supports audio sourcing."""
    return getattr(cls, "_asource_func", None) is not None

has_video classmethod

has_video() -> bool

Whether this indexer supports video sourcing.

Source code in vssource/indexers/base.py
63
64
65
66
67
@classproperty
@classmethod
def has_video(cls) -> bool:
    """Whether this indexer supports video sourcing."""
    return getattr(cls, "_source_func", None) is not None

normalize_filenames classmethod

normalize_filenames(file: SPathLike | Iterable[SPathLike]) -> list[SPath]
Source code in vssource/indexers/base.py
187
188
189
190
191
192
193
194
195
196
197
@classmethod
def normalize_filenames(cls, file: SPathLike | Iterable[SPathLike]) -> list[SPath]:
    files = list[SPath]()

    for f in to_arr(file):
        if str(f).startswith("file:///"):
            f = str(f)[8::]

        files.append(SPath(f))

    return files

pretty_progress classmethod

pretty_progress(
    progress: Literal[True] | Callable[[float], None],
) -> Generator[None]
Source code in vssource/indexers/misc.py
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
@classmethod
@contextmanager
def pretty_progress(cls, progress: Literal[True] | Callable[[float], None]) -> Generator[None]:
    if callable(progress):
        pr_ctx = nullcontext()
        cb = progress
    else:
        pr_ctx = cls.get_progress()
        task_id = pr_ctx.add_task("Indexing with BestSource...", total=100.0, visible=False)
        cb = lambda pct: pr_ctx.update(task_id, completed=pct, visible=True)  # noqa: E731

    handler = _ProgressFromLogHandler(cb)

    vs_logger = getLogger("vapoursynth")
    vs_logger.propagate = False

    try:
        with pr_ctx, handler.with_logger(vs_logger):
            yield
            cb(100.0)
    finally:
        vs_logger.propagate = True

source

source(
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> VideoNode

Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

The returned clip is passed through initialize_clip to apply bit depth conversion and frame props initialization.

Source code in vssource/indexers/base.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@inject_self
def source(
    self,
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: vs.VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> vs.VideoNode:
    """
    Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

    The returned clip is passed through [initialize_clip][vstools.initialize_clip] to apply bit depth conversion
    and frame props initialization.
    """
    if not self.has_video:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support video indexing!", self.source)

    nfiles = self.normalize_filenames(file)
    clips = [self._source_file(f.to_str(), **self.indexer_kwargs | kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.Splice(clips)
    clip = initialize_clip(clip, bits, matrix, transfer, primaries, chroma_location, color_range, field_based)

    if idx_props:
        clip = clip.std.SetFrameProps(IdxFilePath=[f.to_str() for f in nfiles], Idx=self.__class__.__name__)

    if name:
        clip = clip.std.SetFrameProps(Name=name)

    if ref:
        clip = match_clip(clip, ref, length=True)

    return clip

source_func classmethod

source_func(path: SPathLike, **kwargs: Any) -> VideoNode
Source code in vssource/indexers/base.py
179
180
181
182
183
184
185
@classmethod
@deprecated(
    "`source_func` is deprecated and will be removed in a future version. Use `source` instead.",
    category=DeprecationWarning,
)
def source_func(cls, path: SPathLike, **kwargs: Any) -> vs.VideoNode:
    return cls._source_file(path, **kwargs)

FFMS2

FFMS2(*, force: bool = True, **kwargs: Any)

Bases: CacheIndexer

FFmpegSource2 indexer.

Unlike the plugin's default behavior, the indexer cache file will be stored in .vsjet/vssource next to the script file.

When cachefile=None, the behavior falls back to the default cache handling defined by the plugin itself.

Methods:

  • asource

    Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.

  • ensure_obj

    Ensure that the input is a indexer instance, resolving it if necessary.

  • from_param

    Resolve and return an Indexer type from a given input (string, type, or instance).

  • get_cache_path
  • has_audio

    Whether this indexer supports audio sourcing.

  • has_video

    Whether this indexer supports video sourcing.

  • normalize_filenames
  • source

    Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

  • source_func

Attributes:

Source code in vssource/indexers/base.py
57
58
59
60
61
def __init__(self, *, force: bool = True, **kwargs: Any) -> None:
    super().__init__()

    self.force = force
    self.indexer_kwargs = kwargs

force instance-attribute

force = force

indexer_kwargs instance-attribute

indexer_kwargs = kwargs

asource

asource(
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> AudioNode

Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.

Source code in vssource/indexers/base.py
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
@inject_self
def asource(
    self,
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> vs.AudioNode:
    """
    Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.
    """
    if not self.has_audio:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support audio indexing!", self.asource)

    nfiles = self.normalize_filenames(file)
    call_kwargs = self.indexer_kwargs | kwargs
    if self._audio_track_arg_name not in call_kwargs and track is not None:
        call_kwargs[self._audio_track_arg_name] = track

    clips = [self._asource_file(f.to_str(), **call_kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.AudioSplice(clips)

    if sample_rate is not None or channels is not None or bits is not None:
        clip = core.std.AudioResample(clip, samplerate=sample_rate, channels=channels, bits=bits)

    return clip

ensure_obj classmethod

ensure_obj(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> Self

Ensure that the input is a indexer instance, resolving it if necessary.

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

  • Self

    Indexer instance.

Source code in vssource/indexers/base.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
@classmethod
def ensure_obj(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> Self:
    """
    Ensure that the input is a indexer instance, resolving it if necessary.

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Indexer instance.
    """
    return _base_ensure_obj(cls, indexer, func_except)

from_param classmethod

from_param(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> type[Self]

Resolve and return an Indexer type from a given input (string, type, or instance).

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

Source code in vssource/indexers/base.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@classmethod
def from_param(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> type[Self]:
    """
    Resolve and return an Indexer type from a given input (string, type, or instance).

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Resolved indexer type.
    """
    return _base_from_param(cls, indexer, func_except)

get_cache_path staticmethod

get_cache_path(
    source_path: SPathLike,
    ext: str | None = None,
    track: int | None = None,
    is_audio: bool = False,
) -> SPath
Source code in vssource/indexers/base.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
@staticmethod
def get_cache_path(
    source_path: SPathLike,
    ext: str | None = None,
    track: int | None = None,
    is_audio: bool = False,
) -> SPath:
    source_file = SPath(source_path).resolve()
    hashed_path = hashlib.blake2s(source_file.to_str().encode("utf-8"), digest_size=4).hexdigest()
    cache_filename = f"{source_file.name}_{hashed_path}"

    if is_audio and ext:
        tr_suffix = f"_a{track if track is not None else 0}"
        cache_filename = f"{cache_filename}{tr_suffix}"

    if ext:
        cache_filename = f"{cache_filename}.{ext.lstrip('.')}"

    storage = _get_indexer_cache_storage()
    return storage.get_file(cache_filename)

has_audio classmethod

has_audio() -> bool

Whether this indexer supports audio sourcing.

Source code in vssource/indexers/base.py
69
70
71
72
73
@classproperty
@classmethod
def has_audio(cls) -> bool:
    """Whether this indexer supports audio sourcing."""
    return getattr(cls, "_asource_func", None) is not None

has_video classmethod

has_video() -> bool

Whether this indexer supports video sourcing.

Source code in vssource/indexers/base.py
63
64
65
66
67
@classproperty
@classmethod
def has_video(cls) -> bool:
    """Whether this indexer supports video sourcing."""
    return getattr(cls, "_source_func", None) is not None

normalize_filenames classmethod

normalize_filenames(file: SPathLike | Iterable[SPathLike]) -> list[SPath]
Source code in vssource/indexers/base.py
187
188
189
190
191
192
193
194
195
196
197
@classmethod
def normalize_filenames(cls, file: SPathLike | Iterable[SPathLike]) -> list[SPath]:
    files = list[SPath]()

    for f in to_arr(file):
        if str(f).startswith("file:///"):
            f = str(f)[8::]

        files.append(SPath(f))

    return files

source

source(
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> VideoNode

Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

The returned clip is passed through initialize_clip to apply bit depth conversion and frame props initialization.

Source code in vssource/indexers/base.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@inject_self
def source(
    self,
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: vs.VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> vs.VideoNode:
    """
    Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

    The returned clip is passed through [initialize_clip][vstools.initialize_clip] to apply bit depth conversion
    and frame props initialization.
    """
    if not self.has_video:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support video indexing!", self.source)

    nfiles = self.normalize_filenames(file)
    clips = [self._source_file(f.to_str(), **self.indexer_kwargs | kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.Splice(clips)
    clip = initialize_clip(clip, bits, matrix, transfer, primaries, chroma_location, color_range, field_based)

    if idx_props:
        clip = clip.std.SetFrameProps(IdxFilePath=[f.to_str() for f in nfiles], Idx=self.__class__.__name__)

    if name:
        clip = clip.std.SetFrameProps(Name=name)

    if ref:
        clip = match_clip(clip, ref, length=True)

    return clip

source_func classmethod

source_func(path: SPathLike, **kwargs: Any) -> VideoNode
Source code in vssource/indexers/base.py
179
180
181
182
183
184
185
@classmethod
@deprecated(
    "`source_func` is deprecated and will be removed in a future version. Use `source` instead.",
    category=DeprecationWarning,
)
def source_func(cls, path: SPathLike, **kwargs: Any) -> vs.VideoNode:
    return cls._source_file(path, **kwargs)

LSMAS

LSMAS(*, force: bool = True, **kwargs: Any)

Bases: CacheIndexer

L-SMASH-Works indexer.

Unlike the plugin's default behavior, the indexer cache file will be stored in .vsjet/vssource next to the script file.

When cachefile=None, the behavior falls back to the default cache handling defined by the plugin itself.

Methods:

  • asource

    Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.

  • ensure_obj

    Ensure that the input is a indexer instance, resolving it if necessary.

  • from_param

    Resolve and return an Indexer type from a given input (string, type, or instance).

  • get_cache_path
  • has_audio

    Whether this indexer supports audio sourcing.

  • has_video

    Whether this indexer supports video sourcing.

  • normalize_filenames
  • source

    Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

  • source_func

Attributes:

Source code in vssource/indexers/base.py
57
58
59
60
61
def __init__(self, *, force: bool = True, **kwargs: Any) -> None:
    super().__init__()

    self.force = force
    self.indexer_kwargs = kwargs

force instance-attribute

force = force

indexer_kwargs instance-attribute

indexer_kwargs = kwargs

asource

asource(
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> AudioNode

Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.

Source code in vssource/indexers/base.py
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
@inject_self
def asource(
    self,
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> vs.AudioNode:
    """
    Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.
    """
    if not self.has_audio:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support audio indexing!", self.asource)

    nfiles = self.normalize_filenames(file)
    call_kwargs = self.indexer_kwargs | kwargs
    if self._audio_track_arg_name not in call_kwargs and track is not None:
        call_kwargs[self._audio_track_arg_name] = track

    clips = [self._asource_file(f.to_str(), **call_kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.AudioSplice(clips)

    if sample_rate is not None or channels is not None or bits is not None:
        clip = core.std.AudioResample(clip, samplerate=sample_rate, channels=channels, bits=bits)

    return clip

ensure_obj classmethod

ensure_obj(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> Self

Ensure that the input is a indexer instance, resolving it if necessary.

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

  • Self

    Indexer instance.

Source code in vssource/indexers/base.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
@classmethod
def ensure_obj(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> Self:
    """
    Ensure that the input is a indexer instance, resolving it if necessary.

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Indexer instance.
    """
    return _base_ensure_obj(cls, indexer, func_except)

from_param classmethod

from_param(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> type[Self]

Resolve and return an Indexer type from a given input (string, type, or instance).

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

Source code in vssource/indexers/base.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@classmethod
def from_param(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> type[Self]:
    """
    Resolve and return an Indexer type from a given input (string, type, or instance).

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Resolved indexer type.
    """
    return _base_from_param(cls, indexer, func_except)

get_cache_path staticmethod

get_cache_path(
    source_path: SPathLike,
    ext: str | None = None,
    track: int | None = None,
    is_audio: bool = False,
) -> SPath
Source code in vssource/indexers/base.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
@staticmethod
def get_cache_path(
    source_path: SPathLike,
    ext: str | None = None,
    track: int | None = None,
    is_audio: bool = False,
) -> SPath:
    source_file = SPath(source_path).resolve()
    hashed_path = hashlib.blake2s(source_file.to_str().encode("utf-8"), digest_size=4).hexdigest()
    cache_filename = f"{source_file.name}_{hashed_path}"

    if is_audio and ext:
        tr_suffix = f"_a{track if track is not None else 0}"
        cache_filename = f"{cache_filename}{tr_suffix}"

    if ext:
        cache_filename = f"{cache_filename}.{ext.lstrip('.')}"

    storage = _get_indexer_cache_storage()
    return storage.get_file(cache_filename)

has_audio classmethod

has_audio() -> bool

Whether this indexer supports audio sourcing.

Source code in vssource/indexers/base.py
69
70
71
72
73
@classproperty
@classmethod
def has_audio(cls) -> bool:
    """Whether this indexer supports audio sourcing."""
    return getattr(cls, "_asource_func", None) is not None

has_video classmethod

has_video() -> bool

Whether this indexer supports video sourcing.

Source code in vssource/indexers/base.py
63
64
65
66
67
@classproperty
@classmethod
def has_video(cls) -> bool:
    """Whether this indexer supports video sourcing."""
    return getattr(cls, "_source_func", None) is not None

normalize_filenames classmethod

normalize_filenames(file: SPathLike | Iterable[SPathLike]) -> list[SPath]
Source code in vssource/indexers/base.py
187
188
189
190
191
192
193
194
195
196
197
@classmethod
def normalize_filenames(cls, file: SPathLike | Iterable[SPathLike]) -> list[SPath]:
    files = list[SPath]()

    for f in to_arr(file):
        if str(f).startswith("file:///"):
            f = str(f)[8::]

        files.append(SPath(f))

    return files

source

source(
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> VideoNode

Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

The returned clip is passed through initialize_clip to apply bit depth conversion and frame props initialization.

Source code in vssource/indexers/base.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@inject_self
def source(
    self,
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: vs.VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> vs.VideoNode:
    """
    Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

    The returned clip is passed through [initialize_clip][vstools.initialize_clip] to apply bit depth conversion
    and frame props initialization.
    """
    if not self.has_video:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support video indexing!", self.source)

    nfiles = self.normalize_filenames(file)
    clips = [self._source_file(f.to_str(), **self.indexer_kwargs | kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.Splice(clips)
    clip = initialize_clip(clip, bits, matrix, transfer, primaries, chroma_location, color_range, field_based)

    if idx_props:
        clip = clip.std.SetFrameProps(IdxFilePath=[f.to_str() for f in nfiles], Idx=self.__class__.__name__)

    if name:
        clip = clip.std.SetFrameProps(Name=name)

    if ref:
        clip = match_clip(clip, ref, length=True)

    return clip

source_func classmethod

source_func(path: SPathLike, **kwargs: Any) -> VideoNode
Source code in vssource/indexers/base.py
179
180
181
182
183
184
185
@classmethod
@deprecated(
    "`source_func` is deprecated and will be removed in a future version. Use `source` instead.",
    category=DeprecationWarning,
)
def source_func(cls, path: SPathLike, **kwargs: Any) -> vs.VideoNode:
    return cls._source_file(path, **kwargs)

ZipSource

ZipSource(*, force: bool = True, **kwargs: Any)

Bases: Indexer

vszip image reader indexer

Methods:

  • asource

    Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.

  • ensure_obj

    Ensure that the input is a indexer instance, resolving it if necessary.

  • from_param

    Resolve and return an Indexer type from a given input (string, type, or instance).

  • has_audio

    Whether this indexer supports audio sourcing.

  • has_video

    Whether this indexer supports video sourcing.

  • normalize_filenames
  • source

    Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

  • source_func

Attributes:

Source code in vssource/indexers/base.py
57
58
59
60
61
def __init__(self, *, force: bool = True, **kwargs: Any) -> None:
    super().__init__()

    self.force = force
    self.indexer_kwargs = kwargs

force instance-attribute

force = force

indexer_kwargs instance-attribute

indexer_kwargs = kwargs

asource

asource(
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> AudioNode

Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.

Source code in vssource/indexers/base.py
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
@inject_self
def asource(
    self,
    file: SPathLike | Iterable[SPathLike],
    *,
    track: int = -1,
    sample_rate: int | None = None,
    channels: Sequence[int] | None = None,
    bits: int | None = None,
    **kwargs: Any,
) -> vs.AudioNode:
    """
    Load one or more input files as an [AudioNode][vs.AudioNode] using the indexer.
    """
    if not self.has_audio:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support audio indexing!", self.asource)

    nfiles = self.normalize_filenames(file)
    call_kwargs = self.indexer_kwargs | kwargs
    if self._audio_track_arg_name not in call_kwargs and track is not None:
        call_kwargs[self._audio_track_arg_name] = track

    clips = [self._asource_file(f.to_str(), **call_kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.AudioSplice(clips)

    if sample_rate is not None or channels is not None or bits is not None:
        clip = core.std.AudioResample(clip, samplerate=sample_rate, channels=channels, bits=bits)

    return clip

ensure_obj classmethod

ensure_obj(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> Self

Ensure that the input is a indexer instance, resolving it if necessary.

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

  • Self

    Indexer instance.

Source code in vssource/indexers/base.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
@classmethod
def ensure_obj(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> Self:
    """
    Ensure that the input is a indexer instance, resolving it if necessary.

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Indexer instance.
    """
    return _base_ensure_obj(cls, indexer, func_except)

from_param classmethod

from_param(
    indexer: str | type[Self] | Self | None = None,
    /,
    func_except: FuncExcept | None = None,
) -> type[Self]

Resolve and return an Indexer type from a given input (string, type, or instance).

Parameters:

  • indexer

    (str | type[Self] | Self | None, default: None ) –

    Indexer identifier (string, class, or instance). Plugin namespace is also supported.

  • func_except

    (FuncExcept | None, default: None ) –

    Function returned for custom error handling.

Returns:

Source code in vssource/indexers/base.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@classmethod
def from_param(
    cls, indexer: str | type[Self] | Self | None = None, /, func_except: FuncExcept | None = None
) -> type[Self]:
    """
    Resolve and return an Indexer type from a given input (string, type, or instance).

    Args:
        indexer: Indexer identifier (string, class, or instance). Plugin namespace is also supported.
        func_except: Function returned for custom error handling.

    Returns:
        Resolved indexer type.
    """
    return _base_from_param(cls, indexer, func_except)

has_audio classmethod

has_audio() -> bool

Whether this indexer supports audio sourcing.

Source code in vssource/indexers/base.py
69
70
71
72
73
@classproperty
@classmethod
def has_audio(cls) -> bool:
    """Whether this indexer supports audio sourcing."""
    return getattr(cls, "_asource_func", None) is not None

has_video classmethod

has_video() -> bool

Whether this indexer supports video sourcing.

Source code in vssource/indexers/base.py
63
64
65
66
67
@classproperty
@classmethod
def has_video(cls) -> bool:
    """Whether this indexer supports video sourcing."""
    return getattr(cls, "_source_func", None) is not None

normalize_filenames classmethod

normalize_filenames(file: SPathLike | Iterable[SPathLike]) -> list[SPath]
Source code in vssource/indexers/base.py
187
188
189
190
191
192
193
194
195
196
197
@classmethod
def normalize_filenames(cls, file: SPathLike | Iterable[SPathLike]) -> list[SPath]:
    files = list[SPath]()

    for f in to_arr(file):
        if str(f).startswith("file:///"):
            f = str(f)[8::]

        files.append(SPath(f))

    return files

source

source(
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> VideoNode

Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

The returned clip is passed through initialize_clip to apply bit depth conversion and frame props initialization.

Source code in vssource/indexers/base.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@inject_self
def source(
    self,
    file: SPathLike | Iterable[SPathLike],
    bits: int | None = 32,
    *,
    matrix: MatrixLike | None = None,
    transfer: TransferLike | None = None,
    primaries: PrimariesLike | None = None,
    chroma_location: ChromaLocation | None = None,
    color_range: RangeLike | None = None,
    field_based: FieldBasedLike | None = None,
    idx_props: bool = True,
    ref: vs.VideoNode | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> vs.VideoNode:
    """
    Load one or more input files as a [VideoNode][vs.VideoNode] using the indexer.

    The returned clip is passed through [initialize_clip][vstools.initialize_clip] to apply bit depth conversion
    and frame props initialization.
    """
    if not self.has_video:
        raise CustomRuntimeError(f"{self.__class__.__name__} does not support video indexing!", self.source)

    nfiles = self.normalize_filenames(file)
    clips = [self._source_file(f.to_str(), **self.indexer_kwargs | kwargs) for f in nfiles]
    clip = clips[0] if len(clips) == 1 else core.std.Splice(clips)
    clip = initialize_clip(clip, bits, matrix, transfer, primaries, chroma_location, color_range, field_based)

    if idx_props:
        clip = clip.std.SetFrameProps(IdxFilePath=[f.to_str() for f in nfiles], Idx=self.__class__.__name__)

    if name:
        clip = clip.std.SetFrameProps(Name=name)

    if ref:
        clip = match_clip(clip, ref, length=True)

    return clip

source_func classmethod

source_func(path: SPathLike, **kwargs: Any) -> VideoNode
Source code in vssource/indexers/base.py
179
180
181
182
183
184
185
@classmethod
@deprecated(
    "`source_func` is deprecated and will be removed in a future version. Use `source` instead.",
    category=DeprecationWarning,
)
def source_func(cls, path: SPathLike, **kwargs: Any) -> vs.VideoNode:
    return cls._source_file(path, **kwargs)