Source code for cutcutcodec.core.analysis.video.properties.resolution
"""Find frame shape of a video stream."""
import collections
import pathlib
import cv2 # pip install opencv-contrib-python-headless
from cutcutcodec.core.analysis._helper_properties import _check_pathexists_index, _mix_and_check
from cutcutcodec.core.analysis.ffprobe import _estimate_resolution_ffmpeg, _map_index_rel_to_abs
from cutcutcodec.core.exceptions import MissingInformation, MissingStreamError
def _estimate_resolution_cv2(filename: str, index: int) -> tuple[int, int]:
"""Retrieve via cv2, the metadata concerning the resolution.
This function is fast because it reads only the header of the file.
Examples
--------
>>> from cutcutcodec.core.analysis.video.properties.resolution import _estimate_resolution_cv2
>>> from cutcutcodec.utils import get_project_root
>>> media = str(get_project_root() / "media" / "video" / "intro.webm")
>>> _estimate_resolution_cv2(media, 0)
(720, 1280)
>>>
"""
cap = cv2.VideoCapture(filename, index)
if not cap.isOpened():
raise MissingStreamError(f"impossible to open '{filename}' stream {index} with 'cv2'")
try:
shape = (
round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)), round(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
)
except TypeError as err:
raise MissingInformation(
f"'cv2' failed to find the resolution of '{filename}' stream {index}",
) from err
return shape
[docs]
def get_resolution(
filename: pathlib.Path | str | bytes,
index: int = 0,
*,
backend: str | None = None,
) -> tuple[int, int]:
"""Read in the metadata, the display video resolution.
Parameters
----------
filename : pathlike
The pathlike of the file containing a video stream.
index : int
The relative index of the video stream being considered,
by default the first stream encountered is selected.
backend : str, optional
- None (default) : Try to read the stream by trying differents backends.
- 'ffmpeg' : Uses the modules ``pip install ffmpeg-python``
which are using the ``ffmpeg`` program in the background.
- 'cv2' : Uses the module ``pip install opencv-contrib-python-headless``.
Returns
-------
height, width : int
The number of diplay pixel of the frames of the video stream.
Raises
------
MissingStreamError
If the file does not contain a playable video stream.
MissingInformation
If the information is unavailable.
Examples
--------
>>> from cutcutcodec.core.analysis.video.properties.resolution import get_resolution
>>> from cutcutcodec.utils import get_project_root
>>> media = get_project_root() / "media" / "video" / "intro.webm"
>>> get_resolution(media)
(720, 1280)
>>>
"""
_check_pathexists_index(filename, index)
return _mix_and_check(
backend, False, (str(pathlib.Path(filename)), index),
collections.OrderedDict([
(
(
lambda filename, index: _estimate_resolution_ffmpeg(
filename, _map_index_rel_to_abs(filename, index, "video"),
)
),
{"accurate": False, "backend": "ffmpeg"},
),
(_estimate_resolution_cv2, {"accurate": False, "backend": "cv2"}),
]),
)