auto-editor 24.27.1__py3-none-any.whl → 24.29.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 CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "24.27.1"
2
- version = "24w27a"
1
+ __version__ = "24.29.1"
2
+ version = "24w29a"
auto_editor/analyze.py CHANGED
@@ -9,22 +9,6 @@ from typing import TYPE_CHECKING
9
9
  import numpy as np
10
10
 
11
11
  from auto_editor import version
12
- from auto_editor.lang.json import Lexer, Parser, dump
13
- from auto_editor.lib.contracts import (
14
- is_bool,
15
- is_nat,
16
- is_nat1,
17
- is_str,
18
- is_threshold,
19
- is_void,
20
- orc,
21
- )
22
- from auto_editor.lib.data_structs import Sym
23
- from auto_editor.utils.cmdkw import (
24
- Required,
25
- pAttr,
26
- pAttrs,
27
- )
28
12
  from auto_editor.utils.subtitle_tools import convert_ass_to_text
29
13
  from auto_editor.wavfile import read
30
14
 
@@ -41,35 +25,6 @@ if TYPE_CHECKING:
41
25
  from auto_editor.utils.log import Log
42
26
 
43
27
 
44
- audio_builder = pAttrs(
45
- "audio",
46
- pAttr("threshold", 0.04, is_threshold),
47
- pAttr("stream", 0, orc(is_nat, Sym("all"), "all")),
48
- pAttr("mincut", 6, is_nat),
49
- pAttr("minclip", 3, is_nat),
50
- )
51
- motion_builder = pAttrs(
52
- "motion",
53
- pAttr("threshold", 0.02, is_threshold),
54
- pAttr("stream", 0, is_nat),
55
- pAttr("blur", 9, is_nat),
56
- pAttr("width", 400, is_nat1),
57
- )
58
- subtitle_builder = pAttrs(
59
- "subtitle",
60
- pAttr("pattern", Required, is_str),
61
- pAttr("stream", 0, is_nat),
62
- pAttr("ignore-case", False, is_bool),
63
- pAttr("max-count", None, orc(is_nat, is_void)),
64
- )
65
-
66
- builder_map = {
67
- "audio": audio_builder,
68
- "motion": motion_builder,
69
- "subtitle": subtitle_builder,
70
- }
71
-
72
-
73
28
  @dataclass(slots=True)
74
29
  class FileSetup:
75
30
  src: FileInfo
@@ -90,10 +45,6 @@ def link_nodes(*nodes: FilterContext) -> None:
90
45
  c.link_to(n)
91
46
 
92
47
 
93
- def to_threshold(arr: np.ndarray, t: int | float) -> NDArray[np.bool_]:
94
- return np.fromiter((x >= t for x in arr), dtype=np.bool_)
95
-
96
-
97
48
  def mut_remove_small(
98
49
  arr: NDArray[np.bool_], lim: int, replace: int, with_: int
99
50
  ) -> None:
@@ -193,63 +144,43 @@ class Levels:
193
144
 
194
145
  def read_cache(self, tag: str, obj: dict[str, Any]) -> None | np.ndarray:
195
146
  workfile = os.path.join(
196
- os.path.dirname(self.temp), f"ae-{version}", "cache.json"
147
+ os.path.dirname(self.temp), f"ae-{version}", "cache.npz"
197
148
  )
198
149
 
199
150
  try:
200
- with open(workfile, encoding="utf-8") as file:
201
- cache = Parser(Lexer(workfile, file)).expr()
202
- except Exception:
151
+ npzfile = np.load(workfile, allow_pickle=False)
152
+ except Exception as e:
153
+ self.log.debug(e)
203
154
  return None
204
155
 
205
- if f"{self.src.path.resolve()}" not in cache:
156
+ key = f"{self.src.path}:{obj_tag(tag, self.tb, obj)}"
157
+ if key not in npzfile.files:
206
158
  return None
207
159
 
208
- key = obj_tag(tag, self.tb, obj)
209
-
210
- if key not in (root := cache[f"{self.src.path.resolve()}"]):
211
- return None
212
-
213
- return np.asarray(root[key]["arr"], dtype=root[key]["type"])
160
+ self.log.debug("Using cache")
161
+ return npzfile[key]
214
162
 
215
163
  def cache(self, tag: str, obj: dict[str, Any], arr: np.ndarray) -> np.ndarray:
216
164
  workdur = os.path.join(os.path.dirname(self.temp), f"ae-{version}")
217
- workfile = os.path.join(workdur, "cache.json")
218
165
  if not os.path.exists(workdur):
