auto-editor 24.25.1__tar.gz → 24.27.1__tar.gz

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.
Files changed (64) hide show
  1. {auto_editor-24.25.1/auto_editor.egg-info → auto_editor-24.27.1}/PKG-INFO +2 -2
  2. auto_editor-24.27.1/auto_editor/__init__.py +2 -0
  3. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/__main__.py +4 -4
  4. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/edit.py +3 -3
  5. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/ffwrapper.py +6 -2
  6. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/formats/fcp7.py +2 -2
  7. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/formats/shotcut.py +1 -2
  8. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/make_layers.py +1 -1
  9. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/output.py +39 -4
  10. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/render/video.py +9 -9
  11. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/levels.py +1 -1
  12. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/repl.py +1 -1
  13. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/test.py +12 -5
  14. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/validate_input.py +9 -12
  15. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/vanparse.py +3 -3
  16. {auto_editor-24.25.1 → auto_editor-24.27.1/auto_editor.egg-info}/PKG-INFO +2 -2
  17. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor.egg-info/requires.txt +1 -1
  18. {auto_editor-24.25.1 → auto_editor-24.27.1}/pyproject.toml +1 -1
  19. auto_editor-24.25.1/auto_editor/__init__.py +0 -2
  20. {auto_editor-24.25.1 → auto_editor-24.27.1}/LICENSE +0 -0
  21. {auto_editor-24.25.1 → auto_editor-24.27.1}/README.md +0 -0
  22. {auto_editor-24.25.1 → auto_editor-24.27.1}/ae-ffmpeg/ae_ffmpeg/__init__.py +0 -0
  23. {auto_editor-24.25.1 → auto_editor-24.27.1}/ae-ffmpeg/ae_ffmpeg/py.typed +0 -0
  24. {auto_editor-24.25.1 → auto_editor-24.27.1}/ae-ffmpeg/setup.py +0 -0
  25. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/analyze.py +0 -0
  26. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/formats/__init__.py +0 -0
  27. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/formats/fcp11.py +0 -0
  28. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/formats/json.py +0 -0
  29. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/formats/utils.py +0 -0
  30. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/help.py +0 -0
  31. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lang/__init__.py +0 -0
  32. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lang/json.py +0 -0
  33. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lang/libmath.py +0 -0
  34. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lang/palet.py +0 -0
  35. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lib/__init__.py +0 -0
  36. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lib/contracts.py +0 -0
  37. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lib/data_structs.py +0 -0
  38. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/lib/err.py +0 -0
  39. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/preview.py +0 -0
  40. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/render/__init__.py +0 -0
  41. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/render/audio.py +0 -0
  42. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/render/subtitle.py +0 -0
  43. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/__init__.py +0 -0
  44. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/desc.py +0 -0
  45. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/info.py +0 -0
  46. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/palet.py +0 -0
  47. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/subcommands/subdump.py +0 -0
  48. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/timeline.py +0 -0
  49. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/__init__.py +0 -0
  50. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/bar.py +0 -0
  51. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/chunks.py +0 -0
  52. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/cmdkw.py +0 -0
  53. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/container.py +0 -0
  54. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/encoder.py +0 -0
  55. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/func.py +0 -0
  56. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/log.py +0 -0
  57. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/subtitle_tools.py +0 -0
  58. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/utils/types.py +0 -0
  59. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor/wavfile.py +0 -0
  60. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor.egg-info/SOURCES.txt +0 -0
  61. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor.egg-info/dependency_links.txt +0 -0
  62. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor.egg-info/entry_points.txt +0 -0
  63. {auto_editor-24.25.1 → auto_editor-24.27.1}/auto_editor.egg-info/top_level.txt +0 -0
  64. {auto_editor-24.25.1 → auto_editor-24.27.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-editor
3
- Version: 24.25.1
3
+ Version: 24.27.1
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.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: numpy>=1.22.0
15
- Requires-Dist: pyav==12.1.0
15
+ Requires-Dist: pyav==12.2.*
16
16
  Requires-Dist: ae-ffmpeg==1.2.*
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,2 @@
1
+ __version__ = "24.27.1"
2
+ version = "24w27a"
@@ -311,10 +311,10 @@ def main() -> None:
311
311
 
312
312
  import av
313
313
 
314
- print(f"Python Version: {plat.python_version()}")
315
- print(f"Platform: {plat.system()} {plat.release()} {plat.machine().lower()}")
316
- print(f"PyAV Version: {av.__version__}")
317
- print(f"Auto-Editor Version: {auto_editor.version}")
314
+ print(f"OS: {plat.system()} {plat.release()} {plat.machine().lower()}")
315
+ print(f"Python: {plat.python_version()}")
316
+ print(f"PyAV: {av.__version__}")
317
+ print(f"Auto-Editor: {auto_editor.version}")
318
318
  return
319
319
 
320
320
  if not args.input:
@@ -160,7 +160,7 @@ def edit_media(
160
160
  if path_ext == ".xml":
161
161
  from auto_editor.formats.fcp7 import fcp7_read_xml
162
162
 
163
- tl = fcp7_read_xml(paths[0], ffmpeg, log)
163
+ tl = fcp7_read_xml(paths[0], log)
164
164
  assert tl.src is not None
165
165
  sources: list[FileInfo] = [tl.src]
166
166
  src: FileInfo | None = tl.src
@@ -168,7 +168,7 @@ def edit_media(
168
168
  elif path_ext == ".mlt":
169
169
  from auto_editor.formats.shotcut import shotcut_read_mlt
170
170
 
171
- tl = shotcut_read_mlt(paths[0], ffmpeg, log)
171
+ tl = shotcut_read_mlt(paths[0], log)
172
172
  assert tl.src is not None
173
173
  sources = [tl.src]
174
174
  src = tl.src
@@ -209,7 +209,7 @@ def edit_media(
209
209
  else:
210
210
  samplerate = args.sample_rate
211
211
 
212
- ensure = Ensure(ffmpeg, samplerate, temp, log)
212
+ ensure = Ensure(ffmpeg, bar, samplerate, temp, log)
213
213
 
214
214
  if tl is None:
215
215
  tl = make_timeline(sources, ensure, args, samplerate, bar, temp, log)
@@ -11,6 +11,8 @@ from shutil import which
11
11
  from subprocess import PIPE, Popen
12
12
  from typing import Any
13
13
 
14
+ import av
15
+
14
16
  from auto_editor.utils.func import get_stdout
15
17
  from auto_editor.utils.log import Log
16
18
 
@@ -190,10 +192,12 @@ class FileInfo:
190
192
 
191
193
 
192
194
  def initFileInfo(path: str, log: Log) -> FileInfo:
193
- import av
194
-
195
195
  try:
196
196
  cont = av.open(path, "r")
197
+ except av.error.FileNotFoundError:
198
+ log.error(f"Could not find '{path}'")
199
+ except av.error.IsADirectoryError:
200
+ log.error(f"Expected a media file, but got a directory: {path}")
197
201
  except av.error.InvalidDataError:
198
202
  log.error(f"Invalid data when processing: {path}")
199
203
 
@@ -7,7 +7,7 @@ from math import ceil
7
7
  from typing import TYPE_CHECKING
8
8
  from xml.etree.ElementTree import Element
9
9
 
10
- from auto_editor.ffwrapper import FFmpeg, FileInfo, initFileInfo
10
+ from auto_editor.ffwrapper import FileInfo, initFileInfo
11
11
  from auto_editor.timeline import ASpace, TlAudio, TlVideo, VSpace, v3
12
12
 
13
13
  from .utils import Validator, show
@@ -177,7 +177,7 @@ def read_filters(clipitem: Element, log: Log) -> float:
177
177
  return 1.0
178
178
 
179
179
 
180
- def fcp7_read_xml(path: str, ffmpeg: FFmpeg, log: Log) -> v3:
180
+ def fcp7_read_xml(path: str, log: Log) -> v3:
181
181
  def xml_bool(val: str) -> bool:
182
182
  if val == "TRUE":
183
183
  return True
@@ -9,7 +9,6 @@ from auto_editor.utils.func import aspect_ratio, to_timecode
9
9
  if TYPE_CHECKING:
10
10
  from collections.abc import Sequence
11
11
 
12
- from auto_editor.ffwrapper import FFmpeg
13
12
  from auto_editor.timeline import TlAudio, TlVideo
14
13
  from auto_editor.utils.log import Log
15
14
 
@@ -22,7 +21,7 @@ https://mltframework.org/docs/mltxml/
22
21
  """
23
22
 
24
23
 
25
- def shotcut_read_mlt(path: str, ffmpeg: FFmpeg, log: Log) -> v3:
24
+ def shotcut_read_mlt(path: str, log: Log) -> v3:
26
25
  raise NotImplementedError
27
26
 
28
27
 
@@ -38,7 +38,7 @@ def clipify(chunks: Chunks, src: FileInfo, start: int = 0) -> list[Clip]:
38
38
  clips: list[Clip] = []
39
39
  i = 0
40
40
  for chunk in chunks:
41
- if chunk[2] != 99999:
41
+ if chunk[2] > 0 and chunk[2] < 99999.0:
42
42
  dur = round((chunk[1] - chunk[0]) / chunk[2])
43
43
  if dur == 0:
44
44
  continue
@@ -4,7 +4,11 @@ import os.path
4
4
  from dataclasses import dataclass, field
5
5
  from fractions import Fraction
6
6
 
7
+ import av
8
+ from av.audio.resampler import AudioResampler
9
+
7
10
  from auto_editor.ffwrapper import FFmpeg, FileInfo
11
+ from auto_editor.utils.bar import Bar
8
12
  from auto_editor.utils.container import Container
9
13
  from auto_editor.utils.log import Log
10
14
  from auto_editor.utils.types import Args
@@ -13,6 +17,7 @@ from auto_editor.utils.types import Args
13
17
  @dataclass(slots=True)
14
18
  class Ensure:
15
19
  _ffmpeg: FFmpeg
20
+ _bar: Bar
16
21
  _sr: int
17
22
  temp: str
18
23
  log: Log
@@ -31,12 +36,42 @@ class Ensure:
31
36
  out_path = os.path.join(self.temp, f"{label:x}.wav")
32
37
 
33
38
  if first_time:
39
+ sample_rate = self._sr
40
+ bar = self._bar
34
41
  self.log.debug(f"Making external audio: {out_path}")
35
- self.log.conwrite("Extracting audio")
36
42
 
37
- cmd = ["-i", f"{src.path}", "-map", f"0:a:{stream}"]
38
- cmd += ["-ac", "2", "-ar", f"{self._sr}", "-rf64", "always", out_path]
39
- self._ffmpeg.run(cmd)
43
+ in_container = av.open(src.path, "r")
44
+ out_container = av.open(
45
+ out_path, "w", format="wav", options={"rf64": "always"}
46
+ )
47
+ astream = in_container.streams.audio[stream]
48
+
49
+ if astream.duration is None or astream.time_base is None:
50
+ dur = 1
51
+ else:
52
+ dur = int(astream.duration * astream.time_base)
53
+
54
+ bar.start(dur, "Extracting audio")
55
+
56
+ # PyAV always uses "stereo" layout, which is what we want.
57
+ output_astream = out_container.add_stream("pcm_s16le", rate=sample_rate)
58
+ assert isinstance(output_astream, av.audio.stream.AudioStream)
59
+
60
+ resampler = AudioResampler(format="s16", layout="stereo", rate=sample_rate) # type: ignore
61
+ for i, frame in enumerate(in_container.decode(astream)):
62
+ if i % 1500 == 0:
63
+ bar.tick(0 if frame.time is None else frame.time)
64
+
65
+ for new_frame in resampler.resample(frame):
66
+ for packet in output_astream.encode(new_frame):
67
+ out_container.mux_one(packet)
68
+
69
+ for packet in output_astream.encode():
70
+ out_container.mux_one(packet)
71
+
72
+ out_container.close()
73
+ in_container.close()
74
+ bar.end()
40
75
 
41
76
  return out_path
42
77
 
@@ -103,8 +103,8 @@ def make_image_cache(tl: v3) -> dict[tuple[FileInfo, int], np.ndarray]:
103
103
  graph.add("scale", f"{obj.width}:-1"),
104
104
  graph.add("buffersink"),
105
105
  )
106
- graph.push(frame)
107
- frame = graph.pull()
106
+ graph.vpush(frame)
107
+ frame = graph.vpull()
108
108
  img_cache[(obj.src, obj.width)] = frame.to_ndarray(
109
109
  format="rgb24"
110
110
  )
@@ -122,7 +122,7 @@ def render_av(
122
122
  log: Log,
123
123
  ) -> tuple[str, bool]:
124
124
  src = tl.src
125
- cns: dict[FileInfo, av.InputContainer] = {}
125
+ cns: dict[FileInfo, av.container.InputContainer] = {}
126
126
  decoders: dict[FileInfo, Iterator[av.VideoFrame]] = {}
127
127
  seek_cost: dict[FileInfo, int] = {}
128
128
  tous: dict[FileInfo, int] = {}
@@ -302,8 +302,8 @@ def render_av(
302
302
  graph.add("pad", f"{width}:{height}:-1:-1:color={bg}"),
303
303
  graph.add("buffersink"),
304
304
  )
305
- graph.push(frame)
306
- frame = graph.pull()
305
+ graph.vpush(frame)
306
+ frame = graph.vpull()
307
307
  elif isinstance(obj, TlRect):
308
308
  graph = av.filter.Graph()
309
309
  x, y = apply_anchor(obj.x, obj.y, obj.width, obj.height, obj.anchor)
@@ -315,8 +315,8 @@ def render_av(
315
315
  ),
316
316
  graph.add("buffersink"),
317
317
  )
318
- graph.push(frame)
319
- frame = graph.pull()
318
+ graph.vpush(frame)
319
+ frame = graph.vpull()
320
320
  elif isinstance(obj, TlImage):
321
321
  img = img_cache[(obj.src, obj.width)]
322
322
  array = frame.to_ndarray(format="rgb24")
@@ -355,8 +355,8 @@ def render_av(
355
355
  frame = av.VideoFrame.from_ndarray(array, format="rgb24")
356
356
 
357
357
  if scale_graph is not None and frame.width != target_width:
358
- scale_graph.push(frame)
359
- frame = scale_graph.pull()
358
+ scale_graph.vpush(frame)
359
+ frame = scale_graph.vpull()
360
360
 
361
361
  if frame.format.name != target_pix_fmt:
362
362
  frame = frame.reformat(format=target_pix_fmt)
@@ -85,7 +85,7 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
85
85
  src = sources[0]
86
86
 
87
87
  tb = src.get_fps() if args.timebase is None else args.timebase
88
- ensure = Ensure(ffmpeg, src.get_sr(), temp, log)
88
+ ensure = Ensure(ffmpeg, bar, src.get_sr(), temp, log)
89
89
 
90
90
  if ":" in args.edit:
91
91
  method, attrs = args.edit.split(":", 1)
@@ -73,8 +73,8 @@ 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
- ensure = Ensure(ffmpeg, src.get_sr(), temp, log)
77
76
  bar = Bar("none")
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)
80
80
  env["@filesetup"] = FileSetup(src, ensure, strict, tb, bar, temp, log)
@@ -340,11 +340,19 @@ def main(sys_args: list[str] | None = None):
340
340
  def track_tests():
341
341
  return run.main(["resources/multi-track.mov"], ["--keep_tracks_seperate"])
342
342
 
343
- def json_tests():
343
+ def export_json_tests():
344
344
  out = run.main(["example.mp4"], ["--export_as_json"])
345
345
  out2 = run.main([out], [])
346
346
  return out, out2
347
347
 
348
+ def import_v1_tests():
349
+ with open("v1.json", "w") as file:
350
+ file.write(
351
+ """{"version": "1", "source": "example.mp4", "chunks": [ [0, 26, 1.0], [26, 34, 0] ]}"""
352
+ )
353
+
354
+ return run.main(["v1.json"], [])
355
+
348
356
  def premiere_named_export():
349
357
  run.main(["example.mp4"], ["--export", 'premiere:name="Foo Bar"'])
350
358
 
@@ -524,9 +532,7 @@ def main(sys_args: list[str] | None = None):
524
532
  # Issue 280
525
533
  def SAR():
526
534
  out = run.main(["resources/SAR-2by3.mp4"], [])
527
-
528
- # It's working, PyAV just can't detect the changes.
529
- # assert checker.check(out).videos[0].sar == Fraction(2, 3)
535
+ assert checker.check(out).videos[0].sar == Fraction(2, 3)
530
536
 
531
537
  return out
532
538
 
@@ -711,7 +717,8 @@ def main(sys_args: list[str] | None = None):
711
717
  edit_positive_tests,
712
718
  audio_norm_f,
713
719
  audio_norm_ebu,
714
- json_tests,
720
+ export_json_tests,
721
+ import_v1_tests,
715
722
  high_speed_test,
716
723
  video_speed,
717
724
  multi_track_edit,
@@ -67,20 +67,17 @@ def download_video(my_input: str, args: Args, ffmpeg: FFmpeg, log: Log) -> str:
67
67
 
68
68
 
69
69
  def valid_input(inputs: list[str], ffmpeg: FFmpeg, args: Args, log: Log) -> list[str]:
70
- new_inputs = []
70
+ result = []
71
71
 
72
72
  for my_input in inputs:
73
- if os.path.isfile(my_input):
73
+ if my_input.startswith("http://") or my_input.startswith("https://"):
74
+ result.append(download_video(my_input, args, ffmpeg, log))
75
+ else:
74
76
  _, ext = os.path.splitext(my_input)
75
77
  if ext == "":
76
- log.error("File must have an extension.")
77
- new_inputs.append(my_input)
78
-
79
- elif my_input.startswith("http://") or my_input.startswith("https://"):
80
- new_inputs.append(download_video(my_input, args, ffmpeg, log))
81
- else:
82
- if os.path.isdir(my_input):
83
- log.error("Input must be a file or a URL, not a directory.")
84
- log.error(f"Could not find '{my_input}'")
78
+ if os.path.isdir(my_input):
79
+ log.error("Input must be a file or a URL, not a directory.")
80
+ log.error("Input file must have an extension.")
81
+ result.append(my_input)
85
82
 
86
- return new_inputs
83
+ return result
@@ -119,7 +119,7 @@ def to_key(op: Options | Required) -> str:
119
119
  return op.names[0][:2].replace("-", "") + op.names[0][2:].replace("-", "_")
120
120
 
121
121
 
122
- def print_option_help(program_name: str | None, ns_obj: T, option: Options) -> None:
122
+ def print_option_help(name: str | None, ns_obj: object, option: Options) -> None:
123
123
  text = StringIO()
124
124
  text.write(
125
125
  f" {', '.join(option.names)} {'' if option.metavar is None else option.metavar}\n\n"
@@ -145,8 +145,8 @@ def print_option_help(program_name: str | None, ns_obj: T, option: Options) -> N
145
145
 
146
146
  from auto_editor.help import data
147
147
 
148
- if program_name is not None and option.names[0] in data[program_name]:
149
- text.write(indent(data[program_name][option.names[0]], " ") + "\n")
148
+ if name is not None and option.names[0] in data[name]:
149
+ text.write(indent(data[name][option.names[0]], " ") + "\n")
150
150
  else:
151
151
  text.write(f" {option.help}\n\n")
152
152
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-editor
3
- Version: 24.25.1
3
+ Version: 24.27.1
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.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: numpy>=1.22.0
15
- Requires-Dist: pyav==12.1.0
15
+ Requires-Dist: pyav==12.2.*
16
16
  Requires-Dist: ae-ffmpeg==1.2.*
17
17
 
18
18
  <p align="center"><img src="https://auto-editor.com/img/auto-editor-banner.webp" title="Auto-Editor" width="700"></p>
@@ -1,3 +1,3 @@
1
1
  numpy>=1.22.0
2
- pyav==12.1.0
2
+ pyav==12.2.*
3
3
  ae-ffmpeg==1.2.*
@@ -10,7 +10,7 @@ authors = [{ name = "WyattBlue", email = "wyattblue@auto-editor.com" }]
10
10
  requires-python = ">=3.10"
11
11
  dependencies = [
12
12
  "numpy>=1.22.0",
13
- "pyav==12.1.0",
13
+ "pyav==12.2.*",
14
14
  "ae-ffmpeg==1.2.*",
15
15
  ]
16
16
  keywords = [
@@ -1,2 +0,0 @@
1
- __version__ = "24.25.1"
2
- version = "24w25a"
File without changes
File without changes
File without changes