auto-editor 27.1.1__py3-none-any.whl → 28.0.1__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/__main__.py +0 -8
- auto_editor/cmds/cache.py +1 -1
- auto_editor/cmds/desc.py +8 -9
- auto_editor/cmds/info.py +4 -17
- auto_editor/cmds/palet.py +1 -1
- auto_editor/cmds/subdump.py +2 -4
- auto_editor/cmds/test.py +50 -31
- auto_editor/edit.py +52 -52
- auto_editor/{formats → exports}/fcp11.py +11 -7
- auto_editor/{formats → exports}/fcp7.py +7 -239
- auto_editor/exports/json.py +32 -0
- auto_editor/{formats → exports}/shotcut.py +8 -17
- auto_editor/ffwrapper.py +1 -3
- auto_editor/help.py +6 -17
- auto_editor/imports/__init__.py +0 -0
- auto_editor/imports/fcp7.py +275 -0
- auto_editor/{formats → imports}/json.py +16 -43
- auto_editor/json.py +2 -2
- auto_editor/lang/palet.py +6 -43
- auto_editor/lang/stdenv.py +8 -20
- auto_editor/lib/contracts.py +4 -6
- auto_editor/lib/data_structs.py +0 -3
- auto_editor/make_layers.py +13 -13
- auto_editor/preview.py +1 -2
- auto_editor/render/audio.py +9 -6
- auto_editor/render/video.py +3 -2
- auto_editor/timeline.py +35 -52
- {auto_editor-27.1.1.dist-info → auto_editor-28.0.1.dist-info}/METADATA +2 -2
- auto_editor-28.0.1.dist-info/RECORD +56 -0
- {auto_editor-27.1.1.dist-info → auto_editor-28.0.1.dist-info}/WHEEL +1 -1
- auto_editor/formats/utils.py +0 -56
- auto_editor-27.1.1.dist-info/RECORD +0 -54
- /auto_editor/{formats → exports}/__init__.py +0 -0
- {auto_editor-27.1.1.dist-info → auto_editor-28.0.1.dist-info}/entry_points.txt +0 -0
- {auto_editor-27.1.1.dist-info → auto_editor-28.0.1.dist-info}/licenses/LICENSE +0 -0
- {auto_editor-27.1.1.dist-info → auto_editor-28.0.1.dist-info}/top_level.txt +0 -0
auto_editor/make_layers.py
CHANGED
@@ -11,7 +11,7 @@ from auto_editor.ffwrapper import FileInfo
|
|
11
11
|
from auto_editor.lang.palet import Lexer, Parser, env, interpret, is_boolean_array
|
12
12
|
from auto_editor.lib.data_structs import print_str
|
13
13
|
from auto_editor.lib.err import MyError
|
14
|
-
from auto_editor.timeline import ASpace,
|
14
|
+
from auto_editor.timeline import ASpace, Clip, Template, VSpace, v1, v3
|
15
15
|
from auto_editor.utils.func import mut_margin
|
16
16
|
from auto_editor.utils.types import CoerceError, time
|
17
17
|
|
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
|
|
26
26
|
BoolList = NDArray[np.bool_]
|
27
27
|
|
28
28
|
|
29
|
-
class
|
29
|
+
class VirClip(NamedTuple):
|
30
30
|
start: int
|
31
31
|
dur: int
|
32
32
|
offset: int
|
@@ -34,8 +34,8 @@ class Clip(NamedTuple):
|
|
34
34
|
src: FileInfo
|
35
35
|
|
36
36
|
|
37
|
-
def clipify(chunks: Chunks, src: FileInfo, start: int = 0) -> list[
|
38
|
-
clips: list[
|
37
|
+
def clipify(chunks: Chunks, src: FileInfo, start: int = 0) -> list[VirClip]:
|
38
|
+
clips: list[VirClip] = []
|
39
39
|
i = 0
|
40
40
|
for chunk in chunks:
|
41
41
|
if chunk[2] > 0 and chunk[2] < 99999.0:
|
@@ -46,14 +46,14 @@ def clipify(chunks: Chunks, src: FileInfo, start: int = 0) -> list[Clip]:
|
|
46
46
|
offset = int(chunk[0] / chunk[2])
|
47
47
|
|
48
48
|
if not (clips and clips[-1].start == round(start)):
|
49
|
-
clips.append(
|
49
|
+
clips.append(VirClip(start, dur, offset, chunk[2], src))
|
50
50
|
start += dur
|
51
51
|
i += 1
|
52
52
|
|
53
53
|
return clips
|
54
54
|
|
55
55
|
|
56
|
-
def make_av(src: FileInfo, all_clips: list[list[
|
56
|
+
def make_av(src: FileInfo, all_clips: list[list[VirClip]]) -> tuple[VSpace, ASpace]:
|
57
57
|
assert type(src) is FileInfo
|
58
58
|
vtl: VSpace = []
|
59
59
|
atl: ASpace = [[] for _ in range(len(src.audios))]
|
@@ -63,11 +63,11 @@ def make_av(src: FileInfo, all_clips: list[list[Clip]]) -> tuple[VSpace, ASpace]
|
|
63
63
|
if src.videos:
|
64
64
|
if len(vtl) == 0:
|
65
65
|
vtl.append([])
|
66
|
-
vtl[0].append(
|
66
|
+
vtl[0].append(Clip(c.start, c.dur, c.src, c.offset, 0, c.speed))
|
67
67
|
|
68
68
|
for c in clips:
|
69
69
|
for a in range(len(src.audios)):
|
70
|
-
atl[a].append(
|
70
|
+
atl[a].append(Clip(c.start, c.dur, c.src, c.offset, a, c.speed))
|
71
71
|
|
72
72
|
return vtl, atl
|
73
73
|
|
@@ -139,7 +139,7 @@ def make_timeline(
|
|
139
139
|
interpret(env, parser)
|
140
140
|
|
141
141
|
results = []
|
142
|
-
for
|
142
|
+
for src in sources:
|
143
143
|
try:
|
144
144
|
parser = Parser(Lexer("`--edit`", args.edit))
|
145
145
|
if log.is_debug:
|
@@ -247,7 +247,7 @@ def make_timeline(
|
|
247
247
|
check_monotonic = len(sources) == 1
|
248
248
|
last_i = 0
|
249
249
|
|
250
|
-
clips: list[
|
250
|
+
clips: list[VirClip] = []
|
251
251
|
start = 0
|
252
252
|
|
253
253
|
for chunk in echunk(speed_index, src_index):
|
@@ -265,7 +265,7 @@ def make_timeline(
|
|
265
265
|
raise ValueError("not monotonic", sources, this_i, last_i)
|
266
266
|
last_i = this_i
|
267
267
|
|
268
|
-
clips.append(
|
268
|
+
clips.append(VirClip(start, dur, offset, chunk[3], chunk[0]))
|
269
269
|
|
270
270
|
start += dur
|
271
271
|
|
@@ -275,13 +275,13 @@ def make_timeline(
|
|
275
275
|
if c.src.videos:
|
276
276
|
if len(vtl) == 0:
|
277
277
|
vtl.append([])
|
278
|
-
vtl[0].append(
|
278
|
+
vtl[0].append(Clip(c.start, c.dur, c.src, c.offset, 0, c.speed))
|
279
279
|
|
280
280
|
for c in clips:
|
281
281
|
for a in range(len(c.src.audios)):
|
282
282
|
if a >= len(atl):
|
283
283
|
atl.append([])
|
284
|
-
atl[a].append(
|
284
|
+
atl[a].append(Clip(c.start, c.dur, c.src, c.offset, a, c.speed))
|
285
285
|
|
286
286
|
# Turn long silent/loud array to formatted chunk list.
|
287
287
|
# Example: [1, 1, 1, 2, 2], {1: 1.0, 2: 1.5} => [(0, 3, 1.0), (3, 5, 1.5)]
|
auto_editor/preview.py
CHANGED
auto_editor/render/audio.py
CHANGED
@@ -15,7 +15,7 @@ from auto_editor.json import load
|
|
15
15
|
from auto_editor.lang.palet import env
|
16
16
|
from auto_editor.lib.contracts import andc, between_c, is_int_or_float
|
17
17
|
from auto_editor.lib.err import MyError
|
18
|
-
from auto_editor.timeline import
|
18
|
+
from auto_editor.timeline import Clip, v3
|
19
19
|
from auto_editor.utils.cmdkw import ParserError, parse_with_palet, pAttr, pAttrs
|
20
20
|
from auto_editor.utils.func import parse_bitrate
|
21
21
|
from auto_editor.utils.log import Log
|
@@ -155,7 +155,7 @@ def apply_audio_normalization(
|
|
155
155
|
output_file.close()
|
156
156
|
|
157
157
|
|
158
|
-
def process_audio_clip(clip:
|
158
|
+
def process_audio_clip(clip: Clip, data: np.ndarray, sr: int, log: Log) -> np.ndarray:
|
159
159
|
to_s16 = bv.AudioResampler(format="s16", layout="stereo", rate=sr)
|
160
160
|
input_buffer = BytesIO()
|
161
161
|
|
@@ -217,6 +217,9 @@ def process_audio_clip(clip: TlAudio, data: np.ndarray, sr: int) -> np.ndarray:
|
|
217
217
|
except (bv.BlockingIOError, bv.EOFError):
|
218
218
|
break
|
219
219
|
|
220
|
+
if not all_frames:
|
221
|
+
log.debug(f"No audio frames at {clip=}")
|
222
|
+
return np.zeros_like(data)
|
220
223
|
return np.concatenate(all_frames, axis=1)
|
221
224
|
|
222
225
|
|
@@ -272,7 +275,7 @@ def mix_audio_files(sr: int, audio_paths: list[str], output_path: str) -> None:
|
|
272
275
|
max_val = np.max(np.abs(mixed_audio))
|
273
276
|
if max_val > 0:
|
274
277
|
mixed_audio = mixed_audio * (32767 / max_val)
|
275
|
-
mixed_audio = mixed_audio.astype(np.int16)
|
278
|
+
mixed_audio = mixed_audio.astype(np.int16)
|
276
279
|
|
277
280
|
output_container = bv.open(output_path, mode="w")
|
278
281
|
output_stream = output_container.add_stream("pcm_s16le", rate=sr)
|
@@ -383,7 +386,7 @@ class Getter:
|
|
383
386
|
|
384
387
|
def __init__(self, path: Path, stream: int, rate: int):
|
385
388
|
self.container = bv.open(path)
|
386
|
-
self.stream = self.container.streams.audio[
|
389
|
+
self.stream = self.container.streams.audio[stream]
|
387
390
|
self.rate = rate
|
388
391
|
|
389
392
|
def get(self, start: int, end: int) -> np.ndarray:
|
@@ -454,7 +457,7 @@ def _make_new_audio(tl: v3, fmt: bv.AudioFormat, args: Args, log: Log) -> list[A
|
|
454
457
|
arr: np.ndarray | None = None
|
455
458
|
use_iter = False
|
456
459
|
|
457
|
-
for
|
460
|
+
for clip in layer:
|
458
461
|
if (clip.src, clip.stream) not in samples:
|
459
462
|
samples[(clip.src, clip.stream)] = Getter(
|
460
463
|
clip.src.path, clip.stream, sr
|
@@ -473,7 +476,7 @@ def _make_new_audio(tl: v3, fmt: bv.AudioFormat, args: Args, log: Log) -> list[A
|
|
473
476
|
|
474
477
|
if clip.speed != 1 or clip.volume != 1:
|
475
478
|
clip_arr = process_audio_clip(
|
476
|
-
clip, getter.get(samp_start, samp_end), sr
|
479
|
+
clip, getter.get(samp_start, samp_end), sr, log
|
477
480
|
)
|
478
481
|
else:
|
479
482
|
clip_arr = getter.get(samp_start, samp_end)
|
auto_editor/render/video.py
CHANGED
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING
|
|
6
6
|
import bv
|
7
7
|
import numpy as np
|
8
8
|
|
9
|
-
from auto_editor.timeline import TlImage, TlRect
|
9
|
+
from auto_editor.timeline import Clip, TlImage, TlRect
|
10
10
|
from auto_editor.utils.func import parse_bitrate
|
11
11
|
|
12
12
|
if TYPE_CHECKING:
|
@@ -120,6 +120,7 @@ def render_av(
|
|
120
120
|
|
121
121
|
del codec
|
122
122
|
output_stream = output.add_stream(args.video_codec, rate=target_fps)
|
123
|
+
output_stream.options = {"x265-params": "log-level=error"} # type: ignore
|
123
124
|
|
124
125
|
cc = output_stream.codec_context
|
125
126
|
if args.vprofile is not None:
|
@@ -193,7 +194,7 @@ def render_av(
|
|
193
194
|
obj_list: list[VideoFrame | TlRect | TlImage] = []
|
194
195
|
for layer in tl.v:
|
195
196
|
for lobj in layer:
|
196
|
-
if isinstance(lobj,
|
197
|
+
if isinstance(lobj, Clip):
|
197
198
|
if index >= lobj.start and index < (lobj.start + lobj.dur):
|
198
199
|
_i = round((lobj.offset + index - lobj.start) * lobj.speed)
|
199
200
|
obj_list.append(VideoFrame(_i, lobj.src))
|
auto_editor/timeline.py
CHANGED
@@ -12,7 +12,6 @@ if TYPE_CHECKING:
|
|
12
12
|
from collections.abc import Iterator
|
13
13
|
from fractions import Fraction
|
14
14
|
from pathlib import Path
|
15
|
-
from typing import Any
|
16
15
|
|
17
16
|
from auto_editor.ffwrapper import FileInfo
|
18
17
|
from auto_editor.utils.chunks import Chunks
|
@@ -39,45 +38,24 @@ class v1:
|
|
39
38
|
|
40
39
|
|
41
40
|
@dataclass(slots=True)
|
42
|
-
class
|
41
|
+
class Clip:
|
43
42
|
start: int
|
44
43
|
dur: int
|
45
44
|
src: FileInfo
|
46
45
|
offset: int
|
47
|
-
speed: float
|
48
46
|
stream: int
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
"name": "video",
|
53
|
-
"src": self.src,
|
54
|
-
"start": self.start,
|
55
|
-
"dur": self.dur,
|
56
|
-
"offset": self.offset,
|
57
|
-
"speed": self.speed,
|
58
|
-
"stream": self.stream,
|
59
|
-
}
|
60
|
-
|
61
|
-
|
62
|
-
@dataclass(slots=True)
|
63
|
-
class TlAudio:
|
64
|
-
start: int
|
65
|
-
dur: int
|
66
|
-
src: FileInfo
|
67
|
-
offset: int
|
68
|
-
speed: float
|
69
|
-
volume: float
|
70
|
-
stream: int
|
48
|
+
speed: float = 1.0
|
49
|
+
volume: float = 1.0
|
71
50
|
|
72
51
|
def as_dict(self) -> dict:
|
73
52
|
return {
|
74
|
-
"name": "
|
53
|
+
"name": "video",
|
75
54
|
"src": self.src,
|
76
55
|
"start": self.start,
|
77
56
|
"dur": self.dur,
|
78
57
|
"offset": self.offset,
|
79
58
|
"speed": self.speed,
|
80
|
-
"volume": self.volume,
|
81
59
|
"stream": self.stream,
|
82
60
|
}
|
83
61
|
|
@@ -177,14 +155,12 @@ rect_builder = pAttrs(
|
|
177
155
|
visual_objects = {
|
178
156
|
"rect": (TlRect, rect_builder),
|
179
157
|
"image": (TlImage, img_builder),
|
180
|
-
"video": (
|
158
|
+
"video": (Clip, video_builder),
|
181
159
|
}
|
182
160
|
|
183
|
-
VLayer = list[
|
161
|
+
VLayer = list[Clip | TlImage | TlRect]
|
184
162
|
VSpace = list[VLayer]
|
185
|
-
|
186
|
-
ALayer = list[TlAudio]
|
187
|
-
ASpace = list[ALayer]
|
163
|
+
ASpace = list[list[Clip]]
|
188
164
|
|
189
165
|
|
190
166
|
@dataclass(slots=True)
|
@@ -249,7 +225,7 @@ video\n"""
|
|
249
225
|
for i, layer in enumerate(self.v):
|
250
226
|
result += f" v{i} "
|
251
227
|
for obj in layer:
|
252
|
-
if isinstance(obj,
|
228
|
+
if isinstance(obj, Clip):
|
253
229
|
result += (
|
254
230
|
f"[#:start {obj.start} #:dur {obj.dur} #:off {obj.offset}] "
|
255
231
|
)
|
@@ -284,7 +260,7 @@ video\n"""
|
|
284
260
|
def sources(self) -> Iterator[FileInfo]:
|
285
261
|
for vclips in self.v:
|
286
262
|
for v in vclips:
|
287
|
-
if isinstance(v,
|
263
|
+
if isinstance(v, Clip):
|
288
264
|
yield v.src
|
289
265
|
for aclips in self.a:
|
290
266
|
for a in aclips:
|
@@ -297,29 +273,36 @@ video\n"""
|
|
297
273
|
seen.add(source.path)
|
298
274
|
yield source
|
299
275
|
|
300
|
-
def
|
301
|
-
|
302
|
-
for clips in
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
total_dur = max(total_dur, dur)
|
307
|
-
return total_dur
|
276
|
+
def __len__(self) -> int:
|
277
|
+
result = 0
|
278
|
+
for clips in self.v + self.a:
|
279
|
+
if len(clips) > 0:
|
280
|
+
lastClip = clips[-1]
|
281
|
+
result = max(result, lastClip.start + lastClip.dur)
|
308
282
|
|
309
|
-
|
310
|
-
# Calculates the duration of the timeline
|
311
|
-
return max(self._duration(self.v), self._duration(self.a))
|
283
|
+
return result
|
312
284
|
|
313
285
|
def as_dict(self) -> dict:
|
286
|
+
def aclip_to_dict(self: Clip) -> dict:
|
287
|
+
return {
|
288
|
+
"name": "audio",
|
289
|
+
"src": self.src,
|
290
|
+
"start": self.start,
|
291
|
+
"dur": self.dur,
|
292
|
+
"offset": self.offset,
|
293
|
+
"speed": self.speed,
|
294
|
+
"volume": self.volume,
|
295
|
+
"stream": self.stream,
|
296
|
+
}
|
297
|
+
|
314
298
|
v = []
|
315
|
-
|
299
|
+
a = []
|
300
|
+
for vlayer in self.v:
|
316
301
|
vb = [vobj.as_dict() for vobj in vlayer]
|
317
302
|
if vb:
|
318
303
|
v.append(vb)
|
319
|
-
|
320
|
-
|
321
|
-
for i, alayer in enumerate(self.a):
|
322
|
-
ab = [aobj.as_dict() for aobj in alayer]
|
304
|
+
for layer in self.a:
|
305
|
+
ab = [aclip_to_dict(clip) for clip in layer]
|
323
306
|
if ab:
|
324
307
|
a.append(ab)
|
325
308
|
|
@@ -347,7 +330,7 @@ video\n"""
|
|
347
330
|
return self.T.sr
|
348
331
|
|
349
332
|
|
350
|
-
def make_tracks_dir(tracks_dir: Path
|
333
|
+
def make_tracks_dir(tracks_dir: Path) -> None:
|
351
334
|
from os import mkdir
|
352
335
|
from shutil import rmtree
|
353
336
|
|
@@ -358,7 +341,7 @@ def make_tracks_dir(tracks_dir: Path, path: Path) -> None:
|
|
358
341
|
mkdir(tracks_dir)
|
359
342
|
|
360
343
|
|
361
|
-
def set_stream_to_0(
|
344
|
+
def set_stream_to_0(tl: v3, log: Log) -> None:
|
362
345
|
dir_exists = False
|
363
346
|
cache: dict[Path, FileInfo] = {}
|
364
347
|
|
@@ -367,7 +350,7 @@ def set_stream_to_0(src: FileInfo, tl: v3, log: Log) -> None:
|
|
367
350
|
|
368
351
|
fold = path.parent / f"{path.stem}_tracks"
|
369
352
|
if not dir_exists:
|
370
|
-
make_tracks_dir(fold
|
353
|
+
make_tracks_dir(fold)
|
371
354
|
dir_exists = True
|
372
355
|
|
373
356
|
newtrack = fold / f"{path.stem}_{i}.wav"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: auto-editor
|
3
|
-
Version:
|
3
|
+
Version: 28.0.1
|
4
4
|
Summary: Auto-Editor: Effort free video editing!
|
5
5
|
Author-email: WyattBlue <wyattblue@auto-editor.com>
|
6
6
|
License-Expression: 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,>=2
|
15
|
-
Requires-Dist: basswood-av<16,>=15.
|
15
|
+
Requires-Dist: basswood-av<16,>=15.2.1
|
16
16
|
Dynamic: license-file
|
17
17
|
|
18
18
|
<p align="center"><img src="https://auto-editor.com/img/auto-editor-banner.webp" title="Auto-Editor" width="700"></p>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
auto_editor/__init__.py,sha256=qvc7djhJkqlXmlxcWZWLvK6JKBp01_I3fJuFV5euTBg,23
|
2
|
+
auto_editor/__main__.py,sha256=t5Um7M9ess9xYRfmn6iDvJoBqj_KRQLhlkpFdfhx3MU,15478
|
3
|
+
auto_editor/analyze.py,sha256=CeJG0LI9wXZk1R-QPrNGPS4za-_Avd8y7H-D437DqLg,12300
|
4
|
+
auto_editor/edit.py,sha256=GhOfKIe_FdbBGDQ_WH02CJl7Oi-AwaaSSh73F81h_kA,19234
|
5
|
+
auto_editor/ffwrapper.py,sha256=ueYdN7-cBAdJBJbv5yT05iuQP_BPFIrR5hFeMkk5c3U,5040
|
6
|
+
auto_editor/help.py,sha256=8Kkos7Bpcn-3YN7ngv0fZp-8a8Qw6b70ZZKerL8SEQ4,7901
|
7
|
+
auto_editor/json.py,sha256=g6ZsrSOXtjQj-8Otea3TIY2G-HZ6g-IXUblwukgTO1g,9332
|
8
|
+
auto_editor/make_layers.py,sha256=Udxn7Vw0Jz9HOarLeswQ-WwTu87PWcsyduBdtFwSOyc,10079
|
9
|
+
auto_editor/preview.py,sha256=yYn5jJLQ3TiJiNC6JffaggLVPQfBU558zJeRQz7nCDY,3046
|
10
|
+
auto_editor/timeline.py,sha256=ebnEX23HubNm444SIB2QNPkNdZcxHGhci1BpAeVDwcQ,9186
|
11
|
+
auto_editor/vanparse.py,sha256=Ug5A2QaRqGiw4l55Z_h9T2QU1x0WqRibR7yY5rQ0WTk,10002
|
12
|
+
auto_editor/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
+
auto_editor/cmds/cache.py,sha256=rK06dX3Z1pDAK0t5rqR7S2cMEpnT_Tv17t3Q5qPQKLI,1959
|
14
|
+
auto_editor/cmds/desc.py,sha256=kdRJfabdde5thuFOoTXlW3J3G8F0ZvbsJoOkUn7E3GA,805
|
15
|
+
auto_editor/cmds/info.py,sha256=NwzZu6l6IIdK0ajZdn8WX_iiJwlsMrGIZ2vffDRu3gc,6535
|
16
|
+
auto_editor/cmds/levels.py,sha256=2Hbvoy6wMbRRoHdZf25PMqq1uvhRKyPcITNPMpZFo7s,5632
|
17
|
+
auto_editor/cmds/palet.py,sha256=t2O_xM82PXUjnSgcHxyt9OG24gwQS4ksR2sKiQ1SvUA,743
|
18
|
+
auto_editor/cmds/repl.py,sha256=HSUTDaVykPb5Bd-v_jz_8R7HvFmKOcT_ZVmP-d0AbUY,3247
|
19
|
+
auto_editor/cmds/subdump.py,sha256=Zxs9X0gEaQYA5F1EqccJmVUYfI1o3J7ltyc9bvy1tA4,2393
|
20
|
+
auto_editor/cmds/test.py,sha256=p7z2cojsiyWnRN_UVeT4iYakkGlsQTjt_dRZ4cSvIQg,29835
|
21
|
+
auto_editor/exports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
+
auto_editor/exports/fcp11.py,sha256=LiWHtA-jgwzbiSoBzNBUaTjOEuqnvr3dYBQmdlw7m3Y,5244
|
23
|
+
auto_editor/exports/fcp7.py,sha256=shZtn5i66hqGVrpR1PP1hiwKiZirr1cRUxATzbW-BOo,12069
|
24
|
+
auto_editor/exports/json.py,sha256=Z7RKtD5-OB3saOtWG9qfI9OrLtylhU9VyfpnVRNcuU8,768
|
25
|
+
auto_editor/exports/shotcut.py,sha256=MpzYqDO_XSnd-bKCKQjJFqOf_mSdR9QOWi8_Y1Y_BwY,4696
|
26
|
+
auto_editor/imports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
+
auto_editor/imports/fcp7.py,sha256=Vep1syViRZOrtZBlF6Ek_eRy0rLINpTso5nrh3uY3zk,8563
|
28
|
+
auto_editor/imports/json.py,sha256=5c_vKoS8FzxAWagCetrwATHdnZ2beWQ77g8JYKVM0i8,6993
|
29
|
+
auto_editor/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
|
+
auto_editor/lang/libintrospection.py,sha256=6H1rGp0wqaCud5IPaoEmzULGnYt6ec7_0h32ATcw2oY,261
|
31
|
+
auto_editor/lang/libmath.py,sha256=z33A161Oe6vYYK7R6pgYjdZZe63dQkN38Qf36TL3prg,847
|
32
|
+
auto_editor/lang/palet.py,sha256=bsuEWNEefTb0-69Dc4lq4aotqu7aarH1okETK8ab-Gw,22794
|
33
|
+
auto_editor/lang/stdenv.py,sha256=munuKA5rkg_5krQ_km92JhoNY6Vio9wo5E79YWlD2eg,43654
|
34
|
+
auto_editor/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
+
auto_editor/lib/contracts.py,sha256=bADXnFXyq_-Tku59saxwDOlvexfS3wMAMdrKNL-Ql2w,7494
|
36
|
+
auto_editor/lib/data_structs.py,sha256=2SxsOXKiY0H95wRIFOrQBjv1ykJUQar0Vr5dK9zZOiQ,6971
|
37
|
+
auto_editor/lib/err.py,sha256=UlszQJdzMZwkbT8x3sY4GkCV_5x9yrd6uVVUzvA8iiI,35
|
38
|
+
auto_editor/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
|
+
auto_editor/render/audio.py,sha256=08Leg9R66ROz8meZyY03e7yfUd5otxdd6DdNO9vX5ys,17518
|
40
|
+
auto_editor/render/subtitle.py,sha256=F27T8OsAojUIGTGBWqTdH36h0BnHXSExxIqzOtqyZoE,6129
|
41
|
+
auto_editor/render/video.py,sha256=8somlAxtbGMSRREab8psTdIlaETZQ2s2gY20PWY9sww,12072
|
42
|
+
auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
|
+
auto_editor/utils/bar.py,sha256=Ky9JRf37JTgLyvNuIXDfucaUE8H1vBbCqKLjttmsmmo,4156
|
44
|
+
auto_editor/utils/chunks.py,sha256=J-eGKtEz68gFtRrj1kOSgH4Tj_Yz6prNQ7Xr-d9NQJw,52
|
45
|
+
auto_editor/utils/cmdkw.py,sha256=aUGBvBel2Ko1o6Rwmr4rEL-BMc5hEnzYLbyZ1GeJdcY,5729
|
46
|
+
auto_editor/utils/container.py,sha256=CNHChHbhzIrjmDdWw6UzMqscrr9u7A-ZqKWejGjJwYE,2628
|
47
|
+
auto_editor/utils/func.py,sha256=ODyjXnzSDatEu08w398K8_xBKYdXMY3IPHiJpGRZDyQ,3250
|
48
|
+
auto_editor/utils/log.py,sha256=wPNf6AabV-0cnoS_bPLv1Lh7llQBtNqPKeh07einOuc,3701
|
49
|
+
auto_editor/utils/types.py,sha256=j2hd4zMQ9EftDy41Ji2_PFru_7HEZObd9yKA0BJxFaY,7616
|
50
|
+
auto_editor-28.0.1.dist-info/licenses/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
|
51
|
+
docs/build.py,sha256=g1uc1H9T_naGaermUiVMMwUpbT0IWElRhjgT0fvCh8w,1914
|
52
|
+
auto_editor-28.0.1.dist-info/METADATA,sha256=DqTFmUbe3CYS0CefGlNadtwH80JaemOw0MOCXtDGCsg,6176
|
53
|
+
auto_editor-28.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
54
|
+
auto_editor-28.0.1.dist-info/entry_points.txt,sha256=UAsTc7qJQbnAzHd7KWg-ALo_X9Hj2yDs3M9I2DV3eyI,212
|
55
|
+
auto_editor-28.0.1.dist-info/top_level.txt,sha256=jBV5zlbWRbKOa-xaWPvTD45QL7lGExx2BDzv-Ji4dTw,17
|
56
|
+
auto_editor-28.0.1.dist-info/RECORD,,
|
auto_editor/formats/utils.py
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from typing import TYPE_CHECKING
|
4
|
-
from xml.etree.ElementTree import Element
|
5
|
-
|
6
|
-
if TYPE_CHECKING:
|
7
|
-
from auto_editor.utils.log import Log
|
8
|
-
|
9
|
-
|
10
|
-
def show(ele: Element, limit: int, depth: int = 0) -> None:
|
11
|
-
print(
|
12
|
-
f"{' ' * (depth * 4)}<{ele.tag} {ele.attrib}> {ele.text.strip() if ele.text is not None else ''}"
|
13
|
-
)
|
14
|
-
for child in ele:
|
15
|
-
if isinstance(child, Element) and depth < limit:
|
16
|
-
show(child, limit, depth + 1)
|
17
|
-
|
18
|
-
|
19
|
-
class Validator:
|
20
|
-
def __init__(self, log: Log):
|
21
|
-
self.log = log
|
22
|
-
|
23
|
-
def parse(self, ele: Element, schema: dict) -> dict:
|
24
|
-
new: dict = {}
|
25
|
-
|
26
|
-
for key, val in schema.items():
|
27
|
-
if isinstance(val, dict) and "__arr" in val:
|
28
|
-
new[key] = []
|
29
|
-
|
30
|
-
is_arr = False
|
31
|
-
for child in ele:
|
32
|
-
if child.tag not in schema:
|
33
|
-
continue
|
34
|
-
|
35
|
-
if schema[child.tag] is None:
|
36
|
-
new[child.tag] = child
|
37
|
-
continue
|
38
|
-
|
39
|
-
if isinstance(schema[child.tag], dict):
|
40
|
-
val = self.parse(child, schema[child.tag])
|
41
|
-
is_arr = "__arr" in schema[child.tag]
|
42
|
-
else:
|
43
|
-
val = schema[child.tag](child.text)
|
44
|
-
|
45
|
-
if child.tag in new:
|
46
|
-
if not is_arr:
|
47
|
-
self.log.error(f"<{child.tag}> can only occur once")
|
48
|
-
new[child.tag].append(val)
|
49
|
-
else:
|
50
|
-
new[child.tag] = [val] if is_arr else val
|
51
|
-
|
52
|
-
return new
|
53
|
-
|
54
|
-
def check(self, ele: Element, tag: str) -> None:
|
55
|
-
if tag != ele.tag:
|
56
|
-
self.log.error(f"Expected '{tag}' tag, got '{ele.tag}'")
|
@@ -1,54 +0,0 @@
|
|
1
|
-
auto_editor/__init__.py,sha256=0ioEHfOkA9Eoup9m_rzaYLCKq4b4PYoylPtUx3iCRPE,23
|
2
|
-
auto_editor/__main__.py,sha256=WfNtjKwx5fDMPpfSNLarigXD3Jp0My98FpzQqSAxQZ8,15807
|
3
|
-
auto_editor/analyze.py,sha256=CeJG0LI9wXZk1R-QPrNGPS4za-_Avd8y7H-D437DqLg,12300
|
4
|
-
auto_editor/edit.py,sha256=qeuStjcBbRVhLweap_pxxAfME3Jh6tHyxywOjrYJ_ts,19125
|
5
|
-
auto_editor/ffwrapper.py,sha256=Wet6B5nohgnjpBX7o20Zq0rYr-H9mUuOqHrbQAPPj38,5128
|
6
|
-
auto_editor/help.py,sha256=CzfDTsL4GuGu596ySHKj_wKnxGR9h8B0KUdkZpo33oE,8044
|
7
|
-
auto_editor/json.py,sha256=8IVhZJSLx2IVqJsbR5YKDvbHOhgIOvdQmYNpMdMG_xA,9332
|
8
|
-
auto_editor/make_layers.py,sha256=nSEeCHysMot2eze23q05g2HFDuskN_4Jk108xlk2Rw8,10102
|
9
|
-
auto_editor/preview.py,sha256=cqQdozM2IB-5qXHNxeqiSrSdEIzlMfjD4SU-NX9sYZ0,3052
|
10
|
-
auto_editor/timeline.py,sha256=wUduvIB7JRoV_kswSBWJar_aNJH6i-RO917xrON6lIM,9521
|
11
|
-
auto_editor/vanparse.py,sha256=Ug5A2QaRqGiw4l55Z_h9T2QU1x0WqRibR7yY5rQ0WTk,10002
|
12
|
-
auto_editor/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
-
auto_editor/cmds/cache.py,sha256=bViYbtVXefTeEIUvSanDfA6cG35ep1N_Jvtz7ZjgIkY,1959
|
14
|
-
auto_editor/cmds/desc.py,sha256=DSAWPKt8PS9soBTgzpsFIEWoTe4gPTWwjXpNL-p3WsI,866
|
15
|
-
auto_editor/cmds/info.py,sha256=VA2WkTBbQPvrVHjDaJyqryoVMtiiN6cguiUMdWgBJfU,7002
|
16
|
-
auto_editor/cmds/levels.py,sha256=2Hbvoy6wMbRRoHdZf25PMqq1uvhRKyPcITNPMpZFo7s,5632
|
17
|
-
auto_editor/cmds/palet.py,sha256=ONzTqemaQq9YEfIOsDRNnwzfqnEMUMSXIQrETxyroRU,749
|
18
|
-
auto_editor/cmds/repl.py,sha256=HSUTDaVykPb5Bd-v_jz_8R7HvFmKOcT_ZVmP-d0AbUY,3247
|
19
|
-
auto_editor/cmds/subdump.py,sha256=kHg8nfUi6I6VeJjEgMxupPa666qsYUh7ZEUxint7Gqo,2443
|
20
|
-
auto_editor/cmds/test.py,sha256=UNN1r6J69-woqA6QU7TeY0WlPxukQzwCRl5DGBTLK8g,28837
|
21
|
-
auto_editor/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
-
auto_editor/formats/fcp11.py,sha256=uaJbLiwiVxqoVy5JCA14wZj-m1wqZIzWh7rS-BsnSQM,5219
|
23
|
-
auto_editor/formats/fcp7.py,sha256=Q_raDxOBqo8QcnhaiXrIFPB-Un7wUvQ4SYt6KALOI1s,19212
|
24
|
-
auto_editor/formats/json.py,sha256=UUBhFR_79vn4Lxu73B0cVBFgw4qytrmMP-TiCmDFMd0,7666
|
25
|
-
auto_editor/formats/shotcut.py,sha256=-ES854LLFCMCBe100JRJedDmuk8zPev17aQMTrzPv-g,4923
|
26
|
-
auto_editor/formats/utils.py,sha256=LYXDiqOk9WwUorLGw2D0M7In9BNDkoKikNawuks7hqE,1648
|
27
|
-
auto_editor/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
auto_editor/lang/libintrospection.py,sha256=6H1rGp0wqaCud5IPaoEmzULGnYt6ec7_0h32ATcw2oY,261
|
29
|
-
auto_editor/lang/libmath.py,sha256=z33A161Oe6vYYK7R6pgYjdZZe63dQkN38Qf36TL3prg,847
|
30
|
-
auto_editor/lang/palet.py,sha256=RQjyIZMJSWnzDkHTu-5mt74o9_4zO4VrcH-wLojCF7A,24113
|
31
|
-
auto_editor/lang/stdenv.py,sha256=o7kFu7EbaH71XPFGxJUXYGxSeZ8O3i1_C5Hmi9uya4Q,44150
|
32
|
-
auto_editor/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
|
-
auto_editor/lib/contracts.py,sha256=lExGQymcQUmwG5lC1lO4qm4GY8W0q_yzK_miTaAoPA4,7586
|
34
|
-
auto_editor/lib/data_structs.py,sha256=Hnzl5gWvo-geTU0g-lGejj6HQW3VvPv0NBEj2XoGskY,7089
|
35
|
-
auto_editor/lib/err.py,sha256=UlszQJdzMZwkbT8x3sY4GkCV_5x9yrd6uVVUzvA8iiI,35
|
36
|
-
auto_editor/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
|
-
auto_editor/render/audio.py,sha256=ejV_NIvrmxMJt6mf7nPNIzlPHOumNhcIO2J-irHO-k8,17427
|
38
|
-
auto_editor/render/subtitle.py,sha256=F27T8OsAojUIGTGBWqTdH36h0BnHXSExxIqzOtqyZoE,6129
|
39
|
-
auto_editor/render/video.py,sha256=uIrYzF4bDZ3vwfX2F6TdR6F73GI4yruGssto9xEQ-AA,11999
|
40
|
-
auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
|
-
auto_editor/utils/bar.py,sha256=Ky9JRf37JTgLyvNuIXDfucaUE8H1vBbCqKLjttmsmmo,4156
|
42
|
-
auto_editor/utils/chunks.py,sha256=J-eGKtEz68gFtRrj1kOSgH4Tj_Yz6prNQ7Xr-d9NQJw,52
|
43
|
-
auto_editor/utils/cmdkw.py,sha256=aUGBvBel2Ko1o6Rwmr4rEL-BMc5hEnzYLbyZ1GeJdcY,5729
|
44
|
-
auto_editor/utils/container.py,sha256=CNHChHbhzIrjmDdWw6UzMqscrr9u7A-ZqKWejGjJwYE,2628
|
45
|
-
auto_editor/utils/func.py,sha256=ODyjXnzSDatEu08w398K8_xBKYdXMY3IPHiJpGRZDyQ,3250
|
46
|
-
auto_editor/utils/log.py,sha256=wPNf6AabV-0cnoS_bPLv1Lh7llQBtNqPKeh07einOuc,3701
|
47
|
-
auto_editor/utils/types.py,sha256=j2hd4zMQ9EftDy41Ji2_PFru_7HEZObd9yKA0BJxFaY,7616
|
48
|
-
auto_editor-27.1.1.dist-info/licenses/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
|
49
|
-
docs/build.py,sha256=g1uc1H9T_naGaermUiVMMwUpbT0IWElRhjgT0fvCh8w,1914
|
50
|
-
auto_editor-27.1.1.dist-info/METADATA,sha256=ri7aLym52FDEnnDR7czUR3xqZ025BLmepV0Em6GXjQc,6176
|
51
|
-
auto_editor-27.1.1.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
|
52
|
-
auto_editor-27.1.1.dist-info/entry_points.txt,sha256=UAsTc7qJQbnAzHd7KWg-ALo_X9Hj2yDs3M9I2DV3eyI,212
|
53
|
-
auto_editor-27.1.1.dist-info/top_level.txt,sha256=jBV5zlbWRbKOa-xaWPvTD45QL7lGExx2BDzv-Ji4dTw,17
|
54
|
-
auto_editor-27.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|