219
166
  os.mkdir(workdur)
220
167
 
221
- key = obj_tag(tag, self.tb, obj)
222
-
223
- try:
224
- with open(workfile, encoding="utf-8") as file:
225
- json_object = Parser(Lexer(workfile, file)).expr()
226
- except Exception:
227
- json_object = {}
228
-
229
- entry = {"type": str(arr.dtype), "arr": arr.tolist()}
230
- src_key = f"{self.src.path}"
231
-
232
- if src_key in json_object:
233
- json_object[src_key][key] = entry
234
- else:
235
- json_object[src_key] = {key: entry}
236
-
237
- with open(os.path.join(workdur, "cache.json"), "w", encoding="utf-8") as file:
238
- dump(json_object, file)
168
+ tag = obj_tag(tag, self.tb, obj)
169
+ np.savez(os.path.join(workdur, "cache.npz"), **{f"{self.src.path}:{tag}": arr})
239
170
 
240
171
  return arr
241
172
 
242
- def audio(self, s: int) -> NDArray[np.float64]:
243
- if s > len(self.src.audios) - 1:
244
- raise LevelError(f"audio: audio stream '{s}' does not exist.")
173
+ def audio(self, stream: int) -> NDArray[np.float64]:
174
+ if stream > len(self.src.audios) - 1:
175
+ raise LevelError(f"audio: audio stream '{stream}' does not exist.")
245
176
 
246
- if (arr := self.read_cache("audio", {"stream": s})) is not None:
177
+ if (arr := self.read_cache("audio", {"stream": stream})) is not None:
247
178
  return arr
248
179
 
249
- sr, samples = read(self.ensure.audio(self.src, s))
180
+ sr, samples = read(self.ensure.audio(self.src, stream))
250
181
 
251
182
  if len(samples) == 0:
252
- raise LevelError(f"audio: stream '{s}' has no samples.")
183
+ raise LevelError(f"audio: stream '{stream}' has no samples.")
253
184
 
254
185
  def get_max_volume(s: np.ndarray) -> float:
255
186
  return max(float(np.max(s)), -float(np.min(s)))
@@ -262,7 +193,7 @@ class Levels:
262
193
 
263
194
  if samp_per_ticks < 1:
264
195
  self.log.error(
265
- f"audio: stream '{s}'\n Samplerate ({sr}) must be greater than "
196
+ f"audio: stream '{stream}'\n Samplerate ({sr}) must be greater than "
266
197
  f"or equal to timebase ({self.tb})\n"
267
198
  " Try `-fps 30` and/or `--sample-rate 48000`"
268
199
  )
@@ -289,11 +220,11 @@ class Levels:
289
220
  threshold_list[i] = get_max_volume(samples[start:end]) / max_volume
290
221
 
291
222
  self.bar.end()
292
- return self.cache("audio", {"stream": s}, threshold_list)
223
+ return self.cache("audio", {"stream": stream}, threshold_list)
293
224
 
