auto-editor 24.31.1__py3-none-any.whl → 25.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.
@@ -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[int | float]) -> None:
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
- if isinstance(a, float):
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
- temp = setup_tempdir(None, Log())
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, temp, log)
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))
@@ -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 FileSetup, Levels
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
- temp = setup_tempdir(args.temp_dir, Log())
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, temp, log)
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.version} ({auto_editor.__version__})")
70
+ print(f"Auto-Editor {auto_editor.__version__}")
74
71
  text = None
75
72
 
76
73
  try:
@@ -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 Any
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
- checker = Checker(Log())
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 = checker.check(out)
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 checker.check(out).videos[0].codec == "gif"
297
+ assert fileinfo(out).videos[0].codec == "gif"
299
298
 
300
299
  return out
301
300
 
@@ -310,7 +309,7 @@ def main(sys_args: list[str] | None = None):
310
309
  """Input file must have an extension. Throw error if none is given."""
311
310
 
312
311
  shutil.copy("example.mp4", "example")
313
- run.check(["example", "--no-open"], "must have an extension.")
312
+ run.check(["example", "--no-open"], "must have an extension")
314
313
 
315
314
  return "example"
316
315
 
@@ -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 checker.check(out).videos[0].codec == "h264"
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 checker.check(out).videos[0].codec == "h264"
325
+ assert fileinfo(out).videos[0].codec == "h264"
327
326
 
328
327
  return "out.mp4", "out.mkv"
329
328
 
@@ -356,15 +355,22 @@ def main(sys_args: list[str] | None = None):
356
355
  def premiere_named_export():
357
356
  run.main(["example.mp4"], ["--export", 'premiere:name="Foo Bar"'])
358
357
 
358
+ def export_subtitles():
359
+ cn = fileinfo(run.main(["resources/subtitle.mp4"], []))
360
+
361
+ assert len(cn.videos) == 1
362
+ assert len(cn.audios) == 1
363
+ assert len(cn.subtitles) == 1
364
+
359
365
  def resolution_and_scale():
360
- cn = checker.check(run.main(["example.mp4"], ["--scale", "1.5"]))
366
+ cn = fileinfo(run.main(["example.mp4"], ["--scale", "1.5"]))
361
367
 
362
368
  assert cn.videos[0].fps == 30
363
369
  assert cn.videos[0].width == 1920
364
370
  assert cn.videos[0].height == 1080
365
371
  assert cn.audios[0].samplerate == 48000
366
372
 
367
- cn = checker.check(run.main(["example.mp4"], ["--scale", "0.2"]))
373
+ cn = fileinfo(run.main(["example.mp4"], ["--scale", "0.2"]))
368
374
 
369
375
  assert cn.videos[0].fps == 30
370
376
  assert cn.videos[0].width == 256
@@ -372,7 +378,7 @@ def main(sys_args: list[str] | None = None):
372
378
  assert cn.audios[0].samplerate == 48000
373
379
 
374
380
  out = run.main(["example.mp4"], ["-res", "700,380", "-b", "darkgreen"])
375
- cn = checker.check(out)
381
+ cn = fileinfo(out)
376
382
 
377
383
  assert cn.videos[0].fps == 30
378
384
  assert cn.videos[0].width == 700
@@ -416,7 +422,7 @@ def main(sys_args: list[str] | None = None):
416
422
  ["--edit", "audio:stream=1"],
417
423
  "out.mov",
418
424
  )
419
- assert len(checker.check(out).audios) == 1
425
+ assert len(fileinfo(out).audios) == 1
420
426
 
421
427
  return out
422
428
 
@@ -427,7 +433,7 @@ def main(sys_args: list[str] | None = None):
427
433
 
428
434
  def concat_mux_tracks():
429
435
  out = run.main(["example.mp4", "resources/multi-track.mov"], [], "out.mov")
430
- assert len(checker.check(out).audios) == 1
436
+ assert len(fileinfo(out).audios) == 1
431
437
 
432
438
  return out
433
439
 
@@ -437,30 +443,30 @@ def main(sys_args: list[str] | None = None):
437
443
  ["--keep-tracks-separate"],
438
444
  "out.mov",
439
445
  )
440
- assert len(checker.check(out).audios) == 2
446
+ assert len(fileinfo(out).audios) == 2
441
447
  out = run.main(
442
448
  ["example.mp4", "resources/multi-track.mov"],
443
449
  ["--keep-tracks-separate"],
444
450
  "out.mov",
445
451
  )
446
- assert len(checker.check(out).audios) == 2
452
+ assert len(fileinfo(out).audios) == 2
447
453
 
448
454
  return out
449
455
 
450
456
  def frame_rate():
451
- cn = checker.check(run.main(["example.mp4"], ["-r", "15", "--no-seek"]))
457
+ cn = fileinfo(run.main(["example.mp4"], ["-r", "15", "--no-seek"]))
452
458
  video = cn.videos[0]
