auto-editor 23.38.1__py3-none-any.whl → 23.40.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 +2 -2
- auto_editor/analyze.py +19 -23
- auto_editor/help.py +10 -10
- auto_editor/lang/palet.py +203 -187
- auto_editor/lib/contracts.py +67 -30
- auto_editor/lib/data_structs.py +46 -9
- auto_editor/make_layers.py +24 -15
- auto_editor/subcommands/repl.py +4 -3
- auto_editor/timeline.py +16 -16
- {auto_editor-23.38.1.dist-info → auto_editor-23.40.1.dist-info}/METADATA +33 -8
- {auto_editor-23.38.1.dist-info → auto_editor-23.40.1.dist-info}/RECORD +16 -16
- {auto_editor-23.38.1.dist-info → auto_editor-23.40.1.dist-info}/LICENSE +0 -0
- {auto_editor-23.38.1.dist-info → auto_editor-23.40.1.dist-info}/WHEEL +0 -0
- {auto_editor-23.38.1.dist-info → auto_editor-23.40.1.dist-info}/entry_points.txt +0 -0
- {auto_editor-23.38.1.dist-info → auto_editor-23.40.1.dist-info}/top_level.txt +0 -0
- {auto_editor-23.38.1.dist-info → auto_editor-23.40.1.dist-info}/zip-safe +0 -0
auto_editor/lib/contracts.py
CHANGED
@@ -9,37 +9,17 @@ from .data_structs import Sym, print_str
|
|
9
9
|
from .err import MyError
|
10
10
|
|
11
11
|
|
12
|
-
@dataclass(slots=True)
|
13
|
-
class Proc:
|
14
|
-
name: str
|
15
|
-
proc: Callable
|
16
|
-
arity: tuple[int, int | None] = (1, None)
|
17
|
-
contracts: list[Any] | None = None
|
18
|
-
|
19
|
-
def __call__(self, *args: Any) -> Any:
|
20
|
-
return self.proc(*args)
|
21
|
-
|
22
|
-
def __str__(self) -> str:
|
23
|
-
return self.name
|
24
|
-
|
25
|
-
def __repr__(self) -> str:
|
26
|
-
n = "inf" if self.arity[1] is None else f"{self.arity[1]}"
|
27
|
-
|
28
|
-
if self.contracts is None:
|
29
|
-
c = ""
|
30
|
-
else:
|
31
|
-
c = " (" + " ".join([f"{c}" for c in self.contracts]) + ")"
|
32
|
-
return f"#<proc:{self.name} ({self.arity[0]} {n}){c}>"
|
33
|
-
|
34
|
-
|
35
12
|
@dataclass(slots=True)
|
36
13
|
class Contract:
|
37
14
|
# Convenient flat contract class
|
38
15
|
name: str
|
39
16
|
c: Callable[[object], bool]
|
40
17
|
|
41
|
-
def __call__(self, v: object) -> bool:
|
42
|
-
|
18
|
+
def __call__(self, *v: object) -> bool:
|
19
|
+
if len(v) != 1:
|
20
|
+
o = self.name
|
21
|
+
raise MyError(f"`{o}` has an arity mismatch. Expected 1, got {len(v)}")
|
22
|
+
return self.c(v[0])
|
43
23
|
|
44
24
|
def __str__(self) -> str:
|
45
25
|
return self.name
|
@@ -66,6 +46,63 @@ def check_contract(c: object, val: object) -> bool:
|
|
66
46
|
raise MyError(f"Invalid contract, got: {print_str(c)}")
|
67
47
|
|
68
48
|
|
49
|
+
def check_args(
|
50
|
+
o: str,
|
51
|
+
values: list | tuple,
|
52
|
+
arity: tuple[int, int | None],
|
53
|
+
cont: tuple[Any, ...],
|
54
|
+
) -> None:
|
55
|
+
lower, upper = arity
|
56
|
+
amount = len(values)
|
57
|
+
|
58
|
+
assert not (upper is not None and lower > upper)
|
59
|
+
base = f"`{o}` has an arity mismatch. Expected "
|
60
|
+
|
61
|
+
if lower == upper and len(values) != lower:
|
62
|
+
raise MyError(f"{base}{lower}, got {amount}")
|
63
|
+
if upper is None and amount < lower:
|
64
|
+
raise MyError(f"{base}at least {lower}, got {amount}")
|
65
|
+
if upper is not None and (amount > upper or amount < lower):
|
66
|
+
raise MyError(f"{base}between {lower} and {upper}, got {amount}")
|
67
|
+
|
68
|
+
if not cont:
|
69
|
+
return
|
70
|
+
|
71
|
+
for i, val in enumerate(values):
|
72
|
+
check = cont[-1] if i >= len(cont) else cont[i]
|
73
|
+
if not check_contract(check, val):
|
74
|
+
exp = f"{check}" if callable(check) else print_str(check)
|
75
|
+
raise MyError(f"`{o}` expected a {exp}, got {print_str(val)}")
|
76
|
+
|
77
|
+
|
78
|
+
class Proc:
|
79
|
+
__slots__ = ("name", "proc", "arity", "contracts")
|
80
|
+
|
81
|
+
def __init__(
|
82
|
+
self, n: str, p: Callable, a: tuple[int, int | None] = (1, None), *c: Any
|
83
|
+
):
|
84
|
+
self.name = n
|
85
|
+
self.proc = p
|
86
|
+
self.arity = a
|
87
|
+
self.contracts: tuple[Any, ...] = c
|
88
|
+
|
89
|
+
def __call__(self, *args: Any) -> Any:
|
90
|
+
check_args(self.name, args, self.arity, self.contracts)
|
91
|
+
return self.proc(*args)
|
92
|
+
|
93
|
+
def __str__(self) -> str:
|
94
|
+
return self.name
|
95
|
+
|
96
|
+
def __repr__(self) -> str:
|
97
|
+
n = "inf" if self.arity[1] is None else f"{self.arity[1]}"
|
98
|
+
|
99
|
+
if self.contracts is None:
|
100
|
+
c = ""
|
101
|
+
else:
|
102
|
+
c = " (" + " ".join([f"{c}" for c in self.contracts]) + ")"
|
103
|
+
return f"#<proc:{self.name} ({self.arity[0]} {n}){c}>"
|
104
|
+
|
105
|
+
|
69
106
|
def is_contract(c: object) -> bool:
|
70
107
|
if type(c) is Contract:
|
71
108
|
return True
|
@@ -82,8 +119,8 @@ def is_contract(c: object) -> bool:
|
|
82
119
|
|
83
120
|
is_bool = Contract("bool?", lambda v: type(v) is bool)
|
84
121
|
is_int = Contract("int?", lambda v: type(v) is int)
|
85
|
-
|
86
|
-
|
122
|
+
is_nat = Contract("nat?", lambda v: type(v) is int and v > -1)
|
123
|
+
is_nat1 = Contract("nat1?", lambda v: type(v) is int and v > 0)
|
87
124
|
int_not_zero = Contract("(or/c (not/c 0) int?)", lambda v: v != 0 and is_int(v))
|
88
125
|
is_num = Contract("number?", lambda v: type(v) in (int, float, Fraction, complex))
|
89
126
|
is_real = Contract("real?", lambda v: type(v) in (int, float, Fraction))
|
@@ -101,13 +138,13 @@ is_proc = Contract("procedure?", lambda v: isinstance(v, (Proc, Contract)))
|
|
101
138
|
|
102
139
|
def andc(*cs: object) -> Proc:
|
103
140
|
return Proc(
|
104
|
-
"flat-and/c", lambda v: all([check_contract(c, v) for c in cs]), (1, 1),
|
141
|
+
"flat-and/c", lambda v: all([check_contract(c, v) for c in cs]), (1, 1), any_p
|
105
142
|
)
|
106
143
|
|
107
144
|
|
108
145
|
def orc(*cs: object) -> Proc:
|
109
146
|
return Proc(
|
110
|
-
"flat-or/c", lambda v: any([check_contract(c, v) for c in cs]), (1, 1),
|
147
|
+
"flat-or/c", lambda v: any([check_contract(c, v) for c in cs]), (1, 1), any_p
|
111
148
|
)
|
112
149
|
|
113
150
|
|
@@ -131,7 +168,7 @@ def lt_c(n: int | float | Fraction) -> Proc:
|
|
131
168
|
return Proc(f"(</c {n})", lambda i: i < n, (1, 1), [is_real])
|
132
169
|
|
133
170
|
|
134
|
-
def between_c(n:
|
171
|
+
def between_c(n: Any, m: Any) -> Proc:
|
135
172
|
if m > n:
|
136
173
|
return Proc(
|
137
174
|
f"(between/c {n} {m})", lambda i: is_real(i) and i <= m and i >= n, (1, 1)
|
auto_editor/lib/data_structs.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
from collections.abc import Iterator
|
3
4
|
from fractions import Fraction
|
4
5
|
from io import StringIO
|
5
6
|
from typing import Any
|
@@ -81,6 +82,46 @@ class Keyword:
|
|
81
82
|
return type(obj) is Keyword and self.val == obj.val
|
82
83
|
|
83
84
|
|
85
|
+
class QuotedKeyword:
|
86
|
+
__slots__ = "val"
|
87
|
+
|
88
|
+
def __init__(self, val: Keyword | str):
|
89
|
+
self.val = val if isinstance(val, Keyword) else Keyword(val)
|
90
|
+
|
91
|
+
def __str__(self) -> str:
|
92
|
+
return f"{self.val}"
|
93
|
+
|
94
|
+
__repr__ = __str__
|
95
|
+
|
96
|
+
def __eq__(self, obj: object) -> bool:
|
97
|
+
return type(obj) is QuotedKeyword and self.val == obj.val
|
98
|
+
|
99
|
+
|
100
|
+
class Quoted:
|
101
|
+
__slots__ = "val"
|
102
|
+
|
103
|
+
def __init__(self, val: list):
|
104
|
+
self.val = val
|
105
|
+
|
106
|
+
def __len__(self) -> int:
|
107
|
+
return len(self.val)
|
108
|
+
|
109
|
+
def __getitem__(self, key: int | slice) -> Any:
|
110
|
+
if isinstance(key, slice):
|
111
|
+
return Quoted(self.val[key])
|
112
|
+
|
113
|
+
return self.val[key]
|
114
|
+
|
115
|
+
def __iter__(self) -> Iterator:
|
116
|
+
return self.val.__iter__()
|
117
|
+
|
118
|
+
def __contains__(self, item: object) -> bool:
|
119
|
+
return item in self.val
|
120
|
+
|
121
|
+
def __eq__(self, obj: object) -> bool:
|
122
|
+
return type(obj) is Quoted and self.val == obj.val
|
123
|
+
|
124
|
+
|
84
125
|
class Char:
|
85
126
|
__slots__ = "val"
|
86
127
|
|
@@ -141,16 +182,12 @@ def display_str(val: object) -> str:
|
|
141
182
|
if type(val) is Fraction:
|
142
183
|
return f"{val.numerator}/{val.denominator}"
|
143
184
|
|
144
|
-
if type(val) is
|
145
|
-
if
|
146
|
-
return f"{val[1]}"
|
147
|
-
|
148
|
-
if not val[1]:
|
185
|
+
if type(val) is Quoted:
|
186
|
+
if not val:
|
149
187
|
return "()"
|
150
|
-
|
151
188
|
result = StringIO()
|
152
|
-
result.write(f"({display_str(val[
|
153
|
-
for item in val[1
|
189
|
+
result.write(f"({display_str(val[0])}")
|
190
|
+
for item in val[1:]:
|
154
191
|
result.write(f" {display_str(item)}")
|
155
192
|
result.write(")")
|
156
193
|
return result.getvalue()
|
@@ -213,7 +250,7 @@ def print_str(val: object) -> str:
|
|
213
250
|
return f"{val!r}"
|
214
251
|
if type(val) is Keyword:
|
215
252
|
return f"'{val}"
|
216
|
-
if type(val)
|
253
|
+
if type(val) in (Sym, Quoted, QuotedKeyword):
|
217
254
|
return f"'{display_str(val)}"
|
218
255
|
|
219
256
|
return display_str(val)
|
auto_editor/make_layers.py
CHANGED
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any, NamedTuple
|
|
6
6
|
|
7
7
|
import numpy as np
|
8
8
|
|
9
|
-
from auto_editor.analyze import FileSetup
|
9
|
+
from auto_editor.analyze import FileSetup, Levels
|
10
10
|
from auto_editor.ffwrapper import FFmpeg, FileInfo
|
11
11
|
from auto_editor.lang.palet import Lexer, Parser, env, interpret, is_boolarr
|
12
12
|
from auto_editor.lib.data_structs import print_str
|
@@ -90,31 +90,40 @@ def make_av(
|
|
90
90
|
return vtl, atl
|
91
91
|
|
92
92
|
|
93
|
-
def
|
94
|
-
text: str,
|
95
|
-
filesetup: FileSetup,
|
96
|
-
log: Log,
|
93
|
+
def run_interpreter_for_edit_option(
|
94
|
+
text: str, filesetup: FileSetup
|
97
95
|
) -> NDArray[np.bool_]:
|
96
|
+
ensure = filesetup.ensure
|
97
|
+
src = filesetup.src
|
98
|
+
tb = filesetup.tb
|
99
|
+
bar = filesetup.bar
|
100
|
+
temp = filesetup.temp
|
101
|
+
log = filesetup.log
|
102
|
+
|
98
103
|
try:
|
99
104
|
parser = Parser(Lexer("`--edit`", text))
|
100
105
|
if log.is_debug:
|
101
106
|
log.debug(f"edit: {parser}")
|
102
107
|
|
103
108
|
env["timebase"] = filesetup.tb
|
109
|
+
env["@levels"] = Levels(ensure, src, tb, bar, temp, log)
|
104
110
|
env["@filesetup"] = filesetup
|
105
111
|
|
106
112
|
results = interpret(env, parser)
|
107
|
-
except (MyError, ZeroDivisionError) as e:
|
108
|
-
log.error(e)
|
109
113
|
|
110
|
-
|
111
|
-
|
114
|
+
if len(results) == 0:
|
115
|
+
raise MyError("Expression in --edit must return a bool-array, got nothing")
|
112
116
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
)
|
117
|
+
result = results[-1]
|
118
|
+
if callable(result):
|
119
|
+
result = result()
|
120
|
+
|
121
|
+
if not is_boolarr(result):
|
122
|
+
raise MyError(
|
123
|
+
f"Expression in --edit must return a bool-array, got {print_str(result)}"
|
124
|
+
)
|
125
|
+
except MyError as e:
|
126
|
+
log.error(e)
|
118
127
|
|
119
128
|
assert isinstance(result, np.ndarray)
|
120
129
|
return result
|
@@ -276,7 +285,7 @@ def make_layers(
|
|
276
285
|
|
277
286
|
for i in map(str, inputs):
|
278
287
|
filesetup = FileSetup(sources[i], ensure, len(inputs) < 2, tb, bar, temp, log)
|
279
|
-
has_loud =
|
288
|
+
has_loud = run_interpreter_for_edit_option(method, filesetup)
|
280
289
|
|
281
290
|
if len(mark_loud) > 0:
|
282
291
|
mut_set_range(has_loud, mark_loud, loud_speed)
|
auto_editor/subcommands/repl.py
CHANGED
@@ -5,7 +5,7 @@ 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
|
8
|
+
from auto_editor.analyze import FileSetup, Levels
|
9
9
|
from auto_editor.ffwrapper import FFmpeg, FileInfo
|
10
10
|
from auto_editor.lang.palet import ClosingError, Lexer, Parser, env, interpret
|
11
11
|
from auto_editor.lib.data_structs import print_str
|
@@ -77,9 +77,10 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
|
|
77
77
|
src = sources["0"]
|
78
78
|
tb = src.get_fps() if args.timebase is None else args.timebase
|
79
79
|
ensure = Ensure(ffmpeg, src.get_sr(), temp, log)
|
80
|
-
|
80
|
+
bar = Bar("none")
|
81
81
|
env["timebase"] = tb
|
82
|
-
env["@
|
82
|
+
env["@levels"] = Levels(ensure, src, tb, bar, temp, log)
|
83
|
+
env["@filesetup"] = FileSetup(src, ensure, strict, tb, bar, temp, log)
|
83
84
|
|
84
85
|
print(f"Auto-Editor {auto_editor.version} ({auto_editor.__version__})")
|
85
86
|
text = None
|
auto_editor/timeline.py
CHANGED
@@ -100,59 +100,59 @@ class TlEllipse(_Visual):
|
|
100
100
|
|
101
101
|
video_builder = pAttrs(
|
102
102
|
"video",
|
103
|
-
pAttr("start", Required,
|
104
|
-
pAttr("dur", Required,
|
103
|
+
pAttr("start", Required, is_nat),
|
104
|
+
pAttr("dur", Required, is_nat),
|
105
105
|
pAttr("src", Required, is_str),
|
106
106
|
pAttr("offset", 0, is_int),
|
107
107
|
pAttr("speed", 1, is_real),
|
108
|
-
pAttr("stream", 0,
|
108
|
+
pAttr("stream", 0, is_nat),
|
109
109
|
)
|
110
110
|
audio_builder = pAttrs(
|
111
111
|
"audio",
|
112
|
-
pAttr("start", Required,
|
113
|
-
pAttr("dur", Required,
|
112
|
+
pAttr("start", Required, is_nat),
|
113
|
+
pAttr("dur", Required, is_nat),
|
114
114
|
pAttr("src", Required, is_str),
|
115
115
|
pAttr("offset", 0, is_int),
|
116
116
|
pAttr("speed", 1, is_real),
|
117
117
|
pAttr("volume", 1, is_real),
|
118
|
-
pAttr("stream", 0,
|
118
|
+
pAttr("stream", 0, is_nat),
|
119
119
|
)
|
120
120
|
text_builder = pAttrs(
|
121
121
|
"text",
|
122
|
-
pAttr("start", Required,
|
123
|
-
pAttr("dur", Required,
|
122
|
+
pAttr("start", Required, is_nat),
|
123
|
+
pAttr("dur", Required, is_nat),
|
124
124
|
pAttr("content", Required, is_str),
|
125
125
|
pAttr("x", 0.5, is_real),
|
126
126
|
pAttr("y", 0.5, is_real),
|
127
127
|
pAttr("font", "Arial", is_str),
|
128
|
-
pAttr("size", 55,
|
128
|
+
pAttr("size", 55, is_nat),
|
129
129
|
pAttr("align", "left", is_str),
|
130
130
|
pAttr("opacity", 1, is_threshold),
|
131
131
|
pAttr("anchor", "ce", is_str),
|
132
132
|
pAttr("rotate", 0, is_real),
|
133
133
|
pAttr("fill", "#FFF", is_str),
|
134
|
-
pAttr("stroke", 0,
|
134
|
+
pAttr("stroke", 0, is_nat),
|
135
135
|
pAttr("strokecolor", "#000", is_str),
|
136
136
|
)
|
137
137
|
|
138
138
|
img_builder = pAttrs(
|
139
139
|
"image",
|
140
|
-
pAttr("start", Required,
|
141
|
-
pAttr("dur", Required,
|
140
|
+
pAttr("start", Required, is_nat),
|
141
|
+
pAttr("dur", Required, is_nat),
|
142
142
|
pAttr("src", Required, is_str),
|
143
143
|
pAttr("x", 0.5, is_real),
|
144
144
|
pAttr("y", 0.5, is_real),
|
145
145
|
pAttr("opacity", 1, is_threshold),
|
146
146
|
pAttr("anchor", "ce", is_str),
|
147
147
|
pAttr("rotate", 0, is_real),
|
148
|
-
pAttr("stroke", 0,
|
148
|
+
pAttr("stroke", 0, is_nat),
|
149
149
|
pAttr("strokecolor", "#000", is_str),
|
150
150
|
)
|
151
151
|
|
152
152
|
rect_builder = pAttrs(
|
153
153
|
"rect",
|
154
|
-
pAttr("start", Required,
|
155
|
-
pAttr("dur", Required,
|
154
|
+
pAttr("start", Required, is_nat),
|
155
|
+
pAttr("dur", Required, is_nat),
|
156
156
|
pAttr("x", Required, is_real),
|
157
157
|
pAttr("y", Required, is_real),
|
158
158
|
pAttr("width", Required, is_real),
|
@@ -161,7 +161,7 @@ rect_builder = pAttrs(
|
|
161
161
|
pAttr("anchor", "ce", is_str),
|
162
162
|
pAttr("rotate", 0, is_real),
|
163
163
|
pAttr("fill", "#c4c4c4", is_str),
|
164
|
-
pAttr("stroke", 0,
|
164
|
+
pAttr("stroke", 0, is_nat),
|
165
165
|
pAttr("strokecolor", "#000", is_str),
|
166
166
|
)
|
167
167
|
ellipse_builder = rect_builder
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: auto-editor
|
3
|
-
Version: 23.
|
3
|
+
Version: 23.40.1
|
4
4
|
Summary: Auto-Editor: Effort free video editing!
|
5
5
|
Home-page: https://auto-editor.com
|
6
6
|
Author: WyattBlue
|
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3
|
|
22
22
|
Classifier: Programming Language :: Python :: 3 :: Only
|
23
23
|
Classifier: Programming Language :: Python :: 3.10
|
24
24
|
Classifier: Programming Language :: Python :: 3.11
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
25
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
26
27
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
27
28
|
Requires-Python: >=3.10
|
@@ -29,7 +30,7 @@ Description-Content-Type: text/markdown
|
|
29
30
|
License-File: LICENSE
|
30
31
|
Requires-Dist: numpy >=1.22.0
|
31
32
|
Requires-Dist: pillow ==10.0.1
|
32
|
-
Requires-Dist:
|
33
|
+
Requires-Dist: pyav ==11.0.1
|
33
34
|
Requires-Dist: ae-ffmpeg ==1.1.*
|
34
35
|
|
35
36
|
<p align="center"><img src="https://auto-editor.com/img/auto-editor-banner.webp" title="Auto-Editor" width="700"></p>
|
@@ -129,22 +130,46 @@ Auto-Editor can also export to:
|
|
129
130
|
|
130
131
|
Other editors, like Sony Vegas, can understand the `premiere` format. If your favorite editor doesn't, you can use ` --export clip-sequence` which creates many video clips that can be imported and manipulated like normal.
|
131
132
|
|
133
|
+
### Naming Timelines
|
134
|
+
By default, auto-editor will name the timeline to "Auto-Editor Media Group" if the export supports naming.
|
135
|
+
|
136
|
+
```
|
137
|
+
auto-editor example.mp4 --export 'premiere:name="Your name here"'
|
138
|
+
|
139
|
+
auto-editor example.mp4 --export 'resolve:name="Your name here"'
|
140
|
+
|
141
|
+
auto-editor example.mp4 --export 'final-cut-pro:name="Your name here"'
|
142
|
+
|
143
|
+
# No other export options support naming
|
144
|
+
```
|
145
|
+
|
146
|
+
### Split by Clip
|
147
|
+
|
148
|
+
If you want to split the clips, but don't want auto-editor to do any more editing. There's a simple command.
|
149
|
+
```
|
150
|
+
auto-editor example.mp4 --silent-speed 1 --video-speed 1 --export premiere
|
151
|
+
```
|
152
|
+
|
132
153
|
<h2 align="center">Manual Editing</h2>
|
133
154
|
|
134
155
|
Use the `--cut-out` option to always remove a section.
|
135
156
|
|
136
157
|
```
|
137
158
|
# Cut out the first 30 seconds.
|
138
|
-
auto-editor example.mp4 --cut-out
|
159
|
+
auto-editor example.mp4 --cut-out 0,30sec
|
139
160
|
|
140
161
|
# Cut out the first 30 frames.
|
141
|
-
auto-editor example.mp4 --cut-out
|
162
|
+
auto-editor example.mp4 --cut-out 0,30
|
163
|
+
|
164
|
+
# Always leave in the first 30 seconds.
|
165
|
+
auto-editor example.mp4 --add-in 0,30sec
|
142
166
|
|
143
167
|
# Cut out the last 10 seconds.
|
144
168
|
auto-editor example.mp4 --cut-out -10sec,end
|
145
169
|
|
146
|
-
#
|
147
|
-
auto-editor example.mp4 --cut-out
|
170
|
+
# You can do multiple at once.
|
171
|
+
auto-editor example.mp4 --cut-out 0,10 15sec,20sec
|
172
|
+
auto-editor example.mp4 --add-in 30sec,40sec 120,150sec
|
148
173
|
```
|
149
174
|
|
150
175
|
And of course, you can use any `--edit` configuration.
|
@@ -153,10 +178,10 @@ If you don't want **any automatic cuts**, you can use `--edit none` or `--edit a
|
|
153
178
|
|
154
179
|
```
|
155
180
|
# Cut out the first 5 seconds, leave the rest untouched.
|
156
|
-
auto-editor example.mp4 --edit none --cut-out
|
181
|
+
auto-editor example.mp4 --edit none --cut-out 0,5sec
|
157
182
|
|
158
183
|
# Leave in the first 5 seconds, cut everything else out.
|
159
|
-
auto-editor example.mp4 --edit all/e --add-in
|
184
|
+
auto-editor example.mp4 --edit all/e --add-in 0,5sec
|
160
185
|
```
|
161
186
|
|
162
187
|
<h2 align="center">More Options</h2>
|
@@ -1,13 +1,13 @@
|
|
1
|
-
auto_editor/__init__.py,sha256=
|
1
|
+
auto_editor/__init__.py,sha256=MWD2N5xWDufJ9Z47pkoSVsXQPs4p0mZ0_4KGgP3TuE4,43
|
2
2
|
auto_editor/__main__.py,sha256=CEvSgB-etDzqbTG1ZxubrH6Vq-ZEJ9cgcy_WOwaxoA4,10241
|
3
|
-
auto_editor/analyze.py,sha256=
|
3
|
+
auto_editor/analyze.py,sha256=tj38HlXqMnsgV7vQuFJqyzLI70-26Zm8Yw7joVreOh8,16412
|
4
4
|
auto_editor/edit.py,sha256=BoMnUMf_ofozu2mUaOB6dMHQ7hMBuefZsrKO-vygGas,12442
|
5
5
|
auto_editor/ffwrapper.py,sha256=C6KC14t5BkTUH8K7RG-hRIZAeEyNJYKFV2R4V-pD8Rw,11006
|
6
|
-
auto_editor/help.py,sha256=
|
7
|
-
auto_editor/make_layers.py,sha256=
|
6
|
+
auto_editor/help.py,sha256=MFGDf1B69F97kx-QTI3i-DmdKIWqoEjhpJwM1PsxsvA,9920
|
7
|
+
auto_editor/make_layers.py,sha256=H5xD35M2qlYCeygsezmmtxhnKx4BZOTIwqnZ5MF-MWo,9280
|
8
8
|
auto_editor/output.py,sha256=63T9UkdUvNIKDsf4qOkcSPJzgICyHb6tos7s6XrbAJY,5693
|
9
9
|
auto_editor/preview.py,sha256=cWvx-AXvpDeIouaPZg6rnkHuXIE1mu86vaFEUPwCo64,2613
|
10
|
-
auto_editor/timeline.py,sha256=
|
10
|
+
auto_editor/timeline.py,sha256=20vYjRdL0qJwS_txI05WUA3FPYXBNG5bncU050CvbpM,6648
|
11
11
|
auto_editor/validate_input.py,sha256=G4LzUdt0fSrIPRd-wvP7x9cOzXmHTd7-BPrFk2ZNEWk,2671
|
12
12
|
auto_editor/vanparse.py,sha256=TzvkmDkSH6NwNRtbrV72rdWRytEWcrLAJY7csCgeEfs,9871
|
13
13
|
auto_editor/wavfile.py,sha256=pTCrquFdmpFRjva3zjQRLM3QicHGrYuExPbwCjRbSMg,8378
|
@@ -19,10 +19,10 @@ auto_editor/formats/shotcut.py,sha256=bTpdpv1DykMNqtEq71DwVrk0IzvL6Et4ZHO8yd1yHI
|
|
19
19
|
auto_editor/formats/utils.py,sha256=GIZw28WHuCIaZ_zMI0v6Kxbq0QaIpbLsdSegdYwQxQ8,1990
|
20
20
|
auto_editor/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
21
|
auto_editor/lang/json.py,sha256=zHBqqfrdHAW-NAsdeIMoqOoC4j8ibPpMgA3icCCjBXQ,9093
|
22
|
-
auto_editor/lang/palet.py,sha256=
|
22
|
+
auto_editor/lang/palet.py,sha256=L1ot5lssXwpp3KoWCEQGsCLwRD5BhAbWmQ17gEP-Zao,51469
|
23
23
|
auto_editor/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
-
auto_editor/lib/contracts.py,sha256=
|
25
|
-
auto_editor/lib/data_structs.py,sha256=
|
24
|
+
auto_editor/lib/contracts.py,sha256=v8_4FJnSH8hw58LK9R_mz1uXM_8EOn5knZavRW4UrSE,5400
|
25
|
+
auto_editor/lib/data_structs.py,sha256=WDBBfUjac7bbEjdv07ClsP6KmI4t_142W9wQqQYPnmc,6343
|
26
26
|
auto_editor/lib/err.py,sha256=UlszQJdzMZwkbT8x3sY4GkCV_5x9yrd6uVVUzvA8iiI,35
|
27
27
|
auto_editor/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
28
|
auto_editor/render/audio.py,sha256=4vTz8rliN2prkZh0CGmIG9kIVzlCdRPolaT5JIG7S_U,9030
|
@@ -34,7 +34,7 @@ auto_editor/subcommands/desc.py,sha256=jS0mJk2fNlKetW3bvQw46Bw5GIBJSJxyeGaMPwRZa
|
|
34
34
|
auto_editor/subcommands/info.py,sha256=Z6a7yP7lZxR2Rq7m4Sr7B6sXb5sb_NZobRyTHajYr8I,6105
|
35
35
|
auto_editor/subcommands/levels.py,sha256=PWOYuirLhGgVvpm5EfVR1lzbMP-xxvoAOX6VCGi2jmk,4172
|
36
36
|
auto_editor/subcommands/palet.py,sha256=tbQoRWoT4jR3yu0etGApfprM-oQgXIjC-rIY-QG3nM0,655
|
37
|
-
auto_editor/subcommands/repl.py,sha256=
|
37
|
+
auto_editor/subcommands/repl.py,sha256=TmijSw-hGAExyafQDpQuOUk4Z9GM6mxf0a9qvc_24pc,3739
|
38
38
|
auto_editor/subcommands/subdump.py,sha256=T7vu-7CmRfYat1Jsnib1sqKuedZv04wJTktwQeYgkAc,1661
|
39
39
|
auto_editor/subcommands/test.py,sha256=rTRAx88-pDXMKln1PM3YkpUcX1SSDj71okaiBhgkSE0,27291
|
40
40
|
auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -46,10 +46,10 @@ auto_editor/utils/encoder.py,sha256=auNYo7HXbcU4iTUCc0LE5lpwFmSvdWvBm6-5KIaRK8w,
|
|
46
46
|
auto_editor/utils/func.py,sha256=DCsBiWD-sz1sRlbZJd5JAtyi_1JfXICBzqQ6RgNrjPY,4795
|
47
47
|
auto_editor/utils/log.py,sha256=6j2EWE97_urQijBvxhk2Gr2-VO_KNR1XbEobcAtTG-w,2668
|
48
48
|
auto_editor/utils/types.py,sha256=SmN6C4G7ACGLLlun2VSA0398AlSiC9owpBDZIUsQ2SI,12376
|
49
|
-
auto_editor-23.
|
50
|
-
auto_editor-23.
|
51
|
-
auto_editor-23.
|
52
|
-
auto_editor-23.
|
53
|
-
auto_editor-23.
|
54
|
-
auto_editor-23.
|
55
|
-
auto_editor-23.
|
49
|
+
auto_editor-23.40.1.dist-info/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
|
50
|
+
auto_editor-23.40.1.dist-info/METADATA,sha256=VwKfADFxU2M1yPoWs3PPHN1F4y83NZ4fsz7931CJ4e8,7624
|
51
|
+
auto_editor-23.40.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
52
|
+
auto_editor-23.40.1.dist-info/entry_points.txt,sha256=-H7zdTw4MqnAcwrN5xTNkGIhzZtJMxS9r6lTMeR9-aA,240
|
53
|
+
auto_editor-23.40.1.dist-info/top_level.txt,sha256=ky1HUkqq9i034c4CUU_0wBw0xZsxxyGEak1eTbdvpyA,12
|
54
|
+
auto_editor-23.40.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
55
|
+
auto_editor-23.40.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|