File: func.py

package info (click to toggle)
auto-editor 26.3.1%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 884 kB
  • sloc: python: 8,445; xml: 68; javascript: 27; makefile: 26
file content (107 lines) | stat: -rw-r--r-- 2,747 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
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
from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

if TYPE_CHECKING:
    from collections.abc import Callable
    from fractions import Fraction

    from numpy.typing import NDArray

    BoolList = NDArray[np.bool_]
    BoolOperand = Callable[[BoolList, BoolList], BoolList]


def boolop(a: BoolList, b: BoolList, call: BoolOperand) -> BoolList:
    if len(a) > len(b):
        k = np.copy(b)
        k.resize(len(a))
        b = k
    if len(b) > len(a):
        k = np.copy(a)
        k.resize(len(b))
        a = k

    return call(a, b)


def to_timecode(secs: float | Fraction, fmt: str) -> str:
    sign = ""
    if secs < 0:
        sign = "-"
        secs = -secs

    _m, _s = divmod(secs, 60)
    _h, _m = divmod(_m, 60)
    s, m, h = float(_s), int(_m), int(_h)

    if fmt == "webvtt":
        if h == 0:
            return f"{sign}{m:02d}:{s:06.3f}"
        return f"{sign}{h:02d}:{m:02d}:{s:06.3f}"
    if fmt in {"srt", "mov_text"}:
        return f"{sign}{h:02d}:{m:02d}:" + f"{s:06.3f}".replace(".", ",", 1)
    if fmt == "standard":
        return f"{sign}{h:02d}:{m:02d}:{s:06.3f}"
    if fmt == "ass":
        return f"{sign}{h:d}:{m:02d}:{s:05.2f}"
    if fmt == "rass":
        return f"{sign}{h:d}:{m:02d}:{s:02.0f}"

    raise ValueError("to_timecode: Unreachable")


def mut_margin(arr: BoolList, start_m: int, end_m: int) -> None:
    # Find start and end indexes
    start_index = []
    end_index = []
    arrlen = len(arr)
    for j in range(1, arrlen):
        if arr[j] != arr[j - 1]:
            if arr[j]:
                start_index.append(j)
            else:
                end_index.append(j)

    # Apply margin
    if start_m > 0:
        for i in start_index:
            arr[max(i - start_m, 0) : i] = True
    if start_m < 0:
        for i in start_index:
            arr[i : min(i - start_m, arrlen)] = False

    if end_m > 0:
        for i in end_index:
            arr[i : min(i + end_m, arrlen)] = True
    if end_m < 0:
        for i in end_index:
            arr[max(i + end_m, 0) : i] = False


def get_stdout(cmd: list[str]) -> str:
    from subprocess import DEVNULL, PIPE, Popen

    stdout = Popen(cmd, stdin=DEVNULL, stdout=PIPE, stderr=PIPE).communicate()[0]
    return stdout.decode("utf-8", "replace")


def get_stdout_bytes(cmd: list[str]) -> bytes:
    from subprocess import DEVNULL, PIPE, Popen

    return Popen(cmd, stdin=DEVNULL, stdout=PIPE, stderr=PIPE).communicate()[0]


def aspect_ratio(width: int, height: int) -> tuple[int, int]:
    if height == 0:
        return (0, 0)

    def gcd(a: int, b: int) -> int:
        while b:
            a, b = b, a % b
        return a

    c = gcd(width, height)
    return width // c, height // c