Source code for cutcutcodec.core.io

"""Manage the input/output layer."""

import logging
import pathlib
import typing

from cutcutcodec.core.classes.colorspace import Colorspace
from cutcutcodec.core.classes.node import Node
from cutcutcodec.core.classes.stream import Stream
from cutcutcodec.core.exceptions import DecodeError

from .cst import AUDIO_SUFFIXES, IMAGE_SUFFIXES, VIDEO_SUFFIXES
from .read_color import filter_video_colorspace
from .read_ffmpeg import ContainerInputFFMPEG
from .read_image import ContainerInputImage
from .read_svg import ContainerInputSVG
from .write_ffmpeg import ContainerOutputFFMPEG

__all__ = ["AUDIO_SUFFIXES", "IMAGE_SUFFIXES", "VIDEO_SUFFIXES", "read", "write"]


[docs] def read( filename: pathlib.Path | str | bytes, colorspace: Colorspace | str | None = None, **kwargs, ) -> Node: """Open the media file with the appropriate reader. Parameters ---------- filename : pathlike The path to the file to be decoded. colorspace : str or Colorspace, optional Transmitted to :py:class:`cutcutcodec.core.filter.video.colorspace.FilterVideoColorspace`. **kwargs : dict Transmitted to :py:class:`cutcutcodec.core.io.read_ffmpeg.ContainerInputFFMPEG` or :py:class:`cutcutcodec.core.io.read_image.ContainerInputImage` or :py:class:`cutcutcodec.core.io.read_svg.ContainerInputSVG`. Returns ------- container : cutcutcodec.core.classes.container.ContainerInput The appropriated instanciated container, according to the nature of the file. Raises ------ cutcutcodec.core.exceptions.DecodeError If the file can not be decoded by any reader. """ extension = pathlib.Path(filename).suffix.lower() # simple case where extension is knowned if extension in VIDEO_SUFFIXES | AUDIO_SUFFIXES: return filter_video_colorspace(ContainerInputFFMPEG(filename, **kwargs), colorspace) if extension in IMAGE_SUFFIXES: return filter_video_colorspace(ContainerInputImage(filename, **kwargs), colorspace) if extension in {".svg"}: return filter_video_colorspace(ContainerInputSVG(filename, **kwargs), colorspace) # case we have to try logging.warning("unknown extension %s, try several readers", extension) try: return filter_video_colorspace(ContainerInputSVG(filename, **kwargs), colorspace) except DecodeError: try: return filter_video_colorspace(ContainerInputFFMPEG(filename, **kwargs), colorspace) except DecodeError: return filter_video_colorspace(ContainerInputImage(filename, **kwargs), colorspace)
[docs] def write( streams: typing.Iterable[Stream], filename: pathlib.Path | str | bytes, colorspace: Colorspace | str | None = None, **kwargs, ): """Create, write and encode the multimedia file. This is a high-level version of the ``write`` method of the :py:class:`cutcutcodec.core.io.write_ffmpeg.ContainerOutputFFMPEG` class. Parameters ---------- streams : iterable[Stream] These are all the audio and video streams that will be present in the final container. filename : pathlike The path to the media file to be encoded. colorspace : str or Colorspace, optional The encoded colorspace, by default, it is :py:meth:`cutcutcodec.core.classes.colorspace.Colorspace.from_default_target`. Transmitted to :py:class:`cutcutcodec.core.filter.video.colorspace.FilterVideoColorspace`. """ if colorspace is None: colorspace = Colorspace.from_default_target() else: colorspace = Colorspace(colorspace) streams = [s.apply_video_colorspace(colorspace) if s.type == "video" else s for s in streams] ContainerOutputFFMPEG(streams, filename, **kwargs).write()