Skip to content

FPSTimestamps

Bases: ABCTimestamps

Create a Timestamps object from a fps.

Source code in video_timestamps/fps_timestamps.py
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class FPSTimestamps(ABCTimestamps):
    """Create a Timestamps object from a fps.
    """

    def __init__(
        self,
        rounding_method: RoundingMethod,
        time_scale: Fraction,
        fps: int | float | Fraction | Decimal,
        first_timestamps: Fraction = Fraction(0)
    ):
        """Initialize the FPSTimestamps object.

        To understand why the `rounding_method` and the `time_scale` are needed, see the detailed explanation in the
        [frame_to_time](../Algorithm conversion explanation.md#frame_to_time) section.
        If after reading the [frame_to_time](../Algorithm conversion explanation.md#frame_to_time) section,
        you still think you need to have `time = frame * (1/fps)` instead of `time = pts * timebase`, use **any** `rounding_method` and use the same value for the `time_scale` as for the `fps`.
        It will be the equivalent.

        Parameters:
            rounding_method: The rounding method used to round/floor the PTS (Presentation Time Stamp).
            time_scale: Unit of time (in seconds) in terms of which frame PTS are represented.
            fps: Frames per second (must be > 0).
            first_timestamps: The first timestamp of the video. By default, 0.
        """
        if time_scale <= 0:
            raise ValueError("Parameter ``time_scale`` must be higher than 0.")

        if fps <= 0:
            raise ValueError("Parameter ``fps`` must be higher than 0.")

        self.__rounding_method = rounding_method
        self.__time_scale = time_scale
        self.__fps = Fraction(fps)
        self.__first_timestamps = first_timestamps

    @property
    def rounding_method(self) -> RoundingMethod:
        return self.__rounding_method

    @property
    def fps(self) -> Fraction:
        return self.__fps

    @property
    def time_scale(self) -> Fraction:
        return self.__time_scale

    @property
    def first_timestamps(self) -> Fraction:
        return self.__first_timestamps


    def _time_to_frame(
        self,
        time: Fraction,
        time_type: TimeType,
    ) -> int:
        # To understand this, refer to docs/Algorithm conversion explanation.md
        if time_type == TimeType.START:
            if self.rounding_method == RoundingMethod.ROUND:
                frame = ceil(((ceil(time * self.time_scale) - Fraction(1, 2)) / self.time_scale - self.first_timestamps) * self.fps + Fraction(1)) - 1
            elif self.rounding_method == RoundingMethod.FLOOR:
                frame = ceil(((ceil(time * self.time_scale)) / self.time_scale - self.first_timestamps) * self.fps + Fraction(1)) - 1
        elif time_type == TimeType.END:
            if self.rounding_method == RoundingMethod.ROUND:
                frame = ceil(((ceil(time * self.time_scale) - Fraction(1, 2)) / self.time_scale - self.first_timestamps) * self.fps) - 1
            elif self.rounding_method == RoundingMethod.FLOOR:
                frame = ceil(((ceil(time * self.time_scale)) / self.time_scale - self.first_timestamps) * self.fps) - 1
        elif time_type == TimeType.EXACT:
            if self.rounding_method == RoundingMethod.ROUND:
                frame = ceil(((floor(time * self.time_scale) + Fraction(1, 2)) / self.time_scale - self.first_timestamps) * self.fps) - 1
            elif self.rounding_method == RoundingMethod.FLOOR:
                frame = ceil(((floor(time * self.time_scale) + Fraction(1)) / self.time_scale - self.first_timestamps) * self.fps) - 1
        else:
            raise ValueError(f'The TimeType "{time_type}" isn\'t supported.')

        return frame


    def _frame_to_time(
        self,
        frame: int,
    ) -> Fraction:
        # To understand this, refer to docs/Algorithm conversion explanation.md
        return self.rounding_method((frame/self.fps + self.first_timestamps) * self.time_scale) / self.time_scale


    def __eq__(self, other: object) -> bool:
        if not isinstance(other, FPSTimestamps):
            return False
        return (self.rounding_method, self.fps, self.time_scale, self.first_timestamps) == (
            other.rounding_method, other.fps, other.time_scale, other.first_timestamps
        )


    def __hash__(self) -> int:
        return hash(
            (
                self.rounding_method,
                self.fps,
                self.time_scale,
                self.first_timestamps,
            )
        )

__init__(rounding_method, time_scale, fps, first_timestamps=Fraction(0))

Initialize the FPSTimestamps object.

To understand why the rounding_method and the time_scale are needed, see the detailed explanation in the frame_to_time section. If after reading the frame_to_time section, you still think you need to have time = frame * (1/fps) instead of time = pts * timebase, use any rounding_method and use the same value for the time_scale as for the fps. It will be the equivalent.

Parameters:

Name Type Description Default
rounding_method RoundingMethod

The rounding method used to round/floor the PTS (Presentation Time Stamp).

required
time_scale Fraction

Unit of time (in seconds) in terms of which frame PTS are represented.

required
fps int | float | Fraction | Decimal

Frames per second (must be > 0).

required
first_timestamps Fraction

The first timestamp of the video. By default, 0.

Fraction(0)
Source code in video_timestamps/fps_timestamps.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def __init__(
    self,
    rounding_method: RoundingMethod,
    time_scale: Fraction,
    fps: int | float | Fraction | Decimal,
    first_timestamps: Fraction = Fraction(0)
):
    """Initialize the FPSTimestamps object.

    To understand why the `rounding_method` and the `time_scale` are needed, see the detailed explanation in the
    [frame_to_time](../Algorithm conversion explanation.md#frame_to_time) section.
    If after reading the [frame_to_time](../Algorithm conversion explanation.md#frame_to_time) section,
    you still think you need to have `time = frame * (1/fps)` instead of `time = pts * timebase`, use **any** `rounding_method` and use the same value for the `time_scale` as for the `fps`.
    It will be the equivalent.

    Parameters:
        rounding_method: The rounding method used to round/floor the PTS (Presentation Time Stamp).
        time_scale: Unit of time (in seconds) in terms of which frame PTS are represented.
        fps: Frames per second (must be > 0).
        first_timestamps: The first timestamp of the video. By default, 0.
    """
    if time_scale <= 0:
        raise ValueError("Parameter ``time_scale`` must be higher than 0.")

    if fps <= 0:
        raise ValueError("Parameter ``fps`` must be higher than 0.")

    self.__rounding_method = rounding_method
    self.__time_scale = time_scale
    self.__fps = Fraction(fps)
    self.__first_timestamps = first_timestamps