294
225
  def subtitle(
295
226
  self,
296
- patterns: str,
227
+ pattern: str,
297
228
  stream: int,
298
229
  ignore_case: bool,
299
230
  max_count: int | None,
@@ -303,8 +234,7 @@ class Levels:
303
234
 
304
235
  try:
305
236
  flags = re.IGNORECASE if ignore_case else 0
306
- pattern = re.compile(patterns, flags)
307
- del patterns # make sure we don't accidentally use it
237
+ re_pattern = re.compile(pattern, flags)
308
238
  except re.error as e:
309
239
  self.log.error(e)
310
240
 
@@ -362,7 +292,7 @@ class Levels:
362
292
  else:
363
293
  continue
364
294
 
365
- if line and re.search(pattern, line):
295
+ if line and re.search(re_pattern, line):
366
296
  result[san_start:san_end] = 1
367
297
  count += 1
368
298
 
@@ -370,22 +300,22 @@ class Levels:
370
300
 
371
301
  return result
372
302
 
373
- def motion(self, s: int, blur: int, width: int) -> NDArray[np.float64]:
303
+ def motion(self, stream: int, blur: int, width: int) -> NDArray[np.float64]:
374
304
  import av
375
305
 
376
- if s >= len(self.src.videos):
377
- raise LevelError(f"motion: video stream '{s}' does not exist.")
306
+ if stream >= len(self.src.videos):
307
+ raise LevelError(f"motion: video stream '{stream}' does not exist.")
378
308
 
379
- mobj = {"stream": s, "width": width, "blur": blur}
309
+ mobj = {"stream": stream, "width": width, "blur": blur}
380
310
  if (arr := self.read_cache("motion", mobj)) is not None:
381
311
  return arr
382
312
 
383
313
  container = av.open(f"{self.src.path}", "r")
384
314
 
385
- stream = container.streams.video[s]
386
- stream.thread_type = "AUTO"
315
+ video = container.streams.video[stream]
316
+ video.thread_type = "AUTO"
387
317
 
388
- inaccurate_dur = 1 if stream.duration is None else stream.duration
318
+ inaccurate_dur = 1 if video.duration is None else video.duration
389
319
  self.bar.start(inaccurate_dur, "Analyzing motion")
390
320
 
391
321
  prev_frame = None
@@ -395,7 +325,7 @@ class Levels:
395
325
 
396
326
  graph = av.filter.Graph()
397
327
  link_nodes(
398
- graph.add_buffer(template=stream),
328
+ graph.add_buffer(template=video),
399
329
  graph.add("scale", f"{width}:-1"),
400
330
  graph.add("format", "gray"),
401
331
  graph.add("gblur", f"sigma={blur}"),
@@ -405,7 +335,7 @@ class Levels:
405
335
 
406
336
  threshold_list = np.zeros((1024), dtype=np.float64)
407
337
 
408
- for unframe in container.decode(stream):
338
+ for unframe in container.decode(video):
409
339
  graph.push(unframe)
410
340
  frame = graph.pull()
411
341
 
auto_editor/lang/palet.py CHANGED
@@ -18,12 +18,7 @@ from typing import TYPE_CHECKING
18
18
  import numpy as np
19
19
  from numpy import logical_and, logical_not, logical_or, logical_xor
20
20
 
21
- from auto_editor.analyze import (
22
- LevelError,
23
- mut_remove_large,
24
- mut_remove_small,
25
- to_threshold,
26
- )
21
+ from auto_editor.analyze import LevelError, mut_remove_large, mut_remove_small
27
22
  from auto_editor.lib.contracts import *
28
23
  from auto_editor.lib.data_structs import *
29
24
  from auto_editor.lib.err import MyError
@@ -690,6 +685,9 @@ def palet_map(proc: Proc, seq: Any) -> Any:
690
685
  return Quoted(tuple(map(proc, seq.val)))
691
686
  if isinstance(seq, list | range):
692
687
  return list(map(proc, seq))
688
+ elif isinstance(seq, np.ndarray):
689
+ vectorized_proc = np.vectorize(proc)
690
+ return vectorized_proc(seq)
693
691
  return proc(seq)
694
692
 
695
693
 
@@ -1469,6 +1467,26 @@ def edit_all() -> np.ndarray:
1469
1467
  return env["@levels"].all()
1470
1468
 
1471
1469
 
1470
+ def audio_levels(stream: int) -> np.ndarray:
1471
+ if "@levels" not in env:
1472
+ raise MyError("Can't use `audio` if there's no input media")
1473
+
1474
+ try:
1475
+ return env["@levels"].audio(stream)
1476
+ except LevelError as e:
1477
+ raise MyError(e)
1478
+
1479
+
1480
+ def motion_levels(stream: int, blur: int = 9, width: int = 400) -> np.ndarray:
1481
+ if "@levels" not in env:
1482
+ raise MyError("Can't use `motion` if there's no input media")
1483
+
1484
+ try:
1485
+ return env["@levels"].motion(stream, blur, width)
1486
+ except LevelError as e:
1487
+ raise MyError(e)
1488
+
1489
+
1472
1490
  def edit_audio(
1473
1491
  threshold: float = 0.04,
1474
1492
  stream: object = Sym("all"),
@@ -1491,7 +1509,7 @@ def edit_audio(
1491
1509
 
1492
1510
  try:
1493
1511
  for s in stream_range:
1494
- audio_list = to_threshold(levels.audio(s), threshold)
1512
+ audio_list = levels.audio(s) >= threshold
1495
1513
  if stream_data is None:
1496
1514
  stream_data = audio_list
1497
1515
  else:
@@ -1521,7 +1539,7 @@ def edit_motion(
1521
1539
  levels = env["@levels"]
1522
1540
  strict = env["@filesetup"].strict
1523
1541
  try:
1524
- return to_threshold(levels.motion(stream, blur, width), threshold)
1542
+ return levels.motion(stream, blur, width) >= threshold
1525
1543
  except LevelError as e:
1526
1544
  return raise_(e) if strict else levels.all()
1527
1545
 
@@ -1582,7 +1600,7 @@ def my_eval(env: Env, node: object) -> Any:
1582
1600
  return ref(oper, my_eval(env, node[1]))
1583
1601
 
1584
1602
  raise MyError(
1585
- f"Tried to run: {print_str(oper)} with args: {print_str(node[1:])}"
1603
+ f"{print_str(oper)} is not a function. Tried to run with args: {print_str(node[1:])}"
1586
1604
  )
1587
1605
 
1588
1606
  if type(oper) is Syntax:
@@ -1617,10 +1635,12 @@ env.update({
1617
1635
  # edit procedures
1618
1636
  "none": Proc("none", edit_none, (0, 0)),
1619
1637
  "all/e": Proc("all/e", edit_all, (0, 0)),
1638
+ "audio-levels": Proc("audio-levels", audio_levels, (1, 1), is_nat),
1620
1639
  "audio": Proc("audio", edit_audio, (0, 4),
1621
1640
  is_threshold, orc(is_nat, Sym("all")), is_nat,
1622
1641
  {"threshold": 0, "stream": 1, "minclip": 2, "mincut": 2}
1623
1642
  ),
1643
+ "motion-levels": Proc("motion-levels", motion_levels, (1, 3), is_nat, is_nat1, {"blur": 1, "width": 2}),
1624
1644
  "motion": Proc("motion", edit_motion, (0, 4),
1625
1645
  is_threshold, is_nat, is_nat1,
1626
1646
  {"threshold": 0, "stream": 1, "blur": 1, "width": 2}
@@ -5,6 +5,8 @@ from dataclasses import dataclass
5
5
  from fractions import Fraction
6
6
  from typing import Any
7
7
 
8
+ from numpy import float64
9
+
8
10
  from .data_structs import Sym, print_str
9
11
  from .err import MyError
10
12
 
@@ -41,7 +43,7 @@ def check_contract(c: object, val: object) -> bool:
41
43
  return val is True
42
44
  if c is False:
43
45
  return val is False
44
- if type(c) in (int, float, Fraction, complex, str, Sym):
46
+ if type(c) in (int, float, float64, Fraction, complex, str, Sym):
45
47
  return val == c
46
48
  raise MyError(f"Invalid contract, got: {print_str(c)}")
47
49
 
@@ -163,17 +165,21 @@ is_int = Contract("int?", lambda v: type(v) is int)
163
165
  is_nat = Contract("nat?", lambda v: type(v) is int and v > -1)
164
166
  is_nat1 = Contract("nat1?", lambda v: type(v) is int and v > 0)
165
167
  int_not_zero = Contract("(or/c (not/c 0) int?)", lambda v: v != 0 and is_int(v))
166
- is_num = Contract("number?", lambda v: type(v) in (int, float, Fraction, complex))
167
- is_real = Contract("real?", lambda v: type(v) in (int, float, Fraction))
168
- is_float = Contract("float?", lambda v: type(v) is float)
168
+ is_num = Contract(
169
+ "number?", lambda v: type(v) in (int, float, float64, Fraction, complex)
170
+ )
171
+ is_real = Contract("real?", lambda v: type(v) in (int, float, float64, Fraction))
172
+ is_float = Contract("float?", lambda v: type(v) in (float, float64))
169
173
  is_frac = Contract("frac?", lambda v: type(v) is Fraction)
170
174
  is_str = Contract("string?", lambda v: type(v) is str)
171
175
  any_p = Contract("any", lambda v: True)
172
176
  is_void = Contract("void?", lambda v: v is None)
173
- is_int_or_float = Contract("(or/c int? float?)", lambda v: type(v) in (int, float))
177
+ is_int_or_float = Contract(
178
+ "(or/c int? float?)", lambda v: type(v) in (int, float, float64)
179
+ )
174
180
  is_threshold = Contract(
175
181
  "threshold?",
176
- lambda v: type(v) in (int, float) and v >= 0 and v <= 1, # type: ignore
182
+ lambda v: type(v) in (int, float, float64) and v >= 0 and v <= 1, # type: ignore
177
183
  )
178
184
  is_proc = Contract("procedure?", lambda v: isinstance(v, Proc | Contract))
179
185
 
@@ -296,22 +296,4 @@ def make_timeline(
296
296
  else:
297
297
  v1_compatiable = None
298
298
 
299
- tl = v3(inp, tb, sr, res, args.background, vtl, atl, v1_compatiable)
300
-
301
- # Additional monotonic check, o(n^2) time complexity so disable by default.
302
-
303
- # if len(sources) != 1:
304
- # return tl
305
-
306
- # last_i = 0
307
- # for index in range(tl.end):
308
- # for layer in tl.v:
309
- # for lobj in layer:
310
- # if index >= lobj.start and index < (lobj.start + lobj.dur):
311
- # _i = round((lobj.offset + index - lobj.start) * lobj.speed)
312
- # if (_i < last_i):
313
- # print(_i, last_i)
314
- # raise ValueError("not monotonic")
315
- # last_i = _i
316
-
317
- return tl
299
+ return v3(inp, tb, sr, res, args.background, vtl, atl, v1_compatiable)
@@ -6,12 +6,19 @@ from typing import TYPE_CHECKING
6
6
 
7
7
  import numpy as np
8
8
 
9
- from auto_editor.analyze import LevelError, Levels, builder_map
9
+ from auto_editor.analyze import LevelError, Levels
10
10
  from auto_editor.ffwrapper import FFmpeg, initFileInfo
11
11
  from auto_editor.lang.palet import env
12
+ from auto_editor.lib.contracts import is_bool, is_nat, is_nat1, is_str, is_void, orc
12
13
  from auto_editor.output import Ensure
13
14
  from auto_editor.utils.bar import Bar
14
- from auto_editor.utils.cmdkw import ParserError, parse_with_palet
15
+ from auto_editor.utils.cmdkw import (
16
+ ParserError,
17
+ Required,
18
+ parse_with_palet,
19
+ pAttr,
20
+ pAttrs,
21
+ )
15
22
  from auto_editor.utils.func import setup_tempdir
16
23
  from auto_editor.utils.log import Log
17
24
  from auto_editor.utils.types import frame_rate
@@ -57,6 +64,8 @@ def levels_options(parser: ArgumentParser) -> ArgumentParser:
57
64
 
58
65
 
59
66
  def print_arr(arr: NDArray) -> None:
67
+ print("")
68
+ print("@start")
60
69
  if arr.dtype == np.float64:
61
70
  for a in arr:
62
71
  sys.stdout.write(f"{a:.20f}\n")
@@ -66,6 +75,8 @@ def print_arr(arr: NDArray) -> None:
66
75
  else:
67
76
  for a in arr:
68
77
  sys.stdout.write(f"{a}\n")
78
+ sys.stdout.flush()
79
+ print("")
69
80
 
70
81
 
71
82
  def main(sys_args: list[str] = sys.argv[1:]) -> None:
@@ -92,37 +103,42 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
92
103
  else:
93
104
  method, attrs = args.edit, ""
94
105
 
95
- for src in sources:
96
- print("")
97
- print("@start")
106
+ audio_builder = pAttrs("audio", pAttr("stream", 0, is_nat))
107
+ motion_builder = pAttrs(
108
+ "motion",
109
+ pAttr("stream", 0, is_nat),
110
+ pAttr("blur", 9, is_nat),
111
+ pAttr("width", 400, is_nat1),
112
+ )
113
+ subtitle_builder = pAttrs(
114
+ "subtitle",
115
+ pAttr("pattern", Required, is_str),
116
+ pAttr("stream", 0, is_nat),
117
+ pAttr("ignore-case", False, is_bool),
118
+ pAttr("max-count", None, orc(is_nat, is_void)),
119
+ )
98
120
 
99
- levels = Levels(ensure, src, tb, bar, temp, log)
121
+ builder_map = {
122
+ "audio": audio_builder,
123
+ "motion": motion_builder,
124
+ "subtitle": subtitle_builder,
125
+ }
100
126
 
127
+ for src in sources:
101
128
  if method in builder_map:
102
- builder = builder_map[method]
103
-
104
129
  try:
105
- obj = parse_with_palet(attrs, builder, env)
130
+ obj = parse_with_palet(attrs, builder_map[method], env)
106
131
  except ParserError as e:
107
132
  log.error(e)
108
133
 
109
- if "threshold" in obj:
110
- del obj["threshold"]
111
-
134
+ levels = Levels(ensure, src, tb, bar, temp, log)
112
135
  try:
113
136
  if method == "audio":
114
- print_arr(levels.audio(obj["stream"]))
137
+ print_arr(levels.audio(**obj))
115
138
  elif method == "motion":
116
- print_arr(levels.motion(obj["stream"], obj["blur"], obj["width"]))
139
+ print_arr(levels.motion(**obj))
117
140
  elif method == "subtitle":
118
- print_arr(
119
- levels.subtitle(
120
- obj["pattern"],
121
- obj["stream"],
122
- obj["ignore_case"],
123
- obj["max_count"],
124
- )
125
- )
141
+ print_arr(levels.subtitle(**obj))
126
142
  elif method == "none":
127
143
  print_arr(levels.none())
128
144
  elif method == "all/e":
@@ -132,8 +148,6 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
132
148
  except LevelError as e:
133
149
  log.error(e)
134
150
 
135
- sys.stdout.flush()
136
- print("")
137
151
  log.cleanup()
138
152
 
139
153
 
@@ -73,7 +73,7 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
73
73
  sources = [initFileInfo(path, log) for path in args.input]
74
74
  src = sources[0]
75
75
  tb = src.get_fps() if args.timebase is None else args.timebase
76
- bar = Bar("none")
76
+ bar = Bar("modern")
77
77
  ensure = Ensure(ffmpeg, bar, src.get_sr(), temp, log)
78
78
  env["timebase"] = tb
79
79
  env["@levels"] = Levels(ensure, src, tb, bar, temp, log)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-editor
3
- Version: 24.27.1
3
+ Version: 24.29.1
4
4
  Summary: Auto-Editor: Effort free video editing!
5
5
  Author-email: WyattBlue <wyattblue@auto-editor.com>
6
6
  License: Unlicense
@@ -11,7 +11,7 @@ Keywords: video,audio,media,editor,editing,processing,nonlinear,automatic,silenc
11
11
  Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: numpy >=1.22.0
14
+ Requires-Dist: numpy >=1.23.0
15
15
  Requires-Dist: pyav ==12.2.*
16
16
  Requires-Dist: ae-ffmpeg ==1.2.*
17
17
 
@@ -182,6 +182,3 @@ auto-editor --margin --help
182
182
 
183
183
  ## Copyright
184
184
  Auto-Editor is under the [Public Domain](https://github.com/WyattBlue/auto-editor/blob/master/LICENSE) and includes all directories besides the ones listed below. Auto-Editor was created by [these people.](https://auto-editor.com/blog/thank-you-early-testers)
185
-
186
- ae-ffmpeg is under the [LGPLv3 License](https://github.com/WyattBlue/auto-editor/blob/master/ae-ffmpeg/LICENSE.txt). The ffmpeg and ffprobe programs were created by the FFmpeg team.
187
-
@@ -1,13 +1,10 @@
1
- ae-ffmpeg/setup.py,sha256=HeORyrs8OyJ32lSnMaIhI2B7U1lkk3QP6wOjxpoiF3Y,1891
2
- ae-ffmpeg/ae_ffmpeg/__init__.py,sha256=Fd2YsCINa0dB3tf9VVKDTPT9P6MDH-ve3RT2pqArImI,453
3
- ae-ffmpeg/ae_ffmpeg/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- auto_editor/__init__.py,sha256=x3FkUVgQK07IAJYRgjIfWDxsjSINz0ig_JBv3pG5gas,43
1
+ auto_editor/__init__.py,sha256=wTE-3oMo3sa9_Thlm0qCCBVJbBZIZdsyvXop8tJpD_s,43
5
2
  auto_editor/__main__.py,sha256=nkb8N_bxF_qld53LWo4c6Y0n9NDRdsPfANpVF1RD1cQ,9863
6
- auto_editor/analyze.py,sha256=NVDARF7ZxNLWMJ89HsuqCS1TMSeYhf2e5C66cQUTKrk,13200
3
+ auto_editor/analyze.py,sha256=6u-J0D3tucbX1rgsc7i8MqiKSWEtSdIiyqHUeWy0JyQ,11393
7
4
  auto_editor/edit.py,sha256=EEB9PJdGpXh5b1vDdSnsEtI8aJEcF64-SNZjFRg6Nrs,11484
8
5
  auto_editor/ffwrapper.py,sha256=jga7-HbQnC4w21qZk4aY4kwLT7UPqkGn6NJPFM5Qssc,7811
9
6
  auto_editor/help.py,sha256=BFiP7vBz42TUzum4-zaQIrV1OY7kHeN0pe0MPE0T5xw,7997
10
- auto_editor/make_layers.py,sha256=P49tkQ2td0s6-IPWpnM9iFlyVV-KckLK4Y9xdxrRyhk,9613
7
+ auto_editor/make_layers.py,sha256=g4NUlxiguZ7_XmLx7pd7BAk8JjYpVneVgTQN3iku7VI,9018
11
8
  auto_editor/output.py,sha256=5_4HtSkd6Lwv2ATEwLKJuXL1yBGScWAPLxvh_nHrBA4,8101
12
9
  auto_editor/preview.py,sha256=fo2BDIkvl96q_ssq8AAu1tl6FN_j23h8987aDPSmjDs,3094
13
10
  auto_editor/timeline.py,sha256=JwcS-8AS5vsoTL_m03aosYijScQef4AGa2lyutQ8wbI,7069
@@ -23,9 +20,9 @@ auto_editor/formats/utils.py,sha256=GIZw28WHuCIaZ_zMI0v6Kxbq0QaIpbLsdSegdYwQxQ8,
23
20
  auto_editor/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
21
  auto_editor/lang/json.py,sha256=OsNcYlfEj8ZLlzLK-gkLcrCCKI7mJz9rpe-6XLr4f9U,9231
25
22
  auto_editor/lang/libmath.py,sha256=z33A161Oe6vYYK7R6pgYjdZZe63dQkN38Qf36TL3prg,847
26
- auto_editor/lang/palet.py,sha256=9eQwirwwejf0qrXxXqwETEFv4MQ98jUs-0X_wHMaxRg,59027
23
+ auto_editor/lang/palet.py,sha256=ZlQsKS5TEUDDiPQSXMSXcdoYYibcv6nwwe372IVdQkw,59839
27
24
  auto_editor/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- auto_editor/lib/contracts.py,sha256=CTay7wMWnMSbTD1QAwE-b6yvIcSPvkpxkFQRXoJiqZE,7258
25
+ auto_editor/lib/contracts.py,sha256=HxWWMU63_6nKsdIXCDKnlWaYzS0dpN-H3uwCuzZALaM,7353
29
26
  auto_editor/lib/data_structs.py,sha256=EXNcdMsdmZxMRlpbXmIbRoC-YfGzvPZi7EdBQGwvpP4,6887
30
27
  auto_editor/lib/err.py,sha256=UlszQJdzMZwkbT8x3sY4GkCV_5x9yrd6uVVUzvA8iiI,35
31
28
  auto_editor/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -35,9 +32,9 @@ auto_editor/render/video.py,sha256=E1snevFC4mMk_S_oDquJPKyElQfdDodO7EJEQ22JJF8,1
35
32
  auto_editor/subcommands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
33
  auto_editor/subcommands/desc.py,sha256=GDrKJYiHMaeTrplZAceXl1JwoqD78XsV2_5lc0Xd7po,869
37
34
  auto_editor/subcommands/info.py,sha256=7Sgt9WR0rWxe7juCRKseMxW6gKv3z3voqFcL8-MOVVM,6927
38
- auto_editor/subcommands/levels.py,sha256=qSEXSkYPOCmr4_VZ1xAwtCZzaBOe8wXY0T-orN3Qg_A,4006
35
+ auto_editor/subcommands/levels.py,sha256=F-hhbRSSQBEo3w57Tu70ZVIgnWL1wV9LH5JkBEKv_SM,4348
39
36
  auto_editor/subcommands/palet.py,sha256=tbQoRWoT4jR3yu0etGApfprM-oQgXIjC-rIY-QG3nM0,655
40
- auto_editor/subcommands/repl.py,sha256=nbCVIyFwG3HRtGr8q-yLtASVMbMKDzAbn5vqA6RC9bk,3722
37
+ auto_editor/subcommands/repl.py,sha256=7Ex2CBhuLNL6U4jVqt55taDOWQMPyYqNicZaGJMxvvA,3724
41
38
  auto_editor/subcommands/subdump.py,sha256=2rIaGVtWWMBbPJ0NouPD7fY5lhk0QD_XKE_4EnAeWPw,892
42
39
  auto_editor/subcommands/test.py,sha256=UcpJp-PMcoUyz6LDD4y2V6EQ9w1ed66fPZr4GpzJReg,25050
43
40
  auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -50,9 +47,9 @@ auto_editor/utils/func.py,sha256=H38xO6Wxg1TZILVrx-nCowCzj_mqBUtJuOFp4DV3Hsc,484
50
47
  auto_editor/utils/log.py,sha256=ry-C92PRkJ-c8PQYIs1imk1qigDYfsCoLBYK6CQSP7I,2844
51
48
  auto_editor/utils/subtitle_tools.py,sha256=TjjVPiT8bWzZJcrZjF7ddpgfIsVkLE4LyxXzBswHAGU,693
52
49
  auto_editor/utils/types.py,sha256=zWbU_VkcdP4yHHzKyaSiXu560n5U53i0x5SPkUDsCZU,11570
53
- auto_editor-24.27.1.dist-info/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
54
- auto_editor-24.27.1.dist-info/METADATA,sha256=GBxzQhnfrlu3KJ89iT7RZ04nvEhUeJfAOzPl6OxtS6A,6322
55
- auto_editor-24.27.1.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
56
- auto_editor-24.27.1.dist-info/entry_points.txt,sha256=-H7zdTw4MqnAcwrN5xTNkGIhzZtJMxS9r6lTMeR9-aA,240
57
- auto_editor-24.27.1.dist-info/top_level.txt,sha256=xwV1JV1ZeRmlH9VeBRZXgXtWHpWSD4w1mY5II56D3ns,22
58
- auto_editor-24.27.1.dist-info/RECORD,,
50
+ auto_editor-24.29.1.dist-info/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
51
+ auto_editor-24.29.1.dist-info/METADATA,sha256=2iGS5WK7jDFAhWvhPztV6gwDANq0QMvxQ134hCDS3E0,6138
52
+ auto_editor-24.29.1.dist-info/WHEEL,sha256=-oYQCr74JF3a37z2nRlQays_SX2MqOANoqVjBBAP2yE,91
53
+ auto_editor-24.29.1.dist-info/entry_points.txt,sha256=-H7zdTw4MqnAcwrN5xTNkGIhzZtJMxS9r6lTMeR9-aA,240
54
+ auto_editor-24.29.1.dist-info/top_level.txt,sha256=ky1HUkqq9i034c4CUU_0wBw0xZsxxyGEak1eTbdvpyA,12
55
+ auto_editor-24.29.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.2.0)
2
+ Generator: setuptools (71.0.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,16 +0,0 @@
1
- __version__ = "1.2.0"
2
-
3
- import os.path
4
- from platform import machine, system
5
-
6
-
7
- def get_path() -> str:
8
- _os = system()
9
- _arch = machine().lower()
10
- _interdir = _os if _os != "Darwin" else f"{_os}-{_arch}"
11
- program = "ffmpeg.exe" if _os == "Windows" else "ffmpeg"
12
-
13
- dirpath = os.path.dirname(os.path.realpath(__file__))
14
- file_path = os.path.join(dirpath, _interdir, program)
15
-
16
- return file_path if os.path.isfile(file_path) else "ffmpeg"
File without changes
ae-ffmpeg/setup.py DELETED
@@ -1,65 +0,0 @@
1
- import re
2
-
3
- from setuptools import find_packages, setup
4
-
5
-
6
- def pip_version():
7
- with open("ae_ffmpeg/__init__.py") as f:
8
- version_content = f.read()
9
-
10
- version_match = re.search(
11
- r"^__version__ = ['\"]([^'\"]*)['\"]", version_content, re.M
12
- )
13
-
14
- if version_match:
15
- return version_match.group(1)
16
-
17
- raise ValueError("Unable to find version string.")
18
-
19
-
20
- with open("README.md") as f:
21
- long_description = f.read()
22
-
23
- setup(
24
- name="ae-ffmpeg",
25
- version=pip_version(),
26
- description="Static FFmpeg binaries for Auto-Editor",
27
- long_description=long_description,
28
- long_description_content_type="text/markdown",
29
- license="LGPLv3",
30
- url="https://auto-editor.com",
31
- project_urls={
32
- "Bug Tracker": "https://github.com/WyattBlue/auto-editor/issues",
33
- "Source Code": "https://github.com/WyattBlue/auto-editor",
34
- },
35
- author="WyattBlue",
36
- author_email="wyattblue@auto-editor.com",
37
- keywords="video audio media",
38
- packages=find_packages(),
39
- package_data={
40
- "ae_ffmpeg": [
41
- "LICENSE.txt",
42
- "Windows/ffmpeg.exe",
43
- "Windows/ffprobe.exe",
44
- "Windows/libopenh264.dll",
45
- "Darwin-x86_64/ffmpeg",
46
- "Darwin-x86_64/ffprobe",
47
- "Darwin-arm64/ffmpeg",
48
- "Darwin-arm64/ffprobe",
49
- "py.typed",
50
- ],
51
- },
52
- include_package_data=True,
53
- zip_safe=False,
54
- python_requires=">=3.8",
55
- classifiers=[
56
- "Topic :: Multimedia :: Sound/Audio",
57
- "Topic :: Multimedia :: Video",
58
- "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
59
- "Intended Audience :: Developers",
60
- "Operating System :: MacOS :: MacOS X",
61
- "Operating System :: Microsoft :: Windows",
62
- "Development Status :: 5 - Production/Stable",
63
- "Programming Language :: Python :: 3",
64
- ],
65
- )