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.
- {auto_editor-28.1.0.dist-info → auto_editor-29.0.0.dist-info}/METADATA +4 -3
- auto_editor-29.0.0.dist-info/RECORD +5 -0
- auto_editor-29.0.0.dist-info/top_level.txt +1 -0
- auto_editor/__init__.py +0 -1
- auto_editor/__main__.py +0 -504
- auto_editor/analyze.py +0 -393
- auto_editor/cmds/__init__.py +0 -0
- auto_editor/cmds/cache.py +0 -69
- auto_editor/cmds/desc.py +0 -32
- auto_editor/cmds/info.py +0 -213
- auto_editor/cmds/levels.py +0 -199
- auto_editor/cmds/palet.py +0 -29
- auto_editor/cmds/repl.py +0 -113
- auto_editor/cmds/subdump.py +0 -72
- auto_editor/cmds/test.py +0 -816
- auto_editor/edit.py +0 -560
- auto_editor/exports/__init__.py +0 -0
- auto_editor/exports/fcp11.py +0 -195
- auto_editor/exports/fcp7.py +0 -313
- auto_editor/exports/json.py +0 -63
- auto_editor/exports/kdenlive.py +0 -322
- auto_editor/exports/shotcut.py +0 -147
- auto_editor/ffwrapper.py +0 -187
- auto_editor/help.py +0 -224
- auto_editor/imports/__init__.py +0 -0
- auto_editor/imports/fcp7.py +0 -275
- auto_editor/imports/json.py +0 -234
- auto_editor/json.py +0 -297
- auto_editor/lang/__init__.py +0 -0
- auto_editor/lang/libintrospection.py +0 -10
- auto_editor/lang/libmath.py +0 -23
- auto_editor/lang/palet.py +0 -724
- auto_editor/lang/stdenv.py +0 -1179
- auto_editor/lib/__init__.py +0 -0
- auto_editor/lib/contracts.py +0 -235
- auto_editor/lib/data_structs.py +0 -278
- auto_editor/lib/err.py +0 -2
- auto_editor/make_layers.py +0 -315
- auto_editor/preview.py +0 -93
- auto_editor/render/__init__.py +0 -0
- auto_editor/render/audio.py +0 -517
- auto_editor/render/subtitle.py +0 -205
- auto_editor/render/video.py +0 -307
- auto_editor/timeline.py +0 -331
- auto_editor/utils/__init__.py +0 -0
- auto_editor/utils/bar.py +0 -142
- auto_editor/utils/chunks.py +0 -2
- auto_editor/utils/cmdkw.py +0 -206
- auto_editor/utils/container.py +0 -101
- auto_editor/utils/func.py +0 -128
- auto_editor/utils/log.py +0 -126
- auto_editor/utils/types.py +0 -277
- auto_editor/vanparse.py +0 -313
- auto_editor-28.1.0.dist-info/RECORD +0 -57
- auto_editor-28.1.0.dist-info/entry_points.txt +0 -6
- auto_editor-28.1.0.dist-info/top_level.txt +0 -2
- docs/build.py +0 -70
- {auto_editor-28.1.0.dist-info → auto_editor-29.0.0.dist-info}/WHEEL +0 -0
- {auto_editor-28.1.0.dist-info → auto_editor-29.0.0.dist-info}/licenses/LICENSE +0 -0
auto_editor/help.py
DELETED
@@ -1,224 +0,0 @@
|
|
1
|
-
data = {
|
2
|
-
"Auto-Editor": {
|
3
|
-
"_": """
|
4
|
-
Auto-Editor is an automatic video/audio creator and editor. By default, it will detect silence and create a new video with those sections cut out. By changing some of the options, you can export to a traditional editor like Premiere Pro and adjust the edits there, adjust the pacing of the cuts, and change the method of editing like using audio loudness and video motion to judge making cuts.
|
5
|
-
|
6
|
-
Run:
|
7
|
-
auto-editor --help
|
8
|
-
|
9
|
-
To get the list of options.
|
10
|
-
""".strip(),
|
11
|
-
"--set-speed-for-range": """
|
12
|
-
This option takes 3 arguments delimited with commas and they are as follows:
|
13
|
-
- speed:
|
14
|
-
- How fast to play the media (number)
|
15
|
-
Start:
|
16
|
-
- The time when speed first gets applied (time)
|
17
|
-
End:
|
18
|
-
- The time when speed stops being applied (time)
|
19
|
-
|
20
|
-
example:
|
21
|
-
|
22
|
-
--set-range-for-speed 2.5,400,800
|
23
|
-
|
24
|
-
will set the speed from 400 ticks to 800 ticks to 2.5x
|
25
|
-
If timebase is 30, 400 ticks to 800 means 13.33 to 26.66 seconds
|
26
|
-
""".strip(),
|
27
|
-
"--edit": """
|
28
|
-
Evaluates a palet expression that returns a bool-array?. The array is then used for
|
29
|
-
editing.
|
30
|
-
|
31
|
-
Examples:
|
32
|
-
--edit audio
|
33
|
-
--edit audio:0.03 ; Change the threshold. Can be a value between 0-1.
|
34
|
-
--edit audio:3% ; You can also use the `%` macro.
|
35
|
-
--edit audio:0.03,stream=0 ; Only consider the first stream for editing.
|
36
|
-
--edit audio:stream=1,threshold=0.05 ; Here's how you use keyword arguments.
|
37
|
-
--edit (or audio:0.04,stream=0 audio:0.08,stream=1) ; Consider both streams for editing (merge with logical or), but with different thresholds.
|
38
|
-
--edit motion
|
39
|
-
--edit motion:0.02,blur=3
|
40
|
-
--edit (or audio:0.04 motion:0.02,blur=3)
|
41
|
-
--edit none
|
42
|
-
--edit all/e
|
43
|
-
|
44
|
-
Editing Methods:
|
45
|
-
- audio ; Audio silence/loudness detection
|
46
|
-
- threshold threshold? : 4%
|
47
|
-
- stream (or/c nat? 'all) : 'all
|
48
|
-
- mincut nat? : 6
|
49
|
-
- minclip nat? : 3
|
50
|
-
|
51
|
-
; mincut is more significant, there it has a larger default value.
|
52
|
-
; minclip gets applied first, then mincut
|
53
|
-
|
54
|
-
- motion ; Motion detection specialized for noisy real-life videos
|
55
|
-
- threshold threshold? : 2%
|
56
|
-
- stream nat? : 0
|
57
|
-
- blur nat? : 9
|
58
|
-
- width nat1? : 400
|
59
|
-
|
60
|
-
- subtitle ; Detect when subtitle matches pattern as a RegEx string.
|
61
|
-
- pattern string?
|
62
|
-
- stream nat? : 0
|
63
|
-
- ignore-case bool? : #f
|
64
|
-
- max-count (or/c nat? void?) : (void)
|
65
|
-
|
66
|
-
- none ; Do not modify the media in anyway; mark all sections as "loud" (1).
|
67
|
-
- all/e ; Cut out everything out; mark all sections as "silent" (0).
|
68
|
-
""".strip(),
|
69
|
-
"--export": """
|
70
|
-
This option controls how timelines are exported.
|
71
|
-
|
72
|
-
Export Methods:
|
73
|
-
- default ; Export as a regular media file
|
74
|
-
- premiere ; Export as an XML timeline file for Adobe Premiere Pro
|
75
|
-
- name : "Auto-Editor Media Group"
|
76
|
-
- resolve ; Export as an XML timeline file for DaVinci Resolve
|
77
|
-
- name : "Auto-Editor Media Group"
|
78
|
-
- final-cut-pro ; Export as an XML timeline file for Final Cut Pro
|
79
|
-
- name : "Auto-Editor Media Group"
|
80
|
-
- shotcut ; Export as an XML timeline file for Shotcut
|
81
|
-
- kdenlive ; Export as an XML timeline file for kdenlive
|
82
|
-
- v3 ; Export as an auto-editor v3 timeline file
|
83
|
-
- v1 ; Export as an auto-editor v1 timeline file
|
84
|
-
- clip-sequence ; Export as multiple numbered media files
|
85
|
-
|
86
|
-
""".strip(),
|
87
|
-
"--player": """
|
88
|
-
This option uses shell-like syntax to support using a specific player:
|
89
|
-
|
90
|
-
auto-editor in.mp4 --player mpv
|
91
|
-
|
92
|
-
Args for the player program can be added as well:
|
93
|
-
|
94
|
-
auto-editor in.mp4 --player 'mpv --keep-open'
|
95
|
-
|
96
|
-
Absolute or relative paths can also be used in the event the player's
|
97
|
-
executable can not be resolved:
|
98
|
-
|
99
|
-
auto-editor in.mp4 --player '/path/to/mpv'
|
100
|
-
auto-editor in.mp4 --player './my-relative-path/mpv'
|
101
|
-
|
102
|
-
If --player is not set, auto-editor will use the system default.
|
103
|
-
If --no-open is used, --player will always be ignored.
|
104
|
-
|
105
|
-
on MacOS, QuickTime can be used as the default player this way:
|
106
|
-
|
107
|
-
auto-editor in.mp4 --player 'open -a "quicktime player"'
|
108
|
-
""".strip(),
|
109
|
-
"--resolution": """
|
110
|
-
|
111
|
-
When working with media files, resolution will be based on the first input with a
|
112
|
-
fallback value of 1920x1080
|
113
|
-
""".strip(),
|
114
|
-
"--frame-rate": """
|
115
|
-
Set the timeline's timebase and the output media's frame rate.
|
116
|
-
|
117
|
-
When working with media files, frame-rate will be the first input's frame rate
|
118
|
-
with a fallback value of 30
|
119
|
-
|
120
|
-
The format must be a string in the form:
|
121
|
-
- frame_rate_num/frame_rate_den
|
122
|
-
- an integer
|
123
|
-
- an floating point number
|
124
|
-
- a valid frame rate label
|
125
|
-
|
126
|
-
The following labels are recognized:
|
127
|
-
- ntsc -> 30000/1001
|
128
|
-
- ntsc_film -> 24000/1001
|
129
|
-
- pal -> 25
|
130
|
-
- film -> 24
|
131
|
-
""".strip(),
|
132
|
-
"--temp-dir": """
|
133
|
-
If not set, tempdir will be set with Python's tempfile module
|
134
|
-
The directory doesn't have to exist beforehand, however, the root path must be valid.
|
135
|
-
Beware that the temp directory can get quite big.
|
136
|
-
""".strip(),
|
137
|
-
"--audio-bitrate": """
|
138
|
-
`--audio-bitrate` sets the target bitrate for the audio encoder.
|
139
|
-
By default, the value is `auto` (let the encoder decide).
|
140
|
-
It can be set to a natural number with units: ``, `k`, `K`, `M`, or `G`.
|
141
|
-
|
142
|
-
""".strip(),
|
143
|
-
"--video-bitrate": """
|
144
|
-
`--video-bitrate` sets the target bitrate for the video encoder. `auto` is set as the default. It accepts the same format as `--audio-bitrate`
|
145
|
-
""".strip(),
|
146
|
-
"--margin": """
|
147
|
-
Default value: 0.2s,0.2s
|
148
|
-
|
149
|
-
`--margin` takes either one number of two numbers with a `,` in-between.
|
150
|
-
The numbers may be written in the 'time' format. Here is a quick recap:
|
151
|
-
|
152
|
-
frames / timebase : `` (no units)
|
153
|
-
seconds : `s` `sec` `secs` `second` `seconds`
|
154
|
-
minutes : `min` `mins` `minute` `minutes`
|
155
|
-
hours : `hour`
|
156
|
-
|
157
|
-
seconds, minutes : MM:SS.SS
|
158
|
-
hours, mins, secs : HH:MM:SS.SS
|
159
|
-
|
160
|
-
|
161
|
-
Setting margin examples:
|
162
|
-
- `--margin 6`
|
163
|
-
- `--margin 4,10`
|
164
|
-
- `--margin 0.3s,0.5s`
|
165
|
-
- `--margin 1:12.5` ; 1 minute, 12.5 seconds
|
166
|
-
|
167
|
-
Behind the scenes, margin is a function that operates on boolean arrays
|
168
|
-
(where 1 represents "loud" and 0 represents "silence")
|
169
|
-
|
170
|
-
Here is a list of examples on how margin mutates boolean arrays
|
171
|
-
|
172
|
-
(margin 0 0 (bool-array 0 0 0 1 0 0 0))
|
173
|
-
> (array 'bool 0 0 0 1 0 0 0)
|
174
|
-
|
175
|
-
(margin 1 0 (bool-array 0 0 0 1 0 0 0))
|
176
|
-
> (array 'bool 0 0 1 1 0 0 0)
|
177
|
-
|
178
|
-
(margin 1 1 (bool-array 0 0 0 1 0 0 0))
|
179
|
-
> (array 'bool 0 0 1 1 1 0 0)
|
180
|
-
|
181
|
-
(margin 1 2 (bool-array 0 0 1 1 0 0 0 0 1 0))
|
182
|
-
> (array 'bool 0 1 1 1 1 1 0 1 1 1)
|
183
|
-
|
184
|
-
(margin -2 2 (bool-array 0 0 1 1 0 0 0))
|
185
|
-
> (array 'bool 0 0 0 0 1 1 0)
|
186
|
-
""".strip(),
|
187
|
-
"--audio-normalize": """
|
188
|
-
Apply audio normalization after cutting.
|
189
|
-
|
190
|
-
Normalization Methods:
|
191
|
-
- ebu ; EBU R128 (double pass) loudness normalization
|
192
|
-
; Integrated loudness target
|
193
|
-
- i (and/c (or/c int? float?) (between/c -70 -5)) : -24.0
|
194
|
-
; Loudness range target
|
195
|
-
- lra (and/c (or/c int? float?) (between/c 1 50)) : 7.0
|
196
|
-
; Set maximum true peak
|
197
|
-
- tp (and/c (or/c int? float?) (between/c -9 0)) : -2.0
|
198
|
-
; Set offset gain. Gain is applied before the true-peak limiter
|
199
|
-
- gain (and/c (or/c int? float?) (between/c -99 99)) : 0.0
|
200
|
-
|
201
|
-
- peak
|
202
|
-
; Loudness target
|
203
|
-
- t (and/c (or/c int? float?) (between/c -99 0)) : -8.0
|
204
|
-
|
205
|
-
If `#f` is chosen, no audio-normalization will be applied.
|
206
|
-
|
207
|
-
Note that this option is a thin layer over the audio filter `loudnorm` for `ebu` and `astats`/`volume` for `peak` respectively.
|
208
|
-
Check out its docs for more info: https://ffmpeg.org/ffmpeg-filters.html#loudnorm
|
209
|
-
|
210
|
-
Examples:
|
211
|
-
--audio-normalize #f
|
212
|
-
--audio-normalize ebu:i=-5,lra=40,gain=5,tp=-1
|
213
|
-
""".strip(),
|
214
|
-
"--silent-speed": "99999 is the 'cut speed' and values over that or <=0 are considered 'cut speeds' as well",
|
215
|
-
"--video-speed": "99999 is the 'cut speed' and values over that or <=0 are considered 'cut speeds' as well",
|
216
|
-
},
|
217
|
-
"info": {"_": "Retrieve information and properties about media files"},
|
218
|
-
"levels": {"_": "Display loudness over time"},
|
219
|
-
"subdump": {
|
220
|
-
"_": "Dump text-based subtitles to stdout with formatting stripped out"
|
221
|
-
},
|
222
|
-
"desc": {"_": "Display a media's description metadata"},
|
223
|
-
"test": {"_": "Self-Hosted Unit and End-to-End tests"},
|
224
|
-
}
|
auto_editor/imports/__init__.py
DELETED
File without changes
|
auto_editor/imports/fcp7.py
DELETED
@@ -1,275 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import xml.etree.ElementTree as ET
|
4
|
-
from fractions import Fraction
|
5
|
-
from typing import TYPE_CHECKING
|
6
|
-
from urllib.parse import unquote
|
7
|
-
from xml.etree.ElementTree import Element
|
8
|
-
|
9
|
-
from auto_editor.ffwrapper import FileInfo
|
10
|
-
from auto_editor.timeline import ASpace, Clip, Template, VSpace, v3
|
11
|
-
|
12
|
-
if TYPE_CHECKING:
|
13
|
-
from auto_editor.utils.log import Log
|
14
|
-
|
15
|
-
|
16
|
-
SUPPORTED_EFFECTS = ("timeremap",)
|
17
|
-
|
18
|
-
|
19
|
-
def show(ele: Element, limit: int, depth: int = 0) -> None:
|
20
|
-
print(
|
21
|
-
f"{' ' * (depth * 4)}<{ele.tag} {ele.attrib}> {ele.text.strip() if ele.text is not None else ''}"
|
22
|
-
)
|
23
|
-
for child in ele:
|
24
|
-
if isinstance(child, Element) and depth < limit:
|
25
|
-
show(child, limit, depth + 1)
|
26
|
-
|
27
|
-
|
28
|
-
def read_filters(clipitem: Element, log: Log) -> float:
|
29
|
-
for effect_tag in clipitem:
|
30
|
-
if effect_tag.tag in {"enabled", "start", "end"}:
|
31
|
-
continue
|
32
|
-
if len(effect_tag) < 3:
|
33
|
-
log.error("<effect> requires: <effectid> <name> and one <parameter>")
|
34
|
-
for i, effects in enumerate(effect_tag):
|
35
|
-
if i == 0 and effects.tag != "name":
|
36
|
-
log.error("<effect>: <name> must be first tag")
|
37
|
-
if i == 1 and effects.tag != "effectid":
|
38
|
-
log.error("<effect>: <effectid> must be second tag")
|
39
|
-
if effects.text not in SUPPORTED_EFFECTS:
|
40
|
-
log.error(f"`{effects.text}` is not a supported effect.")
|
41
|
-
|
42
|
-
if i > 1:
|
43
|
-
for j, parms in enumerate(effects):
|
44
|
-
if j == 0:
|
45
|
-
if parms.tag != "parameterid":
|
46
|
-
log.error("<parameter>: <parameterid> must be first tag")
|
47
|
-
if parms.text != "speed":
|
48
|
-
break
|
49
|
-
|
50
|
-
if j > 0 and parms.tag == "value":
|
51
|
-
if parms.text is None:
|
52
|
-
log.error("<value>: number required")
|
53
|
-
return float(parms.text) / 100
|
54
|
-
|
55
|
-
return 1.0
|
56
|
-
|
57
|
-
|
58
|
-
def uri_to_path(uri: str) -> str:
|
59
|
-
# Handle inputs like:
|
60
|
-
# /Users/wyattblue/projects/auto-editor/example.mp4
|
61
|
-
# file:///Users/wyattblue/projects/auto-editor/example.mp4
|
62
|
-
# file:///C:/Users/WyattBlue/projects/auto-editor/example.mp4
|
63
|
-
# file://localhost/Users/wyattblue/projects/auto-editor/example.mp4
|
64
|
-
|
65
|
-
if uri.startswith("file://localhost/"):
|
66
|
-
uri = uri[16:]
|
67
|
-
elif uri.startswith("file://"):
|
68
|
-
# Windows-style paths
|
69
|
-
uri = uri[8:] if len(uri) > 8 and uri[9] == ":" else uri[7:]
|
70
|
-
else:
|
71
|
-
return uri
|
72
|
-
return unquote(uri)
|
73
|
-
|
74
|
-
|
75
|
-
def read_tb_ntsc(tb: int, ntsc: bool) -> Fraction:
|
76
|
-
if ntsc:
|
77
|
-
if tb == 24:
|
78
|
-
return Fraction(24000, 1001)
|
79
|
-
if tb == 30:
|
80
|
-
return Fraction(30000, 1001)
|
81
|
-
if tb == 60:
|
82
|
-
return Fraction(60000, 1001)
|
83
|
-
return tb * Fraction(999, 1000)
|
84
|
-
|
85
|
-
return Fraction(tb)
|
86
|
-
|
87
|
-
|
88
|
-
def fcp7_read_xml(path: str, log: Log) -> v3:
|
89
|
-
def xml_bool(val: str) -> bool:
|
90
|
-
if val == "TRUE":
|
91
|
-
return True
|
92
|
-
if val == "FALSE":
|
93
|
-
return False
|
94
|
-
raise TypeError("Value must be 'TRUE' or 'FALSE'")
|
95
|
-
|
96
|
-
try:
|
97
|
-
tree = ET.parse(path)
|
98
|
-
except FileNotFoundError:
|
99
|
-
log.error(f"Could not find '{path}'")
|
100
|
-
|
101
|
-
root = tree.getroot()
|
102
|
-
|
103
|
-
def parse(ele: Element, schema: dict) -> dict:
|
104
|
-
new: dict = {}
|
105
|
-
for key, val in schema.items():
|
106
|
-
if isinstance(val, dict) and "__arr" in val:
|
107
|
-
new[key] = []
|
108
|
-
|
109
|
-
is_arr = False
|
110
|
-
for child in ele:
|
111
|
-
if child.tag not in schema:
|
112
|
-
continue
|
113
|
-
|
114
|
-
if schema[child.tag] is None:
|
115
|
-
new[child.tag] = child
|
116
|
-
continue
|
117
|
-
|
118
|
-
if isinstance(schema[child.tag], dict):
|
119
|
-
val = parse(child, schema[child.tag])
|
120
|
-
is_arr = "__arr" in schema[child.tag]
|
121
|
-
else:
|
122
|
-
val = schema[child.tag](child.text)
|
123
|
-
|
124
|
-
if child.tag in new:
|
125
|
-
if not is_arr:
|
126
|
-
log.error(f"<{child.tag}> can only occur once")
|
127
|
-
new[child.tag].append(val)
|
128
|
-
else:
|
129
|
-
new[child.tag] = [val] if is_arr else val
|
130
|
-
|
131
|
-
return new
|
132
|
-
|
133
|
-
def check(ele: Element, tag: str) -> None:
|
134
|
-
if tag != ele.tag:
|
135
|
-
log.error(f"Expected '{tag}' tag, got '{ele.tag}'")
|
136
|
-
|
137
|
-
check(root, "xmeml")
|
138
|
-
check(root[0], "sequence")
|
139
|
-
result = parse(
|
140
|
-
root[0],
|
141
|
-
{
|
142
|
-
"name": str,
|
143
|
-
"duration": int,
|
144
|
-
"rate": {
|
145
|
-
"timebase": Fraction,
|
146
|
-
"ntsc": xml_bool,
|
147
|
-
},
|
148
|
-
"media": None,
|
149
|
-
},
|
150
|
-
)
|
151
|
-
|
152
|
-
tb = read_tb_ntsc(result["rate"]["timebase"], result["rate"]["ntsc"])
|
153
|
-
av = parse(
|
154
|
-
result["media"],
|
155
|
-
{
|
156
|
-
"video": None,
|
157
|
-
"audio": None,
|
158
|
-
},
|
159
|
-
)
|
160
|
-
|
161
|
-
sources: dict[str, FileInfo] = {}
|
162
|
-
vobjs: VSpace = []
|
163
|
-
aobjs: ASpace = []
|
164
|
-
|
165
|
-
vclip_schema = {
|
166
|
-
"format": {
|
167
|
-
"samplecharacteristics": {
|
168
|
-
"width": int,
|
169
|
-
"height": int,
|
170
|
-
},
|
171
|
-
},
|
172
|
-
"track": {
|
173
|
-
"__arr": "",
|
174
|
-
"clipitem": {
|
175
|
-
"__arr": "",
|
176
|
-
"start": int,
|
177
|
-
"end": int,
|
178
|
-
"in": int,
|
179
|
-
"out": int,
|
180
|
-
"file": None,
|
181
|
-
"filter": None,
|
182
|
-
},
|
183
|
-
},
|
184
|
-
}
|
185
|
-
|
186
|
-
aclip_schema = {
|
187
|
-
"format": {"samplecharacteristics": {"samplerate": int}},
|
188
|
-
"track": {
|
189
|
-
"__arr": "",
|
190
|
-
"clipitem": {
|
191
|
-
"__arr": "",
|
192
|
-
"start": int,
|
193
|
-
"end": int,
|
194
|
-
"in": int,
|
195
|
-
"out": int,
|
196
|
-
"file": None,
|
197
|
-
"filter": None,
|
198
|
-
},
|
199
|
-
},
|
200
|
-
}
|
201
|
-
|
202
|
-
sr = 48000
|
203
|
-
res = (1920, 1080)
|
204
|
-
|
205
|
-
if "video" in av:
|
206
|
-
tracks = parse(av["video"], vclip_schema)
|
207
|
-
|
208
|
-
if "format" in tracks:
|
209
|
-
width = tracks["format"]["samplecharacteristics"]["width"]
|
210
|
-
height = tracks["format"]["samplecharacteristics"]["height"]
|
211
|
-
res = width, height
|
212
|
-
|
213
|
-
for t, track in enumerate(tracks["track"]):
|
214
|
-
if len(track["clipitem"]) > 0:
|
215
|
-
vobjs.append([])
|
216
|
-
for clipitem in track["clipitem"]:
|
217
|
-
file_id = clipitem["file"].attrib["id"]
|
218
|
-
if file_id not in sources:
|
219
|
-
fileobj = parse(clipitem["file"], {"pathurl": str})
|
220
|
-
|
221
|
-
if "pathurl" in fileobj:
|
222
|
-
sources[file_id] = FileInfo.init(
|
223
|
-
uri_to_path(fileobj["pathurl"]),
|
224
|
-
log,
|
225
|
-
)
|
226
|
-
else:
|
227
|
-
show(clipitem["file"], 3)
|
228
|
-
log.error(
|
229
|
-
f"'pathurl' child element not found in {clipitem['file'].tag}"
|
230
|
-
)
|
231
|
-
|
232
|
-
if "filter" in clipitem:
|
233
|
-
speed = read_filters(clipitem["filter"], log)
|
234
|
-
else:
|
235
|
-
speed = 1.0
|
236
|
-
|
237
|
-
start = clipitem["start"]
|
238
|
-
dur = clipitem["end"] - start
|
239
|
-
offset = clipitem["in"]
|
240
|
-
|
241
|
-
vobjs[t].append(
|
242
|
-
Clip(start, dur, sources[file_id], offset, stream=0, speed=speed)
|
243
|
-
)
|
244
|
-
|
245
|
-
if "audio" in av:
|
246
|
-
tracks = parse(av["audio"], aclip_schema)
|
247
|
-
if "format" in tracks:
|
248
|
-
sr = tracks["format"]["samplecharacteristics"]["samplerate"]
|
249
|
-
|
250
|
-
for t, track in enumerate(tracks["track"]):
|
251
|
-
if len(track["clipitem"]) > 0:
|
252
|
-
aobjs.append([])
|
253
|
-
for clipitem in track["clipitem"]:
|
254
|
-
file_id = clipitem["file"].attrib["id"]
|
255
|
-
if file_id not in sources:
|
256
|
-
fileobj = parse(clipitem["file"], {"pathurl": str})
|
257
|
-
sources[file_id] = FileInfo.init(
|
258
|
-
uri_to_path(fileobj["pathurl"]), log
|
259
|
-
)
|
260
|
-
|
261
|
-
if "filter" in clipitem:
|
262
|
-
speed = read_filters(clipitem["filter"], log)
|
263
|
-
else:
|
264
|
-
speed = 1.0
|
265
|
-
|
266
|
-
start = clipitem["start"]
|
267
|
-
dur = clipitem["end"] - start
|
268
|
-
offset = clipitem["in"]
|
269
|
-
|
270
|
-
aobjs[t].append(
|
271
|
-
Clip(start, dur, sources[file_id], offset, stream=0, speed=speed)
|
272
|
-
)
|
273
|
-
|
274
|
-
T = Template.init(sources[next(iter(sources))], sr, res=res)
|
275
|
-
return v3(tb, "#000", T, vobjs, aobjs, v1=None)
|