auto-editor 24.30.1__py3-none-any.whl → 25.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- auto_editor/__init__.py +1 -2
- auto_editor/__main__.py +12 -19
- auto_editor/analyze.py +26 -30
- auto_editor/edit.py +8 -11
- auto_editor/ffwrapper.py +1 -1
- auto_editor/lang/palet.py +17 -23
- auto_editor/lib/contracts.py +5 -2
- auto_editor/lib/data_structs.py +2 -0
- auto_editor/make_layers.py +28 -47
- auto_editor/output.py +4 -6
- auto_editor/preview.py +2 -2
- auto_editor/render/audio.py +2 -1
- auto_editor/render/video.py +2 -7
- auto_editor/subcommands/levels.py +4 -9
- auto_editor/subcommands/repl.py +4 -7
- auto_editor/subcommands/test.py +33 -34
- auto_editor/timeline.py +10 -12
- auto_editor/utils/container.py +4 -0
- auto_editor/utils/func.py +10 -26
- auto_editor/utils/log.py +35 -8
- auto_editor/utils/types.py +2 -1
- auto_editor/vanparse.py +1 -2
- {auto_editor-24.30.1.dist-info → auto_editor-25.0.0.dist-info}/METADATA +1 -1
- auto_editor-25.0.0.dist-info/RECORD +55 -0
- {auto_editor-24.30.1.dist-info → auto_editor-25.0.0.dist-info}/WHEEL +1 -1
- auto_editor-24.30.1.dist-info/RECORD +0 -55
- {auto_editor-24.30.1.dist-info → auto_editor-25.0.0.dist-info}/LICENSE +0 -0
- {auto_editor-24.30.1.dist-info → auto_editor-25.0.0.dist-info}/entry_points.txt +0 -0
- {auto_editor-24.30.1.dist-info → auto_editor-25.0.0.dist-info}/top_level.txt +0 -0
auto_editor/render/video.py
CHANGED
@@ -105,13 +105,7 @@ def make_image_cache(tl: v3) -> dict[tuple[FileInfo, int], np.ndarray]:
|
|
105
105
|
|
106
106
|
|
107
107
|
def render_av(
|
108
|
-
ffmpeg: FFmpeg,
|
109
|
-
tl: v3,
|
110
|
-
args: Args,
|
111
|
-
bar: Bar,
|
112
|
-
ctr: Container,
|
113
|
-
temp: str,
|
114
|
-
log: Log,
|
108
|
+
ffmpeg: FFmpeg, tl: v3, args: Args, bar: Bar, ctr: Container, log: Log
|
115
109
|
) -> tuple[str, bool]:
|
116
110
|
src = tl.src
|
117
111
|
cns: dict[FileInfo, av.container.InputContainer] = {}
|
@@ -121,6 +115,7 @@ def render_av(
|
|
121
115
|
|
122
116
|
target_pix_fmt = "yuv420p" # Reasonable default
|
123
117
|
img_cache = make_image_cache(tl)
|
118
|
+
temp = log.temp
|
124
119
|
|
125
120
|
first_src: FileInfo | None = None
|
126
121
|
for src in tl.sources:
|
@@ -19,7 +19,6 @@ from auto_editor.utils.cmdkw import (
|
|
19
19
|
pAttr,
|
20
20
|
pAttrs,
|
21
21
|
)
|
22
|
-
from auto_editor.utils.func import setup_tempdir
|
23
22
|
from auto_editor.utils.log import Log
|
24
23
|
from auto_editor.utils.types import frame_rate
|
25
24
|
from auto_editor.vanparse import ArgumentParser
|
@@ -72,14 +71,11 @@ def print_arr(arr: NDArray) -> None:
|
|
72
71
|
print("")
|
73
72
|
|
74
73
|
|
75
|
-
def print_arr_gen(arr: Iterator[
|
74
|
+
def print_arr_gen(arr: Iterator[float | np.float32]) -> None:
|
76
75
|
print("")
|
77
76
|
print("@start")
|
78
77
|
for a in arr:
|
79
|
-
|
80
|
-
print(f"{a:.20f}")
|
81
|
-
else:
|
82
|
-
print(a)
|
78
|
+
print(f"{a:.20f}")
|
83
79
|
print("")
|
84
80
|
|
85
81
|
|
@@ -88,8 +84,7 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
|
|
88
84
|
args = parser.parse_args(LevelArgs, sys_args)
|
89
85
|
|
90
86
|
bar = Bar("none")
|
91
|
-
|
92
|
-
log = Log(quiet=True, temp=temp)
|
87
|
+
log = Log(quiet=True)
|
93
88
|
|
94
89
|
sources = [initFileInfo(path, log) for path in args.input]
|
95
90
|
if len(sources) < 1:
|
@@ -132,7 +127,7 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
|
|
132
127
|
except ParserError as e:
|
133
128
|
log.error(e)
|
134
129
|
|
135
|
-
levels = Levels(src, tb, bar,
|
130
|
+
levels = Levels(src, tb, bar, False, log, strict=True)
|
136
131
|
try:
|
137
132
|
if method == "audio":
|
138
133
|
print_arr_gen(iter_audio(src, tb, **obj))
|
auto_editor/subcommands/repl.py
CHANGED
@@ -5,13 +5,12 @@ from dataclasses import dataclass, field
|
|
5
5
|
from fractions import Fraction
|
6
6
|
|
7
7
|
import auto_editor
|
8
|
-
from auto_editor.analyze import
|
8
|
+
from auto_editor.analyze import Levels
|
9
9
|
from auto_editor.ffwrapper import initFileInfo
|
10
10
|
from auto_editor.lang.palet import ClosingError, Lexer, Parser, env, interpret
|
11
11
|
from auto_editor.lib.data_structs import print_str
|
12
12
|
from auto_editor.lib.err import MyError
|
13
13
|
from auto_editor.utils.bar import Bar
|
14
|
-
from auto_editor.utils.func import setup_tempdir
|
15
14
|
from auto_editor.utils.log import Log
|
16
15
|
from auto_editor.utils.types import frame_rate
|
17
16
|
from auto_editor.vanparse import ArgumentParser
|
@@ -59,18 +58,16 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
|
|
59
58
|
args = repl_options(ArgumentParser(None)).parse_args(REPL_Args, sys_args)
|
60
59
|
|
61
60
|
if args.input:
|
62
|
-
|
63
|
-
log = Log(quiet=True, temp=temp)
|
61
|
+
log = Log(quiet=True, temp_dir=args.temp_dir)
|
64
62
|
strict = len(args.input) < 2
|
65
63
|
sources = [initFileInfo(path, log) for path in args.input]
|
66
64
|
src = sources[0]
|
67
65
|
tb = src.get_fps() if args.timebase is None else args.timebase
|
68
66
|
bar = Bar("modern")
|
69
67
|
env["timebase"] = tb
|
70
|
-
env["@levels"] = Levels(src, tb, bar,
|
71
|
-
env["@filesetup"] = FileSetup(src, strict, tb, bar, temp, log)
|
68
|
+
env["@levels"] = Levels(src, tb, bar, False, log, strict)
|
72
69
|
|
73
|
-
print(f"Auto-Editor {auto_editor.
|
70
|
+
print(f"Auto-Editor {auto_editor.__version__}")
|
74
71
|
text = None
|
75
72
|
|
76
73
|
try:
|
auto_editor/subcommands/test.py
CHANGED
@@ -1,15 +1,13 @@
|
|
1
|
-
# type: ignore
|
2
1
|
from __future__ import annotations
|
3
2
|
|
4
3
|
import os
|
5
4
|
import shutil
|
6
5
|
import subprocess
|
7
6
|
import sys
|
8
|
-
from collections.abc import Callable
|
9
7
|
from dataclasses import dataclass, field
|
10
8
|
from fractions import Fraction
|
11
9
|
from time import perf_counter
|
12
|
-
from typing import
|
10
|
+
from typing import TYPE_CHECKING
|
13
11
|
|
14
12
|
import numpy as np
|
15
13
|
|
@@ -20,6 +18,12 @@ from auto_editor.lib.err import MyError
|
|
20
18
|
from auto_editor.utils.log import Log
|
21
19
|
from auto_editor.vanparse import ArgumentParser
|
22
20
|
|
21
|
+
if TYPE_CHECKING:
|
22
|
+
from collections.abc import Callable
|
23
|
+
from typing import Any
|
24
|
+
|
25
|
+
from auto_editor.vanparse import ArgumentParser
|
26
|
+
|
23
27
|
|
24
28
|
@dataclass(slots=True)
|
25
29
|
class TestArgs:
|
@@ -29,7 +33,7 @@ class TestArgs:
|
|
29
33
|
category: str = "cli"
|
30
34
|
|
31
35
|
|
32
|
-
def test_options(parser):
|
36
|
+
def test_options(parser: ArgumentParser) -> ArgumentParser:
|
33
37
|
parser.add_argument("--only", "-n", nargs="*")
|
34
38
|
parser.add_argument("--no-fail-fast", flag=True)
|
35
39
|
parser.add_required(
|
@@ -47,14 +51,6 @@ def pipe_to_console(cmd: list[str]) -> tuple[int, str, str]:
|
|
47
51
|
return process.returncode, stdout.decode("utf-8"), stderr.decode("utf-8")
|
48
52
|
|
49
53
|
|
50
|
-
class Checker:
|
51
|
-
def __init__(self, log: Log):
|
52
|
-
self.log = log
|
53
|
-
|
54
|
-
def check(self, path: str) -> FileInfo:
|
55
|
-
return initFileInfo(path, self.log)
|
56
|
-
|
57
|
-
|
58
54
|
class Runner:
|
59
55
|
def __init__(self) -> None:
|
60
56
|
self.program = [sys.executable, "-m", "auto_editor"]
|
@@ -176,7 +172,10 @@ def main(sys_args: list[str] | None = None):
|
|
176
172
|
args = test_options(ArgumentParser("test")).parse_args(TestArgs, sys_args)
|
177
173
|
|
178
174
|
run = Runner()
|
179
|
-
|
175
|
+
log = Log()
|
176
|
+
|
177
|
+
def fileinfo(path: str) -> FileInfo:
|
178
|
+
return initFileInfo(path, log)
|
180
179
|
|
181
180
|
### Tests ###
|
182
181
|
|
@@ -229,7 +228,7 @@ def main(sys_args: list[str] | None = None):
|
|
229
228
|
|
230
229
|
def example():
|
231
230
|
out = run.main(inputs=["example.mp4"], cmd=[])
|
232
|
-
cn =
|
231
|
+
cn = fileinfo(out)
|
233
232
|
video = cn.videos[0]
|
234
233
|
|
235
234
|
assert video.fps == 30
|
@@ -295,7 +294,7 @@ def main(sys_args: list[str] | None = None):
|
|
295
294
|
out = run.main(
|
296
295
|
["resources/only-video/man-on-green-screen.gif"], ["--edit", "none"]
|
297
296
|
)
|
298
|
-
assert
|
297
|
+
assert fileinfo(out).videos[0].codec == "gif"
|
299
298
|
|
300
299
|
return out
|
301
300
|
|
@@ -319,11 +318,11 @@ def main(sys_args: list[str] | None = None):
|
|
319
318
|
out = run.main(inputs=["example.mp4"], cmd=[], output="out")
|
320
319
|
|
321
320
|
assert out == "out.mp4"
|
322
|
-
assert
|
321
|
+
assert fileinfo(out).videos[0].codec == "h264"
|
323
322
|
|
324
323
|
out = run.main(inputs=["resources/testsrc.mkv"], cmd=[], output="out")
|
325
324
|
assert out == "out.mkv"
|
326
|
-
assert
|
325
|
+
assert fileinfo(out).videos[0].codec == "h264"
|
327
326
|
|
328
327
|
return "out.mp4", "out.mkv"
|
329
328
|
|
@@ -357,14 +356,14 @@ def main(sys_args: list[str] | None = None):
|
|
357
356
|
run.main(["example.mp4"], ["--export", 'premiere:name="Foo Bar"'])
|
358
357
|
|
359
358
|
def resolution_and_scale():
|
360
|
-
cn =
|
359
|
+
cn = fileinfo(run.main(["example.mp4"], ["--scale", "1.5"]))
|
361
360
|
|
362
361
|
assert cn.videos[0].fps == 30
|
363
362
|
assert cn.videos[0].width == 1920
|
364
363
|
assert cn.videos[0].height == 1080
|
365
364
|
assert cn.audios[0].samplerate == 48000
|
366
365
|
|
367
|
-
cn =
|
366
|
+
cn = fileinfo(run.main(["example.mp4"], ["--scale", "0.2"]))
|
368
367
|
|
369
368
|
assert cn.videos[0].fps == 30
|
370
369
|
assert cn.videos[0].width == 256
|
@@ -372,7 +371,7 @@ def main(sys_args: list[str] | None = None):
|
|
372
371
|
assert cn.audios[0].samplerate == 48000
|
373
372
|
|
374
373
|
out = run.main(["example.mp4"], ["-res", "700,380", "-b", "darkgreen"])
|
375
|
-
cn =
|
374
|
+
cn = fileinfo(out)
|
376
375
|
|
377
376
|
assert cn.videos[0].fps == 30
|
378
377
|
assert cn.videos[0].width == 700
|
@@ -416,7 +415,7 @@ def main(sys_args: list[str] | None = None):
|
|
416
415
|
["--edit", "audio:stream=1"],
|
417
416
|
"out.mov",
|
418
417
|
)
|
419
|
-
assert len(
|
418
|
+
assert len(fileinfo(out).audios) == 1
|
420
419
|
|
421
420
|
return out
|
422
421
|
|
@@ -427,7 +426,7 @@ def main(sys_args: list[str] | None = None):
|
|
427
426
|
|
428
427
|
def concat_mux_tracks():
|
429
428
|
out = run.main(["example.mp4", "resources/multi-track.mov"], [], "out.mov")
|
430
|
-
assert len(
|
429
|
+
assert len(fileinfo(out).audios) == 1
|
431
430
|
|
432
431
|
return out
|
433
432
|
|
@@ -437,30 +436,30 @@ def main(sys_args: list[str] | None = None):
|
|
437
436
|
["--keep-tracks-separate"],
|
438
437
|
"out.mov",
|
439
438
|
)
|
440
|
-
assert len(
|
439
|
+
assert len(fileinfo(out).audios) == 2
|
441
440
|
out = run.main(
|
442
441
|
["example.mp4", "resources/multi-track.mov"],
|
443
442
|
["--keep-tracks-separate"],
|
444
443
|
"out.mov",
|
445
444
|
)
|
446
|
-
assert len(
|
445
|
+
assert len(fileinfo(out).audios) == 2
|
447
446
|
|
448
447
|
return out
|
449
448
|
|
450
449
|
def frame_rate():
|
451
|
-
cn =
|
450
|
+
cn = fileinfo(run.main(["example.mp4"], ["-r", "15", "--no-seek"]))
|
452
451
|
video = cn.videos[0]
|
453
452
|
assert video.fps == 15
|
454
453
|
assert video.time_base == Fraction(1, 15)
|
455
454
|
assert float(video.duration) - 17.33333333333333333333333 < 3
|
456
455
|
|
457
|
-
cn =
|
456
|
+
cn = fileinfo(run.main(["example.mp4"], ["-r", "20"]))
|
458
457
|
video = cn.videos[0]
|
459
458
|
assert video.fps == 20
|
460
459
|
assert video.time_base == Fraction(1, 20)
|
461
460
|
assert float(video.duration) - 17.33333333333333333333333 < 2
|
462
461
|
|
463
|
-
cn =
|
462
|
+
cn = fileinfo(out := run.main(["example.mp4"], ["-r", "60"]))
|
464
463
|
video = cn.videos[0]
|
465
464
|
|
466
465
|
assert video.fps == 60
|
@@ -471,22 +470,22 @@ def main(sys_args: list[str] | None = None):
|
|
471
470
|
|
472
471
|
def embedded_image():
|
473
472
|
out1 = run.main(["resources/embedded-image/h264-png.mp4"], [])
|
474
|
-
cn =
|
473
|
+
cn = fileinfo(out1)
|
475
474
|
assert cn.videos[0].codec == "h264"
|
476
475
|
assert cn.videos[1].codec == "png"
|
477
476
|
|
478
477
|
out2 = run.main(["resources/embedded-image/h264-mjpeg.mp4"], [])
|
479
|
-
cn =
|
478
|
+
cn = fileinfo(out2)
|
480
479
|
assert cn.videos[0].codec == "h264"
|
481
480
|
assert cn.videos[1].codec == "mjpeg"
|
482
481
|
|
483
482
|
out3 = run.main(["resources/embedded-image/h264-png.mkv"], [])
|
484
|
-
cn =
|
483
|
+
cn = fileinfo(out3)
|
485
484
|
assert cn.videos[0].codec == "h264"
|
486
485
|
assert cn.videos[1].codec == "png"
|
487
486
|
|
488
487
|
out4 = run.main(["resources/embedded-image/h264-mjpeg.mkv"], [])
|
489
|
-
cn =
|
488
|
+
cn = fileinfo(out4)
|
490
489
|
assert cn.videos[0].codec == "h264"
|
491
490
|
assert cn.videos[1].codec == "mjpeg"
|
492
491
|
|
@@ -532,7 +531,7 @@ def main(sys_args: list[str] | None = None):
|
|
532
531
|
# Issue 280
|
533
532
|
def SAR():
|
534
533
|
out = run.main(["resources/SAR-2by3.mp4"], [])
|
535
|
-
assert
|
534
|
+
assert fileinfo(out).videos[0].sar == Fraction(2, 3)
|
536
535
|
|
537
536
|
return out
|
538
537
|
|
@@ -628,11 +627,11 @@ def main(sys_args: list[str] | None = None):
|
|
628
627
|
("(string #\\a #\\b)", "ab"),
|
629
628
|
("(string #\\a #\\b #\\c)", "abc"),
|
630
629
|
(
|
631
|
-
"(margin
|
630
|
+
"(margin (bool-array 0 0 0 1 0 0 0) 0)",
|
632
631
|
np.array([0, 0, 0, 1, 0, 0, 0], dtype=np.bool_),
|
633
632
|
),
|
634
633
|
(
|
635
|
-
"(margin
|
634
|
+
"(margin (bool-array 0 0 1 1 0 0 0) -2 2)",
|
636
635
|
np.array([0, 0, 0, 0, 1, 1, 0], dtype=np.bool_),
|
637
636
|
),
|
638
637
|
("(equal? 3 3)", True),
|
auto_editor/timeline.py
CHANGED
@@ -1,21 +1,19 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from collections.abc import Iterator
|
4
3
|
from dataclasses import dataclass
|
5
|
-
from
|
6
|
-
from typing import Any
|
4
|
+
from typing import TYPE_CHECKING
|
7
5
|
|
8
|
-
from auto_editor.ffwrapper import FileInfo
|
9
6
|
from auto_editor.lib.contracts import *
|
10
|
-
from auto_editor.utils.chunks import Chunks
|
11
7
|
from auto_editor.utils.cmdkw import Required, pAttr, pAttrs
|
12
|
-
from auto_editor.utils.types import
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
from auto_editor.utils.types import anchor, color, natural, number, threshold
|
9
|
+
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from collections.abc import Iterator
|
12
|
+
from fractions import Fraction
|
13
|
+
from typing import Any
|
14
|
+
|
15
|
+
from auto_editor.ffwrapper import FileInfo
|
16
|
+
from auto_editor.utils.chunks import Chunks
|
19
17
|
|
20
18
|
|
21
19
|
@dataclass(slots=True)
|
auto_editor/utils/container.py
CHANGED
@@ -83,6 +83,10 @@ def container_constructor(ext: str) -> Container:
|
|
83
83
|
vcodecs.add(codec)
|
84
84
|
if codec == "h264":
|
85
85
|
vcodecs.add("libx264")
|
86
|
+
if codec == "av1":
|
87
|
+
vcodecs.add("libsvtav1")
|
88
|
+
if codec == "hevc":
|
89
|
+
vcodecs.add("hevc_nvenc")
|
86
90
|
if kind == "audio":
|
87
91
|
acodecs.add(codec)
|
88
92
|
if kind == "subtitle":
|
auto_editor/utils/func.py
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from
|
4
|
-
from fractions import Fraction
|
3
|
+
from typing import TYPE_CHECKING
|
5
4
|
|
6
5
|
import numpy as np
|
7
|
-
from numpy.typing import NDArray
|
8
6
|
|
9
|
-
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from collections.abc import Callable
|
9
|
+
from fractions import Fraction
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
from numpy.typing import NDArray
|
12
|
+
|
13
|
+
from auto_editor.utils.log import Log
|
14
|
+
|
15
|
+
BoolList = NDArray[np.bool_]
|
16
|
+
BoolOperand = Callable[[BoolList, BoolList], BoolList]
|
13
17
|
|
14
18
|
|
15
19
|
def boolop(a: BoolList, b: BoolList, call: BoolOperand) -> BoolList:
|
@@ -25,26 +29,6 @@ def boolop(a: BoolList, b: BoolList, call: BoolOperand) -> BoolList:
|
|
25
29
|
return call(a, b)
|
26
30
|
|
27
31
|
|
28
|
-
def setup_tempdir(temp: str | None, log: Log) -> str:
|
29
|
-
if temp is None:
|
30
|
-
import tempfile
|
31
|
-
|
32
|
-
return tempfile.mkdtemp()
|
33
|
-
|
34
|
-
import os.path
|
35
|
-
from os import listdir, mkdir
|
36
|
-
|
37
|
-
if os.path.isfile(temp):
|
38
|
-
log.error("Temp directory cannot be an already existing file.")
|
39
|
-
if os.path.isdir(temp):
|
40
|
-
if len(listdir(temp)) != 0:
|
41
|
-
log.error("Temp directory should be empty!")
|
42
|
-
else:
|
43
|
-
mkdir(temp)
|
44
|
-
|
45
|
-
return temp
|
46
|
-
|
47
|
-
|
48
32
|
def to_timecode(secs: float | Fraction, fmt: str) -> str:
|
49
33
|
sign = ""
|
50
34
|
if secs < 0:
|
auto_editor/utils/log.py
CHANGED
@@ -3,45 +3,72 @@ from __future__ import annotations
|
|
3
3
|
import sys
|
4
4
|
from datetime import timedelta
|
5
5
|
from shutil import get_terminal_size, rmtree
|
6
|
+
from tempfile import mkdtemp
|
6
7
|
from time import perf_counter, sleep
|
7
8
|
from typing import NoReturn
|
8
9
|
|
9
10
|
|
10
11
|
class Log:
|
11
|
-
__slots__ = ("is_debug", "quiet", "
|
12
|
+
__slots__ = ("is_debug", "quiet", "machine", "no_color", "_temp", "_ut", "_s")
|
12
13
|
|
13
14
|
def __init__(
|
14
15
|
self,
|
15
16
|
is_debug: bool = False,
|
16
17
|
quiet: bool = False,
|
17
|
-
|
18
|
+
temp_dir: str | None = None,
|
18
19
|
machine: bool = False,
|
19
20
|
no_color: bool = True,
|
20
21
|
):
|
21
22
|
self.is_debug = is_debug
|
22
23
|
self.quiet = quiet
|
23
|
-
self.temp = temp
|
24
24
|
self.machine = machine
|
25
25
|
self.no_color = no_color
|
26
|
-
self.
|
26
|
+
self._temp: str | None = None
|
27
|
+
self._ut = temp_dir
|
28
|
+
self._s = 0 if self.quiet or self.machine else perf_counter()
|
27
29
|
|
28
30
|
def debug(self, message: object) -> None:
|
29
31
|
if self.is_debug:
|
30
32
|
self.conwrite("")
|
31
33
|
sys.stderr.write(f"Debug: {message}\n")
|
32
34
|
|
35
|
+
@property
|
36
|
+
def temp(self) -> str:
|
37
|
+
if self._temp is not None:
|
38
|
+
return self._temp
|
39
|
+
|
40
|
+
if self._ut is None:
|
41
|
+
result = mkdtemp()
|
42
|
+
else:
|
43
|
+
import os.path
|
44
|
+
from os import listdir, mkdir
|
45
|
+
|
46
|
+
if os.path.isfile(self._ut):
|
47
|
+
self.error("Temp directory cannot be an already existing file.")
|
48
|
+
|
49
|
+
if os.path.isdir(self._ut):
|
50
|
+
if len(listdir(self._ut)) != 0:
|
51
|
+
self.error("Temp directory should be empty!")
|
52
|
+
else:
|
53
|
+
mkdir(self._ut)
|
54
|
+
result = self._ut
|
55
|
+
|
56
|
+
self.debug(f"Temp Directory: {result}")
|
57
|
+
self._temp = result
|
58
|
+
return result
|
59
|
+
|
33
60
|
def cleanup(self) -> None:
|
34
|
-
if self.
|
61
|
+
if self._temp is None:
|
35
62
|
return
|
36
63
|
try:
|
37
|
-
rmtree(self.
|
64
|
+
rmtree(self._temp)
|
38
65
|
self.debug("Removed Temp Directory.")
|
39
66
|
except FileNotFoundError:
|
40
67
|
pass
|
41
68
|
except PermissionError:
|
42
69
|
sleep(0.1)
|
43
70
|
try:
|
44
|
-
rmtree(self.
|
71
|
+
rmtree(self._temp)
|
45
72
|
self.debug("Removed Temp Directory.")
|
46
73
|
except Exception as e:
|
47
74
|
self.debug(f"Failed to delete temp dir:\n{e}")
|
@@ -65,7 +92,7 @@ class Log:
|
|
65
92
|
|
66
93
|
def stop_timer(self) -> None:
|
67
94
|
if not self.quiet and not self.machine:
|
68
|
-
second_len = round(perf_counter() - self.
|
95
|
+
second_len = round(perf_counter() - self._s, 2)
|
69
96
|
minute_len = timedelta(seconds=round(second_len))
|
70
97
|
|
71
98
|
sys.stdout.write(f"Finished. took {second_len} seconds ({minute_len})\n")
|
auto_editor/utils/types.py
CHANGED
@@ -217,7 +217,7 @@ def resolution(val: str | None) -> tuple[int, int] | None:
|
|
217
217
|
return natural(vals[0]), natural(vals[1])
|
218
218
|
|
219
219
|
|
220
|
-
@dataclass
|
220
|
+
@dataclass(slots=True)
|
221
221
|
class Args:
|
222
222
|
yt_dlp_location: str = "yt-dlp"
|
223
223
|
download_format: str | None = None
|
@@ -255,6 +255,7 @@ class Args:
|
|
255
255
|
show_ffmpeg_output: bool = False
|
256
256
|
quiet: bool = False
|
257
257
|
preview: bool = False
|
258
|
+
no_cache: bool = False
|
258
259
|
margin: tuple[str, str] = ("0.2s", "0.2s")
|
259
260
|
silent_speed: float = 99999.0
|
260
261
|
video_speed: float = 1.0
|
auto_editor/vanparse.py
CHANGED
@@ -4,7 +4,6 @@ import difflib
|
|
4
4
|
import re
|
5
5
|
import sys
|
6
6
|
import textwrap
|
7
|
-
from collections.abc import Iterator
|
8
7
|
from dataclasses import dataclass
|
9
8
|
from io import StringIO
|
10
9
|
from shutil import get_terminal_size
|
@@ -14,7 +13,7 @@ from auto_editor.utils.log import Log
|
|
14
13
|
from auto_editor.utils.types import CoerceError
|
15
14
|
|
16
15
|
if TYPE_CHECKING:
|
17
|
-
from collections.abc import Callable
|
16
|
+
from collections.abc import Callable, Iterator
|
18
17
|
from typing import Any, Literal, TypeVar
|
19
18
|
|
20
19
|
T = TypeVar("T")
|
@@ -0,0 +1,55 @@
|
|
1
|
+
auto_editor/__init__.py,sha256=hNpKYQArhnrmhf1u3TNPTwtZw8XS7EeDs-TfBLusM-s,23
|
2
|
+
auto_editor/__main__.py,sha256=89pW_zaFB8WEyKTGadkALLuv_MFONIcfEu8t0jKqeWI,9774
|
3
|
+
auto_editor/analyze.py,sha256=pHoSZ_-wyV1hLJyJpPg9Ha7oecjdGHGJ0a4hbKnb9NY,11779
|
4
|
+
auto_editor/edit.py,sha256=ihyCi9YyIV-WYP81pOnc5jG8n-e8m5aMogg27XVxPVY,11268
|
5
|
+
auto_editor/ffwrapper.py,sha256=RU74pfZUMEIVdpvZVVoJt92AILBGkYaPLZbI94Y0i60,7832
|
6
|
+
auto_editor/help.py,sha256=BFiP7vBz42TUzum4-zaQIrV1OY7kHeN0pe0MPE0T5xw,7997
|
7
|
+
auto_editor/make_layers.py,sha256=ybTxPRD6bDbEX-7e9qu4OYUvYkrdNb4BjnN9hzwkRiQ,8496
|
8
|
+
auto_editor/output.py,sha256=D8NCJwwmcjDf5rvoBnWKu5XY7QtxF3thxbnTxKAxGu8,8043
|
9
|
+
auto_editor/preview.py,sha256=noWkgyzdE14zwG8ZDYxLDual5iVt6zYTt4HTe-QAgFY,3029
|
10
|
+
auto_editor/timeline.py,sha256=d9Qhup2pBwsj7j9kF-Iw22xHbQvGx-keDq2eLI11Mt4,7117
|
11
|
+
auto_editor/validate_input.py,sha256=JQt7J5xOBJDp6lnd2sQptpYhf7Z_hyxNEzLsE9E7LKU,2596
|
12
|
+
auto_editor/vanparse.py,sha256=f0vViZ-aYtDxEyVrFHJ5X2pPTQAfqtw3N2gZgzn51kU,10002
|
13
|
+
auto_editor/wavfile.py,sha256=7N2LX_WfFVRnoXrKveLvuyTYpIz2htpGqfCD8tR4kJ8,9168
|
14
|
+
auto_editor/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
+
auto_editor/formats/fcp11.py,sha256=VwJWJs1qNDIVC8-pswipmKCk0e4V3LnE5fAMA0pPWVg,5857
|
16
|
+
auto_editor/formats/fcp7.py,sha256=fH86sxhlUysWisjvlqzZJgDrRpj3dSzFG-Eho2sehdc,17610
|
17
|
+
auto_editor/formats/json.py,sha256=Br-xHVHj59C0OPP2FwfJeht_fImepRXsaw0iDFvK7-w,7693
|
18
|
+
auto_editor/formats/shotcut.py,sha256=-ES854LLFCMCBe100JRJedDmuk8zPev17aQMTrzPv-g,4923
|
19
|
+
auto_editor/formats/utils.py,sha256=GIZw28WHuCIaZ_zMI0v6Kxbq0QaIpbLsdSegdYwQxQ8,1990
|
20
|
+
auto_editor/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
+
auto_editor/lang/json.py,sha256=OsNcYlfEj8ZLlzLK-gkLcrCCKI7mJz9rpe-6XLr4f9U,9231
|
22
|
+
auto_editor/lang/libmath.py,sha256=z33A161Oe6vYYK7R6pgYjdZZe63dQkN38Qf36TL3prg,847
|
23
|
+
auto_editor/lang/palet.py,sha256=m22TQnKomUM2quxIH4bz7ya_gM166rbJ5pW7Ei-43IA,59712
|
24
|
+
auto_editor/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
+
auto_editor/lib/contracts.py,sha256=a3ZT-bGMa3-UjWKKFrEwLayw2Gl-rhqd5Bmvmrj85oE,7413
|
26
|
+
auto_editor/lib/data_structs.py,sha256=xyB6aEcpdB9NNWp_dU3d2ds5Z8zOfHXNX4mNQLh2pNw,6977
|
27
|
+
auto_editor/lib/err.py,sha256=UlszQJdzMZwkbT8x3sY4GkCV_5x9yrd6uVVUzvA8iiI,35
|
28
|
+
auto_editor/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
|
+
auto_editor/render/audio.py,sha256=darKvlglNXkknSUaPnH-qEUyccM1Awnv03_Px4yY81I,8844
|
30
|
+
auto_editor/render/subtitle.py,sha256=g195kDN0LcwKlZeQMCflXPH5n_74iwCk1RPLSQ5eP34,4373
|
31
|
+
auto_editor/render/video.py,sha256=gMVcLehC_QpdtIzNLR_7tv2CZmYeEWisS_5as4ceHV0,12971
|
32
|
+
auto_editor/subcommands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
|
+
auto_editor/subcommands/desc.py,sha256=GDrKJYiHMaeTrplZAceXl1JwoqD78XsV2_5lc0Xd7po,869
|
34
|
+
auto_editor/subcommands/info.py,sha256=7Sgt9WR0rWxe7juCRKseMxW6gKv3z3voqFcL8-MOVVM,6927
|
35
|
+
auto_editor/subcommands/levels.py,sha256=ZB8_9jbOA5s1AQUcUNZDiLAjyJOKl7Be2YeVWdkOr0Q,4071
|
36
|
+
auto_editor/subcommands/palet.py,sha256=tbQoRWoT4jR3yu0etGApfprM-oQgXIjC-rIY-QG3nM0,655
|
37
|
+
auto_editor/subcommands/repl.py,sha256=OfxIOBjE7W12UemfaaxMnzHcmV5cUTt7g5328R7rAYU,3116
|
38
|
+
auto_editor/subcommands/subdump.py,sha256=af_XBf7kaevqHn1A71z8C-7x8pS5WKD9FE_ugkCw6rk,665
|
39
|
+
auto_editor/subcommands/test.py,sha256=Qg_zY1Cg8Mo7JXsUWFEJxJZAe5pkkXyK4ydnBVpG0I8,24992
|
40
|
+
auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
|
+
auto_editor/utils/bar.py,sha256=RJqkJ8gNr8op_Z-2hh48ExjSonmTPX-RshctK_itv14,3988
|
42
|
+
auto_editor/utils/chunks.py,sha256=J-eGKtEz68gFtRrj1kOSgH4Tj_Yz6prNQ7Xr-d9NQJw,52
|
43
|
+
auto_editor/utils/cmdkw.py,sha256=XApxw7FZBOEJV9N4LHhdw1GVfHbFfCjr-zCZ1gJsSvY,6002
|
44
|
+
auto_editor/utils/container.py,sha256=qSoS5d8JqLRH4_BIWfnJ-37eCKKe_J290yrUNULGT94,2643
|
45
|
+
auto_editor/utils/encoder.py,sha256=auNYo7HXbcU4iTUCc0LE5lpwFmSvdWvBm6-5KIaRK8w,2983
|
46
|
+
auto_editor/utils/func.py,sha256=kcxCOqe-tg6k-kxutIran8LpffRiHDjKB6rm-ngFiSU,4460
|
47
|
+
auto_editor/utils/log.py,sha256=M2QKeQHMRNLm3HMVUKedZPRprT2u5dipOStiO4miPBk,3613
|
48
|
+
auto_editor/utils/subtitle_tools.py,sha256=TjjVPiT8bWzZJcrZjF7ddpgfIsVkLE4LyxXzBswHAGU,693
|
49
|
+
auto_editor/utils/types.py,sha256=JdAwfuT9Ty_FXUm89GUTo0M8FPFrXbqnlk-g4pWP1_k,11609
|
50
|
+
auto_editor-25.0.0.dist-info/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
|
51
|
+
auto_editor-25.0.0.dist-info/METADATA,sha256=ucOoacVK0LCr-DKicxIkO9w6Zx2LWvlfMPgBiXucYkk,6137
|
52
|
+
auto_editor-25.0.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
53
|
+
auto_editor-25.0.0.dist-info/entry_points.txt,sha256=-H7zdTw4MqnAcwrN5xTNkGIhzZtJMxS9r6lTMeR9-aA,240
|
54
|
+
auto_editor-25.0.0.dist-info/top_level.txt,sha256=ky1HUkqq9i034c4CUU_0wBw0xZsxxyGEak1eTbdvpyA,12
|
55
|
+
auto_editor-25.0.0.dist-info/RECORD,,
|