453
459
  assert video.fps == 15
454
460
  assert video.time_base == Fraction(1, 15)
455
461
  assert float(video.duration) - 17.33333333333333333333333 < 3
456
462
 
457
- cn = checker.check(run.main(["example.mp4"], ["-r", "20"]))
463
+ cn = fileinfo(run.main(["example.mp4"], ["-r", "20"]))
458
464
  video = cn.videos[0]
459
465
  assert video.fps == 20
460
466
  assert video.time_base == Fraction(1, 20)
461
467
  assert float(video.duration) - 17.33333333333333333333333 < 2
462
468
 
463
- cn = checker.check(out := run.main(["example.mp4"], ["-r", "60"]))
469
+ cn = fileinfo(out := run.main(["example.mp4"], ["-r", "60"]))
464
470
  video = cn.videos[0]
465
471
 
466
472
  assert video.fps == 60
@@ -471,22 +477,22 @@ def main(sys_args: list[str] | None = None):
471
477
 
472
478
  def embedded_image():
473
479
  out1 = run.main(["resources/embedded-image/h264-png.mp4"], [])
474
- cn = checker.check(out1)
480
+ cn = fileinfo(out1)
475
481
  assert cn.videos[0].codec == "h264"
476
482
  assert cn.videos[1].codec == "png"
477
483
 
478
484
  out2 = run.main(["resources/embedded-image/h264-mjpeg.mp4"], [])
479
- cn = checker.check(out2)
485
+ cn = fileinfo(out2)
480
486
  assert cn.videos[0].codec == "h264"
481
487
  assert cn.videos[1].codec == "mjpeg"
482
488
 
483
489
  out3 = run.main(["resources/embedded-image/h264-png.mkv"], [])
484
- cn = checker.check(out3)
490
+ cn = fileinfo(out3)
485
491
  assert cn.videos[0].codec == "h264"
486
492
  assert cn.videos[1].codec == "png"
487
493
 
488
494
  out4 = run.main(["resources/embedded-image/h264-mjpeg.mkv"], [])
489
- cn = checker.check(out4)
495
+ cn = fileinfo(out4)
490
496
  assert cn.videos[0].codec == "h264"
491
497
  assert cn.videos[1].codec == "mjpeg"
492
498
 
@@ -532,7 +538,7 @@ def main(sys_args: list[str] | None = None):
532
538
  # Issue 280
533
539
  def SAR():
534
540
  out = run.main(["resources/SAR-2by3.mp4"], [])
535
- assert checker.check(out).videos[0].sar == Fraction(2, 3)
541
+ assert fileinfo(out).videos[0].sar == Fraction(2, 3)
536
542
 
537
543
  return out
538
544
 
@@ -744,6 +750,7 @@ def main(sys_args: list[str] | None = None):
744
750
  track_tests,
745
751
  codec_tests,
746
752
  premiere_named_export,
753
+ export_subtitles,
747
754
  export,
748
755
  motion,
749
756
  resolution_and_scale,
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 fractions import Fraction
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
- anchor,
14
- color,
15
- natural,
16
- number,
17
- threshold,
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)
@@ -72,6 +72,8 @@ def container_constructor(ext: str) -> Container:
72
72
  vdefault = container.default_video_codec
73
73
  adefault = container.default_audio_codec
74
74
  sdefault = container.default_subtitle_codec
75
+ if sdefault == "none" and ext == "mp4":
76
+ sdefault = "srt"
75
77
 
76
78
  vcodecs = set()
77
79
  acodecs = set()
@@ -83,6 +85,10 @@ def container_constructor(ext: str) -> Container:
83
85
  vcodecs.add(codec)
84
86
  if codec == "h264":
85
87
  vcodecs.add("libx264")
88
+ if codec == "av1":
89
+ vcodecs.add("libsvtav1")
90
+ if codec == "hevc":
91
+ vcodecs.add("hevc_nvenc")
86
92
  if kind == "audio":
87
93
  acodecs.add(codec)
88
94
  if kind == "subtitle":
auto_editor/utils/func.py CHANGED
@@ -1,15 +1,19 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Callable
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
- from auto_editor.utils.log import Log
7
+ if TYPE_CHECKING:
8
+ from collections.abc import Callable
9
+ from fractions import Fraction
10
10
 
11
- BoolList = NDArray[np.bool_]
12
- BoolOperand = Callable[[BoolList, BoolList], BoolList]
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", "temp", "machine", "start_time", "no_color")
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
- temp: str | None = None,
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.start_time = 0 if self.quiet or self.machine else perf_counter()
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.temp is None:
61
+ if self._temp is None:
35
62
  return
36
63
  try:
37
- rmtree(self.temp)
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.temp)
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.start_time, 2)
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")
@@ -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
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- import os
4
3
  import re
