Skip to content

Backend Selectable Processor

Backend registry mixin for processor families.

This module provides BackendSelectableProcessor, the abstract base class for processor families that support multiple backend implementations (e.g. GStreamer, FFmpeg).

How it works

Each processor family owns its backend registry. Concrete backend classes are auto-registered via __init_subclass__ by declaring:

  • BACKEND: backend key, e.g. gstreamer or ffmpeg
  • IS_DEFAULT: whether this backend is the family default

Minimal contributor pattern

# In base.py — family base class
class ImageTilingProcessor(BackendSelectableProcessor):
    ...

# In pil_backend.py — concrete backend
class PilImageTilingProcessor(ImageTilingProcessor):
    BACKEND = "pil"
    IS_DEFAULT = True

# In cv2_backend.py — another concrete backend
class Cv2ImageTilingProcessor(ImageTilingProcessor):
    BACKEND = "cv2"

Usage

# Build by family name + backend
processor = MediaToolkit.build("ImageTilingProcessor", backend="pil")

# Or use the default backend
processor = MediaToolkit.build("ImageTilingProcessor")

BackendSelectableProcessor()

Bases: MediaToolkit[T_in, T_out], ABC

Abstract base for a processor family with pluggable backends.

Each family owns its backend registry. Concrete backend classes are auto-registered via __init_subclass__ by declaring:

  • BACKEND: backend key, e.g. gstreamer or ffmpeg
  • IS_DEFAULT: whether this backend is the family default
Why this exists

It lets callers construct by stable family class name while deferring runtime selection of backend implementation.

Minimal contributor pattern
# base.py
class ImageTilingProcessor(BackendSelectableProcessor):
    pass

# pil_backend.py
class PilImageTilingProcessor(ImageTilingProcessor):
    BACKEND = "pil"

# cv2_backend.py
class Cv2ImageTilingProcessor(ImageTilingProcessor):
    BACKEND = "cv2"
Then callers can use

MediaToolkit.build("ImageTilingProcessor", backend="pil").

__init_subclass__(**kwargs)

Automatically register backend classes into their family registry.

This hook runs at class definition/import time and maintains per-family backend mappings used by backend-selectable builds.

Registration flow
  1. If cls is the family base itself (e.g. VideoClipProcessor), reset _backends and _default_backend for that family.
  2. If cls is abstract, skip registration.
  3. Otherwise treat cls as a concrete backend implementation:
  4. require class variable BACKEND (e.g. "gstreamer"),
  5. reject duplicate backend keys within the same family,
  6. add mapping family_base._backends[BACKEND] = cls.
Default backend resolution
  1. If IS_DEFAULT=True on a concrete class, that backend becomes the family's default, even if a first-registered fallback already exists.
  2. If no explicit default exists yet, the first registered backend is used as fallback default.
  3. Multiple IS_DEFAULT=True declarations in one family raise ValueError.

Parameters:

Name Type Description Default
**kwargs Any

Extra class declaration keyword arguments forwarded to parent __init_subclass__ implementations.

{}

Raises:

Type Description
TypeError

If a concrete backend class omits BACKEND.

ValueError

If duplicate backend keys are registered in one family.

ValueError

If more than one backend declares IS_DEFAULT=True.

build(backend=None, **kwargs) classmethod

Build a backend implementation for this processor family.

Parameters:

Name Type Description Default
backend str | None

Backend key. Uses the family default when omitted.

None
**kwargs Any

Constructor kwargs forwarded to the backend class.

{}

Returns:

Name Type Description
BackendSelectableProcessor BackendSelectableProcessor

Instantiated backend processor.

Raises:

Type Description
ValueError

If the backend is unknown or no default is configured.

Example

For a family class AudioExtractionProcessor, AudioExtractionProcessor.build(backend="gstreamer") returns the registered GStreamer implementation class instance.

<GstAudioExtractionProcessor instance>

build_from_registry(backend=None, **kwargs) classmethod

Build a family backend or instantiate a concrete backend class.

Parameters:

Name Type Description Default
backend str | MediaBackend | None

Backend key for family resolution. Defaults to None.

None
**kwargs Any

Constructor kwargs forwarded to the backend class.

{}

Returns:

Name Type Description
BackendSelectableProcessor BackendSelectableProcessor

Instantiated processor.

Example

processor = AudioExtractionProcessor.build_from_registry(backend="gstreamer")
<GstAudioExtractionProcessor instance>

get_install_hint(backend=None) classmethod

Return the installation hint for a backend.

Reads INSTALL_HINT from the registered backend class. If the backend is not registered or carries no hint, returns a generic fallback.

Parameters:

Name Type Description Default
backend str | None

Backend key to look up. Defaults to _default_backend when None.

None

Returns:

Name Type Description
str str

Human-readable install hint for the backend, or a generic fallback.

is_family_base(processor_cls) classmethod

Return whether processor_cls is a family abstract base.

Parameters:

Name Type Description Default
processor_cls type[BackendSelectableProcessor]

Candidate processor class.

required

Returns:

Name Type Description
bool bool

True when the class directly subclasses BackendSelectableProcessor.

Example

assert BackendSelectableProcessor.is_family_base(AudioExtractionProcessor) is True
True

list_available_backends() classmethod

Return registered backend keys for backend-selectable family bases.

Returns:

Type Description
list[str]

list[str]: Backend keys available for build. Empty for concrete backend implementations and non-family classes.

Example

AudioExtractionProcessor.list_available_backends()
# e.g. ["gstreamer", "ffmpeg", "moviepy"]
["gstreamer", "ffmpeg", "moviepy"]

list_backends() classmethod

Return registered backend keys for this processor family.

Returns:

Type Description
list[str]

list[str]: Backend keys available for build.

Example

backends = AudioExtractionProcessor.list_backends()
["gstreamer", "ffmpeg", "moviepy"]