auto-editor 26.2.0__py3-none-any.whl → 26.3.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 -1
- auto_editor/cmds/test.py +10 -0
- auto_editor/edit.py +25 -3
- auto_editor/ffwrapper.py +1 -2
- auto_editor/lang/stdenv.py +1 -1
- auto_editor/render/video.py +8 -36
- auto_editor/utils/bar.py +1 -1
- {auto_editor-26.2.0.dist-info → auto_editor-26.3.0.dist-info}/METADATA +2 -2
- {auto_editor-26.2.0.dist-info → auto_editor-26.3.0.dist-info}/RECORD +13 -13
- {auto_editor-26.2.0.dist-info → auto_editor-26.3.0.dist-info}/LICENSE +0 -0
- {auto_editor-26.2.0.dist-info → auto_editor-26.3.0.dist-info}/WHEEL +0 -0
- {auto_editor-26.2.0.dist-info → auto_editor-26.3.0.dist-info}/entry_points.txt +0 -0
- {auto_editor-26.2.0.dist-info → auto_editor-26.3.0.dist-info}/top_level.txt +0 -0
auto_editor/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "26.
|
1
|
+
__version__ = "26.3.0"
|
auto_editor/cmds/test.py
CHANGED
@@ -549,6 +549,15 @@ def main(sys_args: list[str] | None = None):
|
|
549
549
|
def yuv442p():
|
550
550
|
return run.main(["resources/test_yuv422p.mp4"], [])
|
551
551
|
|
552
|
+
def prores():
|
553
|
+
run.main(["resources/testsrc.mp4", "-c:v", "prores", "-o", "out.mkv"], [])
|
554
|
+
assert fileinfo("out.mkv").videos[0].pix_fmt == "yuv422p10le"
|
555
|
+
|
556
|
+
run.main(["out.mkv", "-c:v", "prores", "-o", "out2.mkv"], [])
|
557
|
+
assert fileinfo("out2.mkv").videos[0].pix_fmt == "yuv422p10le"
|
558
|
+
|
559
|
+
return "out.mkv", "out2.mkv"
|
560
|
+
|
552
561
|
# Issue 280
|
553
562
|
def SAR():
|
554
563
|
out = run.main(["resources/SAR-2by3.mp4"], [])
|
@@ -735,6 +744,7 @@ def main(sys_args: list[str] | None = None):
|
|
735
744
|
premiere,
|
736
745
|
SAR,
|
737
746
|
yuv442p,
|
747
|
+
prores,
|
738
748
|
edit_negative_tests,
|
739
749
|
edit_positive_tests,
|
740
750
|
audio_norm_f,
|
auto_editor/edit.py
CHANGED
@@ -365,17 +365,35 @@ def edit_media(paths: list[str], args: Args, log: Log) -> None:
|
|
365
365
|
|
366
366
|
# Setup video
|
367
367
|
if ctr.default_vid != "none" and tl.v:
|
368
|
-
vframes = render_av(output, tl, args,
|
368
|
+
vframes = render_av(output, tl, args, log)
|
369
369
|
output_stream = next(vframes)
|
370
370
|
else:
|
371
371
|
output_stream, vframes = None, iter([])
|
372
372
|
|
373
|
+
no_color = log.no_color or log.machine
|
374
|
+
encoder_titles = []
|
375
|
+
if output_stream is not None:
|
376
|
+
name = output_stream.codec.canonical_name
|
377
|
+
encoder_titles.append(name if no_color else f"\033[95m{name}")
|
378
|
+
if audio_streams:
|
379
|
+
name = audio_streams[0].name
|
380
|
+
encoder_titles.append(name if no_color else f"\033[96m{name}")
|
381
|
+
if subtitle_streams:
|
382
|
+
name = subtitle_streams[0].name
|
383
|
+
encoder_titles.append(name if no_color else f"\033[32m{name}")
|
384
|
+
|
385
|
+
title = f"({os.path.splitext(output_path)[1][1:]}) "
|
386
|
+
if no_color:
|
387
|
+
title += "+".join(encoder_titles)
|
388
|
+
else:
|
389
|
+
title += "\033[0m+".join(encoder_titles) + "\033[0m"
|
390
|
+
bar.start(tl.end, title)
|
391
|
+
|
373
392
|
# Process frames
|
374
393
|
while True:
|
375
394
|
audio_frames = [next(frames, None) for frames in audio_gen_frames]
|
376
|
-
video_frame = next(vframes, None)
|
395
|
+
index, video_frame = next(vframes, (0, None))
|
377
396
|
subtitle_frames = [next(packet, None) for packet in sub_gen_frames]
|
378
|
-
|
379
397
|
if (
|
380
398
|
all(frame is None for frame in audio_frames)
|
381
399
|
and video_frame is None
|
@@ -405,12 +423,16 @@ def edit_media(paths: list[str], args: Args, log: Log) -> None:
|
|
405
423
|
except av.FFmpegError as e:
|
406
424
|
log.error(e)
|
407
425
|
|
426
|
+
bar.tick(index)
|
427
|
+
|
408
428
|
# Flush streams
|
409
429
|
if output_stream is not None:
|
410
430
|
output.mux(output_stream.encode(None))
|
411
431
|
for audio_stream in audio_streams:
|
412
432
|
output.mux(audio_stream.encode(None))
|
413
433
|
|
434
|
+
bar.end()
|
435
|
+
|
414
436
|
# Close resources
|
415
437
|
for audio_input in audio_inputs:
|
416
438
|
audio_input.close()
|
auto_editor/ffwrapper.py
CHANGED
@@ -147,10 +147,9 @@ def initFileInfo(path: str, log: Log) -> FileInfo:
|
|
147
147
|
adur = float(a.duration * a.time_base)
|
148
148
|
|
149
149
|
a_cc = a.codec_context
|
150
|
-
name = a_cc.name if a_cc.name != "mp3float" else "mp3"
|
151
150
|
audios += (
|
152
151
|
AudioStream(
|
153
|
-
|
152
|
+
a_cc.codec.canonical_name,
|
154
153
|
0 if a_cc.sample_rate is None else a_cc.sample_rate,
|
155
154
|
a.layout.name,
|
156
155
|
a_cc.channels,
|
auto_editor/lang/stdenv.py
CHANGED
@@ -1045,7 +1045,7 @@ def make_standard_env() -> dict[str, Any]:
|
|
1045
1045
|
# reals
|
1046
1046
|
"pow": Proc("pow", pow, (2, 2), is_real),
|
1047
1047
|
"abs": Proc("abs", abs, (1, 1), is_real),
|
1048
|
-
"round": Proc("round", round, (1,
|
1048
|
+
"round": Proc("round", round, (1, 2), is_real, is_int),
|
1049
1049
|
"max": Proc("max", lambda *v: max(v), (1, None), is_real),
|
1050
1050
|
"min": Proc("min", lambda *v: min(v), (1, None), is_real),
|
1051
1051
|
"max-seq": Proc("max-seq", max, (1, 1), is_sequence),
|
auto_editor/render/video.py
CHANGED
@@ -15,7 +15,6 @@ if TYPE_CHECKING:
|
|
15
15
|
|
16
16
|
from auto_editor.ffwrapper import FileInfo
|
17
17
|
from auto_editor.timeline import v3
|
18
|
-
from auto_editor.utils.bar import Bar
|
19
18
|
from auto_editor.utils.log import Log
|
20
19
|
from auto_editor.utils.types import Args
|
21
20
|
|
@@ -26,35 +25,12 @@ class VideoFrame:
|
|
26
25
|
src: FileInfo
|
27
26
|
|
28
27
|
|
29
|
-
|
30
|
-
allowed_pix_fmt = {
|
31
|
-
"yuv420p",
|
32
|
-
"yuvj420p",
|
33
|
-
"yuv444p",
|
34
|
-
"yuvj444p",
|
35
|
-
"rgb48be",
|
36
|
-
"rgb48le",
|
37
|
-
"rgb64be",
|
38
|
-
"rgb64le",
|
39
|
-
"rgb24",
|
40
|
-
"bgr24",
|
41
|
-
"argb",
|
42
|
-
"rgba",
|
43
|
-
"abgr",
|
44
|
-
"bgra",
|
45
|
-
"gray",
|
46
|
-
"gray8",
|
47
|
-
"gray16be",
|
48
|
-
"gray16le",
|
49
|
-
"rgb8",
|
50
|
-
"bgr8",
|
51
|
-
"pal8",
|
52
|
-
}
|
28
|
+
allowed_pix_fmt = av.video.frame.supported_np_pix_fmts
|
53
29
|
|
54
30
|
|
55
31
|
def make_solid(width: int, height: int, pix_fmt: str, bg: str) -> av.VideoFrame:
|
56
32
|
hex_color = bg.lstrip("#").upper()
|
57
|
-
rgb_color = tuple(int(hex_color[i : i + 2], 16) for i in
|
33
|
+
rgb_color = tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
|
58
34
|
|
59
35
|
rgb_array = np.full((height, width, 3), rgb_color, dtype=np.uint8)
|
60
36
|
rgb_frame = av.VideoFrame.from_ndarray(rgb_array, format="rgb24")
|
@@ -65,7 +41,7 @@ def make_image_cache(tl: v3) -> dict[tuple[FileInfo, int], np.ndarray]:
|
|
65
41
|
img_cache = {}
|
66
42
|
for clip in tl.v:
|
67
43
|
for obj in clip:
|
68
|
-
if isinstance(obj, TlImage) and obj.src not in img_cache:
|
44
|
+
if isinstance(obj, TlImage) and (obj.src, obj.width) not in img_cache:
|
69
45
|
with av.open(obj.src.path) as cn:
|
70
46
|
my_stream = cn.streams.video[0]
|
71
47
|
for frame in cn.decode(my_stream):
|
@@ -85,7 +61,7 @@ def make_image_cache(tl: v3) -> dict[tuple[FileInfo, int], np.ndarray]:
|
|
85
61
|
|
86
62
|
|
87
63
|
def render_av(
|
88
|
-
output: av.container.OutputContainer, tl: v3, args: Args,
|
64
|
+
output: av.container.OutputContainer, tl: v3, args: Args, log: Log
|
89
65
|
) -> Any:
|
90
66
|
from_ndarray = av.VideoFrame.from_ndarray
|
91
67
|
|
@@ -132,13 +108,15 @@ def render_av(
|
|
132
108
|
|
133
109
|
codec = av.Codec(args.video_codec, "w")
|
134
110
|
|
135
|
-
if
|
111
|
+
if codec.canonical_name == "gif":
|
136
112
|
if codec.video_formats is not None and target_pix_fmt in (
|
137
113
|
f.name for f in codec.video_formats
|
138
114
|
):
|
139
115
|
target_pix_fmt = target_pix_fmt
|
140
116
|
else:
|
141
117
|
target_pix_fmt = "rgb8"
|
118
|
+
elif codec.canonical_name == "prores":
|
119
|
+
target_pix_fmt = "yuv422p10le"
|
142
120
|
else:
|
143
121
|
target_pix_fmt = (
|
144
122
|
target_pix_fmt if target_pix_fmt in allowed_pix_fmt else "yuv420p"
|
@@ -212,8 +190,6 @@ def render_av(
|
|
212
190
|
seek_frame = None
|
213
191
|
frames_saved = 0
|
214
192
|
|
215
|
-
bar.start(tl.end, "Creating new video")
|
216
|
-
|
217
193
|
bg = args.background
|
218
194
|
null_frame = make_solid(target_width, target_height, target_pix_fmt, bg)
|
219
195
|
frame_index = -1
|
@@ -334,11 +310,7 @@ def render_av(
|
|
334
310
|
|
335
311
|
if frame.format.name != target_pix_fmt:
|
336
312
|
frame = frame.reformat(format=target_pix_fmt)
|
337
|
-
bar.tick(index)
|
338
|
-
elif index % 3 == 0:
|
339
|
-
bar.tick(index)
|
340
313
|
|
341
|
-
yield from_ndarray(frame.to_ndarray(), format=frame.format.name)
|
314
|
+
yield (index, from_ndarray(frame.to_ndarray(), format=frame.format.name))
|
342
315
|
|
343
|
-
bar.end()
|
344
316
|
log.debug(f"Total frames saved seeking: {frames_saved}")
|
auto_editor/utils/bar.py
CHANGED
@@ -89,7 +89,7 @@ class Bar:
|
|
89
89
|
percent = round(progress * 100, 1)
|
90
90
|
p_pad = " " * (4 - len(str(percent)))
|
91
91
|
columns = get_terminal_size().columns
|
92
|
-
bar_len = max(1, columns -
|
92
|
+
bar_len = max(1, columns - len_title - 32)
|
93
93
|
bar_str = self._bar_str(progress, bar_len)
|
94
94
|
|
95
95
|
bar = f" {self.icon}{title} {bar_str} {p_pad}{percent}% ETA {new_time}"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: auto-editor
|
3
|
-
Version: 26.
|
3
|
+
Version: 26.3.0
|
4
4
|
Summary: Auto-Editor: Effort free video editing!
|
5
5
|
Author-email: WyattBlue <wyattblue@auto-editor.com>
|
6
6
|
License: Unlicense
|
@@ -12,7 +12,7 @@ Requires-Python: <3.14,>=3.10
|
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
License-File: LICENSE
|
14
14
|
Requires-Dist: numpy<3.0,>=1.24
|
15
|
-
Requires-Dist: pyav==14
|
15
|
+
Requires-Dist: pyav==14.2.0
|
16
16
|
|
17
17
|
<p align="center"><img src="https://auto-editor.com/img/auto-editor-banner.webp" title="Auto-Editor" width="700"></p>
|
18
18
|
|
@@ -1,8 +1,8 @@
|
|
1
|
-
auto_editor/__init__.py,sha256=
|
1
|
+
auto_editor/__init__.py,sha256=foFMRrw-Br8Dq0ZIes1siNTsxZj5nQywX_cfWHfB380,23
|
2
2
|
auto_editor/__main__.py,sha256=g-9q3i6oFeNPeFMeNJEwZua6ZloOPLcaLN-B0FlxWXo,11371
|
3
3
|
auto_editor/analyze.py,sha256=7p_SDRRKQzlc6wtoW6MXYvJkDV4NO4DSOtJPFAuYcwM,12721
|
4
|
-
auto_editor/edit.py,sha256=
|
5
|
-
auto_editor/ffwrapper.py,sha256=
|
4
|
+
auto_editor/edit.py,sha256=gz2MocM5s1uz-hLrFWmiNl1TwOm4S_1EkYn-ZBuu_sE,17401
|
5
|
+
auto_editor/ffwrapper.py,sha256=1lYYfq8gVgMVkYWeAEYDPAHCwFCYbKQwy0FxYBxMzk8,4765
|
6
6
|
auto_editor/help.py,sha256=CzfDTsL4GuGu596ySHKj_wKnxGR9h8B0KUdkZpo33oE,8044
|
7
7
|
auto_editor/make_layers.py,sha256=vEeJt0PnE1vc9-cQZ_AlXVDjvWhObRCWJSCQGraoMvU,9016
|
8
8
|
auto_editor/output.py,sha256=ho8Lpqz4Sv_Gw0Vj2OvG39s83xHpyZlvtRNryTPbXqc,2563
|
@@ -18,7 +18,7 @@ auto_editor/cmds/levels.py,sha256=qMxTOlj4ezna0K2jYWDFyZ0Srn4pT6nIdR-479IOEvw,57
|
|
18
18
|
auto_editor/cmds/palet.py,sha256=ONzTqemaQq9YEfIOsDRNnwzfqnEMUMSXIQrETxyroRU,749
|
19
19
|
auto_editor/cmds/repl.py,sha256=TF_I7zsFY7-KdgidrqjafTz7o_eluVbLvgTcOBG-UWQ,3449
|
20
20
|
auto_editor/cmds/subdump.py,sha256=af_XBf7kaevqHn1A71z8C-7x8pS5WKD9FE_ugkCw6rk,665
|
21
|
-
auto_editor/cmds/test.py,sha256=
|
21
|
+
auto_editor/cmds/test.py,sha256=Wih-KQnv5Ld1CgbOUdtrp_fMnINsr_khzONvlrJ-bhw,26163
|
22
22
|
auto_editor/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
auto_editor/formats/fcp11.py,sha256=sqjC36jI47ICPLjZJYiqGwY7foOnWOiNjkPFLdgSnI4,5208
|
24
24
|
auto_editor/formats/fcp7.py,sha256=x5cagTzGCAW3i3M6m7TZC1h8gLfSmX1UK-iiDuCpdfs,20289
|
@@ -30,7 +30,7 @@ auto_editor/lang/json.py,sha256=D84vwyLtX5t5xl8S4r4jFXGVkbIg1L4IcexlS_a_k6w,9231
|
|
30
30
|
auto_editor/lang/libintrospection.py,sha256=6H1rGp0wqaCud5IPaoEmzULGnYt6ec7_0h32ATcw2oY,261
|
31
31
|
auto_editor/lang/libmath.py,sha256=z33A161Oe6vYYK7R6pgYjdZZe63dQkN38Qf36TL3prg,847
|
32
32
|
auto_editor/lang/palet.py,sha256=ZOzNxLfzY8FTCYlF_mZtU2XoNzdg-eseUVkMtnWkVaI,24139
|
33
|
-
auto_editor/lang/stdenv.py,sha256=
|
33
|
+
auto_editor/lang/stdenv.py,sha256=sQyOD3bttjcieWMtTMNpE6blEZriAfHtSZHbuvC09R8,43762
|
34
34
|
auto_editor/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
35
|
auto_editor/lib/contracts.py,sha256=lExGQymcQUmwG5lC1lO4qm4GY8W0q_yzK_miTaAoPA4,7586
|
36
36
|
auto_editor/lib/data_structs.py,sha256=Hnzl5gWvo-geTU0g-lGejj6HQW3VvPv0NBEj2XoGskY,7089
|
@@ -38,9 +38,9 @@ auto_editor/lib/err.py,sha256=UlszQJdzMZwkbT8x3sY4GkCV_5x9yrd6uVVUzvA8iiI,35
|
|
38
38
|
auto_editor/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
39
|
auto_editor/render/audio.py,sha256=_GuX0WNY1YeumgBN3bWqgwVXiuhpvx7sijABxqyO2ag,12580
|
40
40
|
auto_editor/render/subtitle.py,sha256=jtNRKvgo1fpHTrAfGZqdkNeNgGgasw-K-4PwIKiWwfM,6231
|
41
|
-
auto_editor/render/video.py,sha256=
|
41
|
+
auto_editor/render/video.py,sha256=JBVl8w-hQ6zrs97iA527LPsBZ9s601SVSJs2bSMCq88,12185
|
42
42
|
auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
|
-
auto_editor/utils/bar.py,sha256=
|
43
|
+
auto_editor/utils/bar.py,sha256=0ZSfuWdBA1zySwodkb4mw5uahC6UwCk2umaGnB8A7n0,3996
|
44
44
|
auto_editor/utils/chunks.py,sha256=J-eGKtEz68gFtRrj1kOSgH4Tj_Yz6prNQ7Xr-d9NQJw,52
|
45
45
|
auto_editor/utils/cmdkw.py,sha256=aUGBvBel2Ko1o6Rwmr4rEL-BMc5hEnzYLbyZ1GeJdcY,5729
|
46
46
|
auto_editor/utils/container.py,sha256=C_Ahh7nlMEX4DNQ2M_cITPPbYcIL68r4I_AgFy0OD6o,2487
|
@@ -48,9 +48,9 @@ auto_editor/utils/func.py,sha256=C8ucgsSEzPyBc-8obhsCXd_uQW0cnCdBn1KVxB7FHjU,274
|
|
48
48
|
auto_editor/utils/log.py,sha256=8fOdyTG3vjKhA1tJTMKRjXVqhrY2q3tFnXU8tKm_twA,3937
|
49
49
|
auto_editor/utils/types.py,sha256=r5f6QB81xH7NRwGntITIOCVx-fupOl8l3X3LSFkt3nE,10756
|
50
50
|
docs/build.py,sha256=POy8X8QOBYe_8A8HI_yiVI_Qg9E5mLpn1z7AHQr0_vQ,1888
|
51
|
-
auto_editor-26.
|
52
|
-
auto_editor-26.
|
53
|
-
auto_editor-26.
|
54
|
-
auto_editor-26.
|
55
|
-
auto_editor-26.
|
56
|
-
auto_editor-26.
|
51
|
+
auto_editor-26.3.0.dist-info/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
|
52
|
+
auto_editor-26.3.0.dist-info/METADATA,sha256=YOFNFBSIMQveLah-PSIrBtlfY-xwEveHxKNAneUAs_0,6111
|
53
|
+
auto_editor-26.3.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
54
|
+
auto_editor-26.3.0.dist-info/entry_points.txt,sha256=UAsTc7qJQbnAzHd7KWg-ALo_X9Hj2yDs3M9I2DV3eyI,212
|
55
|
+
auto_editor-26.3.0.dist-info/top_level.txt,sha256=jBV5zlbWRbKOa-xaWPvTD45QL7lGExx2BDzv-Ji4dTw,17
|
56
|
+
auto_editor-26.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|