auto-editor 28.1.0__py3-none-any.whl → 29.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.
Files changed (60) hide show
  1. auto_editor/__init__.py +3 -1
  2. auto_editor/__main__.py +31 -497
  3. auto_editor/cli.py +12 -0
  4. {auto_editor-28.1.0.dist-info → auto_editor-29.0.1.dist-info}/METADATA +5 -6
  5. auto_editor-29.0.1.dist-info/RECORD +9 -0
  6. auto_editor-29.0.1.dist-info/entry_points.txt +2 -0
  7. {auto_editor-28.1.0.dist-info → auto_editor-29.0.1.dist-info}/top_level.txt +0 -1
  8. auto_editor/analyze.py +0 -393
  9. auto_editor/cmds/__init__.py +0 -0
  10. auto_editor/cmds/cache.py +0 -69
  11. auto_editor/cmds/desc.py +0 -32
  12. auto_editor/cmds/info.py +0 -213
  13. auto_editor/cmds/levels.py +0 -199
  14. auto_editor/cmds/palet.py +0 -29
  15. auto_editor/cmds/repl.py +0 -113
  16. auto_editor/cmds/subdump.py +0 -72
  17. auto_editor/cmds/test.py +0 -816
  18. auto_editor/edit.py +0 -560
  19. auto_editor/exports/__init__.py +0 -0
  20. auto_editor/exports/fcp11.py +0 -195
  21. auto_editor/exports/fcp7.py +0 -313
  22. auto_editor/exports/json.py +0 -63
  23. auto_editor/exports/kdenlive.py +0 -322
  24. auto_editor/exports/shotcut.py +0 -147
  25. auto_editor/ffwrapper.py +0 -187
  26. auto_editor/help.py +0 -224
  27. auto_editor/imports/__init__.py +0 -0
  28. auto_editor/imports/fcp7.py +0 -275
  29. auto_editor/imports/json.py +0 -234
  30. auto_editor/json.py +0 -297
  31. auto_editor/lang/__init__.py +0 -0
  32. auto_editor/lang/libintrospection.py +0 -10
  33. auto_editor/lang/libmath.py +0 -23
  34. auto_editor/lang/palet.py +0 -724
  35. auto_editor/lang/stdenv.py +0 -1179
  36. auto_editor/lib/__init__.py +0 -0
  37. auto_editor/lib/contracts.py +0 -235
  38. auto_editor/lib/data_structs.py +0 -278
  39. auto_editor/lib/err.py +0 -2
  40. auto_editor/make_layers.py +0 -315
  41. auto_editor/preview.py +0 -93
  42. auto_editor/render/__init__.py +0 -0
  43. auto_editor/render/audio.py +0 -517
  44. auto_editor/render/subtitle.py +0 -205
  45. auto_editor/render/video.py +0 -307
  46. auto_editor/timeline.py +0 -331
  47. auto_editor/utils/__init__.py +0 -0
  48. auto_editor/utils/bar.py +0 -142
  49. auto_editor/utils/chunks.py +0 -2
  50. auto_editor/utils/cmdkw.py +0 -206
  51. auto_editor/utils/container.py +0 -101
  52. auto_editor/utils/func.py +0 -128
  53. auto_editor/utils/log.py +0 -126
  54. auto_editor/utils/types.py +0 -277
  55. auto_editor/vanparse.py +0 -313
  56. auto_editor-28.1.0.dist-info/RECORD +0 -57
  57. auto_editor-28.1.0.dist-info/entry_points.txt +0 -6
  58. docs/build.py +0 -70
  59. {auto_editor-28.1.0.dist-info → auto_editor-29.0.1.dist-info}/WHEEL +0 -0
  60. {auto_editor-28.1.0.dist-info → auto_editor-29.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,199 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
- from dataclasses import dataclass, field
5
- from fractions import Fraction
6
- from typing import TYPE_CHECKING
7
-
8
- import av
9
- import numpy as np
10
-
11
- from auto_editor.analyze import *
12
- from auto_editor.ffwrapper import FileInfo
13
- from auto_editor.lang.palet import env
14
- from auto_editor.lib.contracts import is_bool, is_nat, is_nat1, is_str, is_void, orc
15
- from auto_editor.utils.bar import initBar
16
- from auto_editor.utils.cmdkw import (
17
- ParserError,
18
- Required,
19
- parse_with_palet,
20
- pAttr,
21
- pAttrs,
22
- )
23
- from auto_editor.utils.log import Log
24
- from auto_editor.utils.types import frame_rate
25
- from auto_editor.vanparse import ArgumentParser
26
-
27
- if TYPE_CHECKING:
28
- from collections.abc import Iterator
29
- from fractions import Fraction
30
-
31
- from numpy.typing import NDArray
32
-
33
-
34
- @dataclass(slots=True)
35
- class LevelArgs:
36
- input: list[str] = field(default_factory=list)
37
- edit: str = "audio"
38
- timebase: Fraction | None = None
39
- no_cache: bool = False
40
- help: bool = False
41
-
42
-
43
- def levels_options(parser: ArgumentParser) -> ArgumentParser:
44
- parser.add_required("input", nargs="*")
45
- parser.add_argument(
46
- "--edit",
47
- metavar="METHOD:[ATTRS?]",
48
- help="Select the kind of detection to analyze with attributes",
49
- )
50
- parser.add_argument(
51
- "--timebase",
52
- "-tb",
53
- metavar="NUM",
54
- type=frame_rate,
55
- help="Set custom timebase",
56
- )
57
- parser.add_argument("--no-cache", flag=True)
58
- return parser
59
-
60
-
61
- def print_arr(arr: NDArray) -> None:
62
- print("")
63
- print("@start")
64
- if arr.dtype == np.bool_:
65
- for a in arr:
66
- sys.stdout.write(f"{1 if a else 0}\n")
67
- else:
68
- for a in arr:
69
- sys.stdout.write(f"{a}\n")
70
- sys.stdout.flush()
71
- print("")
72
-
73
-
74
- def print_arr_gen(arr: Iterator[float | np.float32]) -> None:
75
- print("")
76
- print("@start")
77
- for a in arr:
78
- print(f"{a}")
79
- print("")
80
-
81
-
82
- def main(sys_args: list[str] = sys.argv[1:]) -> None:
83
- parser = levels_options(ArgumentParser("levels"))
84
- args = parser.parse_args(LevelArgs, sys_args)
85
-
86
- bar = initBar("none")
87
- log = Log(quiet=True)
88
-
89
- sources = [FileInfo.init(path, log) for path in args.input]
90
- if len(sources) < 1:
91
- log.error("levels needs at least one input file")
92
-
93
- src = sources[0]
94
-
95
- tb = src.get_fps() if args.timebase is None else args.timebase
96
-
97
- if ":" in args.edit:
98
- method, attrs = args.edit.split(":", 1)
99
- else:
100
- method, attrs = args.edit, ""
101
-
102
- audio_builder = pAttrs("audio", pAttr("stream", 0, is_nat))
103
- motion_builder = pAttrs(
104
- "motion",
105
- pAttr("stream", 0, is_nat),
106
- pAttr("blur", 9, is_nat),
107
- pAttr("width", 400, is_nat1),
108
- )
109
- subtitle_builder = pAttrs(
110
- "subtitle",
111
- pAttr("pattern", Required, is_str),
112
- pAttr("stream", 0, is_nat),
113
- pAttr("ignore-case", False, is_bool),
114
- pAttr("max-count", None, orc(is_nat, is_void)),
115
- )
116
-
117
- builder_map = {
118
- "audio": audio_builder,
119
- "motion": motion_builder,
120
- "subtitle": subtitle_builder,
121
- }
122
-
123
- for src in sources:
124
- if method in builder_map:
125
- try:
126
- obj = parse_with_palet(attrs, builder_map[method], env)
127
- except ParserError as e:
128
- log.error(e)
129
-
130
- levels = initLevels(src, tb, bar, False, log)
131
- try:
132
- if method == "audio":
133
- if (
134
- not args.no_cache
135
- and (arr := levels.read_cache("audio", (obj["stream"],)))
136
- is not None
137
- ):
138
- print_arr(arr)
139
- else:
140
- container = av.open(src.path, "r")
141
- audio_stream = container.streams.audio[obj["stream"]]
142
-
143
- values = []
144
-
145
- def value_storing_generator() -> Iterator[np.float32]:
146
- for value in iter_audio(audio_stream, tb):
147
- values.append(value)
148
- yield value
149
-
150
- print_arr_gen(value_storing_generator())
151
- container.close()
152
-
153
- cache_array = np.array(values, dtype=np.float32)
154
- if not args.no_cache:
155
- levels.cache(cache_array, "audio", (obj["stream"],))
156
-
157
- elif method == "motion":
158
- mobj = (obj["stream"], obj["width"], obj["blur"])
159
- if (
160
- not args.no_cache
161
- and (arr := levels.read_cache("motion", mobj)) is not None
162
- ):
163
- print_arr(arr)
164
- else:
165
- container = av.open(src.path, "r")
166
- video_stream = container.streams.video[obj["stream"]]
167
-
168
- values = []
169
-
170
- def value_storing_generator() -> Iterator[np.float32]:
171
- for value in iter_motion(
172
- video_stream, tb, obj["blur"], obj["width"]
173
- ):
174
- values.append(value)
175
- yield value
176
-
177
- print_arr_gen(value_storing_generator())
178
- container.close()
179
-
180
- cache_array = np.array(values, dtype=np.float32)
181
- if not args.no_cache:
182
- levels.cache(cache_array, "motion", mobj)
183
-
184
- elif method == "subtitle":
185
- print_arr(levels.subtitle(**obj))
186
- elif method == "none":
187
- print_arr(levels.none())
188
- elif method == "all/e":
189
- print_arr(levels.all())
190
- else:
191
- log.error(f"Method: {method} not supported")
192
- except LevelError as e:
193
- log.error(e)
194
-
195
- log.cleanup()
196
-
197
-
198
- if __name__ == "__main__":
199
- main()
auto_editor/cmds/palet.py DELETED
@@ -1,29 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
-
5
- from auto_editor.lang.palet import Lexer, Parser, env, interpret
6
- from auto_editor.lang.stdenv import make_standard_env
7
- from auto_editor.lib.err import MyError
8
-
9
-
10
- def main(sys_args: list[str] = sys.argv[1:]) -> None:
11
- if sys_args:
12
- with open(sys_args[0], encoding="utf-8", errors="ignore") as file:
13
- program_text = file.read()
14
-
15
- env.update(make_standard_env())
16
- try:
17
- interpret(env, Parser(Lexer(sys_args[0], program_text)))
18
- except (MyError, ZeroDivisionError) as e:
19
- sys.stderr.write(f"error: {e}\n")
20
- sys.exit(1)
21
-
22
- else:
23
- from .repl import main
24
-
25
- main(sys_args)
26
-
27
-
28
- if __name__ == "__main__":
29
- main()
auto_editor/cmds/repl.py DELETED
@@ -1,113 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
- from dataclasses import dataclass, field
5
- from fractions import Fraction
6
- from os import environ
7
-
8
- import auto_editor
9
- from auto_editor.analyze import initLevels
10
- from auto_editor.ffwrapper import FileInfo
11
- from auto_editor.lang.palet import ClosingError, Lexer, Parser, env, interpret
12
- from auto_editor.lang.stdenv import make_standard_env
13
- from auto_editor.lib.data_structs import print_str
14
- from auto_editor.lib.err import MyError
15
- from auto_editor.utils.bar import initBar
16
- from auto_editor.utils.log import Log
17
- from auto_editor.utils.types import frame_rate
18
- from auto_editor.vanparse import ArgumentParser
19
-
20
- try:
21
- import readline # noqa
22
- except ImportError:
23
- pass
24
-
25
-
26
- @dataclass(slots=True)
27
- class REPL_Args:
28
- input: list[str] = field(default_factory=list)
29
- debug_parser: bool = False
30
- timebase: Fraction | None = None
31
- ffmpeg_location: str | None = None
32
- my_ffmpeg: bool = False
33
- temp_dir: str | None = None
34
- help: bool = False
35
-
36
-
37
- def repl_options(parser: ArgumentParser) -> ArgumentParser:
38
- parser.add_required("input", nargs="*")
39
- parser.add_argument(
40
- "--debug-parser",
41
- flag=True,
42
- help="Print parser value",
43
- )
44
- parser.add_argument(
45
- "--timebase",
46
- "-tb",
47
- metavar="NUM",
48
- type=frame_rate,
49
- help="Set custom timebase",
50
- )
51
- return parser
52
-
53
-
54
- def main(sys_args: list[str] = sys.argv[1:]) -> None:
55
- args = repl_options(ArgumentParser(None)).parse_args(REPL_Args, sys_args)
56
-
57
- if args.input:
58
- log = Log(quiet=True)
59
- sources = [FileInfo.init(path, log) for path in args.input]
60
- src = sources[0]
61
- tb = src.get_fps() if args.timebase is None else args.timebase
62
- env["timebase"] = tb
63
- env["@levels"] = initLevels(src, tb, initBar("modern"), False, log)
64
-
65
- env.update(make_standard_env())
66
- print(f"Auto-Editor {auto_editor.__version__}")
67
- text = None
68
-
69
- no_color = bool(environ.get("NO_COLOR") or environ.get("AV_LOG_FORCE_NOCOLOR"))
70
- if no_color:
71
- bold_pink = bold_red = reset = ""
72
- else:
73
- bold_pink = "\033[1;95m"
74
- bold_red = "\033[1;31m"
75
- reset = "\033[0m"
76
-
77
- try:
78
- while True:
79
- try:
80
- if text is None:
81
- text = input(f"{bold_pink}>{reset} ")
82
- else:
83
- text += "\n" + input(" ")
84
- except KeyboardInterrupt as e:
85
- if text is None:
86
- raise e
87
- text = None
88
- print("")
89
- continue
90
-
91
- try:
92
- parser = Parser(Lexer("repl", text))
93
- if args.debug_parser:
94
- print(f"parser: {parser}")
95
-
96
- for result in interpret(env, parser):
97
- if result is not None:
98
- sys.stdout.write(f"{print_str(result)}\n")
99
- env["_"] = result
100
-
101
- except ClosingError:
102
- continue # Allow user to continue adding text
103
- except MyError as e:
104
- print(f"{bold_red}error{reset}: {e}")
105
-
106
- text = None
107
-
108
- except (KeyboardInterrupt, EOFError):
109
- print("")
110
-
111
-
112
- if __name__ == "__main__":
113
- main()
@@ -1,72 +0,0 @@
1
- import sys
2
- from dataclasses import dataclass, field
3
-
4
- import av
5
- from av.subtitles.subtitle import AssSubtitle
6
-
7
- from auto_editor.json import dump
8
- from auto_editor.vanparse import ArgumentParser
9
-
10
-
11
- @dataclass(slots=True)
12
- class SubdumpArgs:
13
- help: bool = False
14
- input: list[str] = field(default_factory=list)
15
- json: bool = False
16
-
17
-
18
- def main(sys_args: list[str] = sys.argv[1:]) -> None:
19
- parser = ArgumentParser("subdump")
20
- parser.add_required("input", nargs="*")
21
- parser.add_argument("--json", flag=True)
22
- args = parser.parse_args(SubdumpArgs, sys_args)
23
-
24
- if args.json:
25
- data = {}
26
- for input_file in args.input:
27
- container = av.open(input_file)
28
- for s in range(len(container.streams.subtitles)):
29
- entry_data = []
30
-
31
- input_stream = container.streams.subtitles[s]
32
- assert input_stream.time_base is not None
33
- for packet in container.demux(input_stream):
34
- if (
35
- packet.dts is None
36
- or packet.pts is None
37
- or packet.duration is None
38
- ):
39
- continue
40
-
41
- start = packet.pts * input_stream.time_base
42
- end = start + packet.duration * input_stream.time_base
43
-
44
- startf = round(float(start), 3)
45
- endf = round(float(end), 3)
46
-
47
- if endf - startf <= 0.02:
48
- continue
49
-
50
- for sub in packet.decode():
51
- if isinstance(sub, AssSubtitle):
52
- content = sub.dialogue.decode("utf-8", errors="ignore")
53
- entry_data.append([startf, endf, content])
54
-
55
- data[f"{input_file}:{s}"] = entry_data
56
- container.close()
57
-
58
- dump(data, sys.stdout, indent=4)
59
- return
60
-
61
- for input_file in args.input:
62
- with av.open(input_file) as container:
63
- for s in range(len(container.streams.subtitles)):
64
- print(f"file: {input_file} ({s}:{container.streams.subtitles[s].name})")
65
- for sub2 in container.decode(subtitles=s):
66
- if isinstance(sub2, AssSubtitle):
67
- print(sub2.ass.decode("utf-8", errors="ignore"))
68
- print("------")
69
-
70
-
71
- if __name__ == "__main__":
72
- main()