5
4
  import subprocess
6
5
  import sys
6
+ from os.path import exists, isdir, isfile, lexists, splitext
7
7
 
8
8
  from auto_editor.ffwrapper import FFmpeg
9
9
  from auto_editor.utils.func import get_stdout
@@ -27,7 +27,7 @@ def download_video(my_input: str, args: Args, ffmpeg: FFmpeg, log: Log) -> str:
27
27
  download_format = "bestvideo[ext=mp4]+bestaudio[ext=m4a]"
28
28
 
29
29
  if args.output_format is None:
30
- output_format = re.sub(r"\W+", "-", os.path.splitext(my_input)[0]) + ".%(ext)s"
30
+ output_format = re.sub(r"\W+", "-", splitext(my_input)[0]) + ".%(ext)s"
31
31
  else:
32
32
  output_format = args.output_format
33
33
 
@@ -57,10 +57,10 @@ def download_video(my_input: str, args: Args, ffmpeg: FFmpeg, log: Log) -> str:
57
57
  msg += "pip or your favorite package manager and make sure it's in PATH."
58
58
  log.error(msg)
59
59
 
60
- if not os.path.isfile(location):
60
+ if not isfile(location):
61
61
  subprocess.run([yt_dlp_path] + cmd)
62
62
 
63
- if not os.path.isfile(location):
63
+ if not isfile(location):
64
64
  log.error(f"Download file wasn't created: {location}")
65
65
 
66
66
  return location
@@ -73,11 +73,16 @@ def valid_input(inputs: list[str], ffmpeg: FFmpeg, args: Args, log: Log) -> list
73
73
  if my_input.startswith("http://") or my_input.startswith("https://"):
74
74
  result.append(download_video(my_input, args, ffmpeg, log))
75
75
  else:
76
- _, ext = os.path.splitext(my_input)
76
+ _, ext = splitext(my_input)
77
77
  if ext == "":
78
- if os.path.isdir(my_input):
78
+ if isdir(my_input):
79
79
  log.error("Input must be a file or a URL, not a directory.")
80
- log.error("Input file must have an extension.")
80
+ if exists(my_input):
81
+ log.error(f"Input file must have an extension: {my_input}")
82
+ if lexists(my_input):
83
+ log.error(f"Input file is a broken symbolic link: {my_input}")
84
+ if my_input.startswith("-"):
85
+ log.error(f"Option/Input file doesn't exist: {my_input}")
81
86
  result.append(my_input)
82
87
 
83
88
  return result
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")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-editor
3
- Version: 24.31.1
3
+ Version: 25.0.1
4
4
  Summary: Auto-Editor: Effort free video editing!
5
5
  Author-email: WyattBlue <wyattblue@auto-editor.com>
6
6
  License: Unlicense
@@ -0,0 +1,55 @@
1
+ auto_editor/__init__.py,sha256=HQ6qfTf_xOT2gRqJKN_PWXCV49oRXl228FqZ7w9Haeg,23
2
+ auto_editor/__main__.py,sha256=aXFUlP7v15CzBeYtLdEPyIX2hxtynXo_UKWUQlxQGbM,9852
3
+ auto_editor/analyze.py,sha256=pHoSZ_-wyV1hLJyJpPg9Ha7oecjdGHGJ0a4hbKnb9NY,11779
4
+ auto_editor/edit.py,sha256=fe6YT6O8B_hPOb4r4FdubvswbTuyx4_qlzlJTyMKuVc,11267
5
+ auto_editor/ffwrapper.py,sha256=NnhD4TvKyaap0Y2MQ7aIUQfeLJwfNbjTj5bLUpoMEI4,7888
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=_9vtbNxodhVPf4PzTAH67LSj2K-HS6kShJOARmUMJdY,2904
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=t5n43HLt9hpMFSIfGV777X4zIPBAFugOKlpCfRjiKxY,6921
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=d-StLyIZHkvJVaiXmr1gYTzUIwLhbG34tJfYosobmps,25227
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=RnpoMmMYmn7o69LmMbBFHW4TsP3K52jYDhG9qzWXmAs,2720
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.1.dist-info/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
51
+ auto_editor-25.0.1.dist-info/METADATA,sha256=FsEPvrdesILZ7duMkfSr7kRBhXEEN6dJ2ttjSr4Z9qw,6137
52
+ auto_editor-25.0.1.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
53
+ auto_editor-25.0.1.dist-info/entry_points.txt,sha256=-H7zdTw4MqnAcwrN5xTNkGIhzZtJMxS9r6lTMeR9-aA,240
54
+ auto_editor-25.0.1.dist-info/top_level.txt,sha256=ky1HUkqq9i034c4CUU_0wBw0xZsxxyGEak1eTbdvpyA,12
55
+ auto_editor-25.0.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (72.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5