Source code for cv2ext.io._writer

# Copyright (c) 2024 Justin Davis (davisjustin302@gmail.com)
#
# MIT License
from __future__ import annotations

from typing import TYPE_CHECKING

import cv2

from ._display import Display
from ._fourcc import Fourcc

if TYPE_CHECKING:
    from pathlib import Path
    from types import TracebackType

    import numpy as np
    from typing_extensions import Self


[docs] class VideoWriter: def __init__( self: Self, filename: Path | str, fourcc: Fourcc = Fourcc.mp4v, fps: float = 30.0, frame_size: tuple[int, int] | None = None, *, show: bool | None = None, ) -> None: """ Create a new video writer. Parameters ---------- filename : Path | str The name of the file to write to. fourcc : Fourcc The fourcc codec to use. Defaults to MP4V. fps : float The frames per second of the video. Defaults to 30.0. frame_size : tuple[int, int] | None The size of the frames. If None, the first frame written will determine the size. Defaults to None. show : bool | None If True, the video will be displayed while writing. If False, the video will not be displayed. If None, the video will not be displayed. Useful if a video stream should be written to disk and displayed. """ self._filename = str(filename) self._fourcc = fourcc self._fps = fps self._frame_size = frame_size # allocate writer once first frame is written self._writer: cv2.VideoWriter | None = None # handle display allocation self._display = None if show: self._display = Display(self._filename) def __enter__(self: Self) -> Self: return self def __exit__( self: Self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, ) -> None: self.release()
[docs] def write(self: Self, frame: np.ndarray) -> None: """ Write a new frame to the video. Parameters ---------- frame : np.ndarray The frame to write. """ if self._writer is None: if self._frame_size is None: width, height = frame.shape[:2][::-1] self._frame_size = (width, height) self._writer = cv2.VideoWriter( self._filename, self._fourcc.value, self._fps, self._frame_size, ) self._writer.write(frame) if self._display: self._display(frame)
[docs] def release(self: Self) -> None: """Release the video writer.""" if self._writer is None: return self._writer.release() if self._display: self._display.stop()