auto-editor 28.1.0__py3-none-any.whl → 29.0.0__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 (59) hide show
  1. {auto_editor-28.1.0.dist-info → auto_editor-29.0.0.dist-info}/METADATA +4 -3
  2. auto_editor-29.0.0.dist-info/RECORD +5 -0
  3. auto_editor-29.0.0.dist-info/top_level.txt +1 -0
  4. auto_editor/__init__.py +0 -1
  5. auto_editor/__main__.py +0 -504
  6. auto_editor/analyze.py +0 -393
  7. auto_editor/cmds/__init__.py +0 -0
  8. auto_editor/cmds/cache.py +0 -69
  9. auto_editor/cmds/desc.py +0 -32
  10. auto_editor/cmds/info.py +0 -213
  11. auto_editor/cmds/levels.py +0 -199
  12. auto_editor/cmds/palet.py +0 -29
  13. auto_editor/cmds/repl.py +0 -113
  14. auto_editor/cmds/subdump.py +0 -72
  15. auto_editor/cmds/test.py +0 -816
  16. auto_editor/edit.py +0 -560
  17. auto_editor/exports/__init__.py +0 -0
  18. auto_editor/exports/fcp11.py +0 -195
  19. auto_editor/exports/fcp7.py +0 -313
  20. auto_editor/exports/json.py +0 -63
  21. auto_editor/exports/kdenlive.py +0 -322
  22. auto_editor/exports/shotcut.py +0 -147
  23. auto_editor/ffwrapper.py +0 -187
  24. auto_editor/help.py +0 -224
  25. auto_editor/imports/__init__.py +0 -0
  26. auto_editor/imports/fcp7.py +0 -275
  27. auto_editor/imports/json.py +0 -234
  28. auto_editor/json.py +0 -297
  29. auto_editor/lang/__init__.py +0 -0
  30. auto_editor/lang/libintrospection.py +0 -10
  31. auto_editor/lang/libmath.py +0 -23
  32. auto_editor/lang/palet.py +0 -724
  33. auto_editor/lang/stdenv.py +0 -1179
  34. auto_editor/lib/__init__.py +0 -0
  35. auto_editor/lib/contracts.py +0 -235
  36. auto_editor/lib/data_structs.py +0 -278
  37. auto_editor/lib/err.py +0 -2
  38. auto_editor/make_layers.py +0 -315
  39. auto_editor/preview.py +0 -93
  40. auto_editor/render/__init__.py +0 -0
  41. auto_editor/render/audio.py +0 -517
  42. auto_editor/render/subtitle.py +0 -205
  43. auto_editor/render/video.py +0 -307
  44. auto_editor/timeline.py +0 -331
  45. auto_editor/utils/__init__.py +0 -0
  46. auto_editor/utils/bar.py +0 -142
  47. auto_editor/utils/chunks.py +0 -2
  48. auto_editor/utils/cmdkw.py +0 -206
  49. auto_editor/utils/container.py +0 -101
  50. auto_editor/utils/func.py +0 -128
  51. auto_editor/utils/log.py +0 -126
  52. auto_editor/utils/types.py +0 -277
  53. auto_editor/vanparse.py +0 -313
  54. auto_editor-28.1.0.dist-info/RECORD +0 -57
  55. auto_editor-28.1.0.dist-info/entry_points.txt +0 -6
  56. auto_editor-28.1.0.dist-info/top_level.txt +0 -2
  57. docs/build.py +0 -70
  58. {auto_editor-28.1.0.dist-info → auto_editor-29.0.0.dist-info}/WHEEL +0 -0
  59. {auto_editor-28.1.0.dist-info → auto_editor-29.0.0.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()