Get a formatted timecode string of the form HH:MM:SS[.nnn]. Args: precision: The number of decimal places to include in the output ``[.nnn]``. use_rounding: Rounds the output to the desired precision. If False, the value will be truncated to the speci
(
self, precision: int = 3, use_rounding: bool = True, nearest_frame: bool = True
)
| 405 | # We may also just need to clamp end time to the one specified by the user, this may not be |
| 406 | # happening in the code. |
| 407 | def get_timecode( |
| 408 | self, precision: int = 3, use_rounding: bool = True, nearest_frame: bool = True |
| 409 | ) -> str: |
| 410 | """Get a formatted timecode string of the form HH:MM:SS[.nnn]. |
| 411 | |
| 412 | Args: |
| 413 | precision: The number of decimal places to include in the output ``[.nnn]``. |
| 414 | use_rounding: Rounds the output to the desired precision. If False, the value |
| 415 | will be truncated to the specified precision. |
| 416 | nearest_frame: Ensures that the timecode is moved to the nearest frame boundary if this |
| 417 | object has a defined framerate, otherwise has no effect. |
| 418 | |
| 419 | Returns: |
| 420 | str: The current time in the form ``"HH:MM:SS[.nnn]"``. |
| 421 | """ |
| 422 | # Compute hours and minutes based off of seconds, and update seconds. |
| 423 | # For PTS-backed timecodes, the PTS already represents an exact frame boundary, so we use |
| 424 | # `seconds` directly. For non-PTS timecodes, `nearest_frame` snaps to the nearest frame |
| 425 | # boundary using frame_num, which avoids floating point drift in CFR video display. |
| 426 | if nearest_frame and self.frame_rate and not isinstance(self._time, Timecode): |
| 427 | secs = self.frame_num / float(self.frame_rate) |
| 428 | else: |
| 429 | secs = self.seconds |
| 430 | hrs = int(secs / _SECONDS_PER_HOUR) |
| 431 | secs -= hrs * _SECONDS_PER_HOUR |
| 432 | mins = int(secs / _SECONDS_PER_MINUTE) |
| 433 | secs = max(0.0, secs - (mins * _SECONDS_PER_MINUTE)) |
| 434 | if use_rounding: |
| 435 | secs = round(secs, precision) |
| 436 | secs = min(_SECONDS_PER_MINUTE, secs) |
| 437 | # Guard against emitting timecodes with 60 seconds after rounding/floating point errors. |
| 438 | if int(secs) == _SECONDS_PER_MINUTE: |
| 439 | secs = 0.0 |
| 440 | mins += 1 |
| 441 | if mins >= _MINUTES_PER_HOUR: |
| 442 | mins = 0 |
| 443 | hrs += 1 |
| 444 | # We have to extend the precision by 1 here, since `format` will round up. |
| 445 | msec = format(secs, f".{precision + 1}f") if precision else "" |
| 446 | # Need to include decimal place in `msec_str`. |
| 447 | msec_str = msec[-(2 + precision) : -1] |
| 448 | secs_str = f"{int(secs):02d}{msec_str}" |
| 449 | # Return hours, minutes, and seconds as a formatted timecode string. |
| 450 | return f"{hrs:02d}:{mins:02d}:{secs_str}" |
| 451 | |
| 452 | @staticmethod |
| 453 | def _ensure_fractional(fps: "FrameRate | FrameTimecode") -> Fraction: |
no outgoing calls