Source code for cutcutcodec.core.analysis.video.properties.rate
"""Find the average frame rate of a video stream.
This information is collected in the metadata of the file.
Its access is fast but its value is not always accurate.
Especially since the framerate is not always constant within the same stream.
"""
import collections
import pathlib
from fractions import Fraction
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_rate_ffmpeg, _map_index_rel_to_abs
from cutcutcodec.core.exceptions import MissingInformation, MissingStreamError
def _estimate_rate_cv2(filename: str, index: int) -> Fraction:
"""Retrieve via cv2, the metadata concerning the fps.
This function is fast because it reads only the header of the file.
Examples
--------
>>> from cutcutcodec.core.analysis.video.properties.rate import _estimate_rate_cv2
>>> from cutcutcodec.utils import get_project_root
>>> video = str(get_project_root() / "media" / "video" / "intro.webm")
>>> _estimate_rate_cv2(video, 0)
Fraction(30000, 1001)
>>>
"""
cap = cv2.VideoCapture(filename, index)
if not cap.isOpened():
raise MissingStreamError(f"impossible to open '{filename}' stream {index} with 'cv2'")
fps = Fraction(cap.get(cv2.CAP_PROP_FPS)).limit_denominator(1001)
cap.release()
if fps <= 0:
raise MissingInformation(f"'cv2' finds an fps of {fps} in '{filename}' stream {index}")
return fps
[docs]
def get_rate_video(
filename: pathlib.Path | str | bytes,
index: int = 0,
*,
backend: str | None = None,
) -> Fraction:
"""Read in the metadata, the average frequency of the frames.
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
-------
fps : Fraction
The average frequency of the frames in Hz.
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.rate import get_rate_video
>>> from cutcutcodec.utils import get_project_root
>>> video = get_project_root() / "media" / "video" / "intro.webm"
>>> get_rate_video(video)
Fraction(30000, 1001)
>>>
"""
_check_pathexists_index(filename, index)
return _mix_and_check(
backend, False, (str(pathlib.Path(filename)), index),
collections.OrderedDict([
(
(
lambda filename, index: _estimate_rate_ffmpeg(
filename, _map_index_rel_to_abs(filename, index, "video"),
)
),
{"accurate": False, "backend": "ffmpeg"},
),
(_estimate_rate_cv2, {"accurate": False, "backend": "cv2"}),
]),
)