auto-editor 25.0.0__py3-none-any.whl → 25.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.
- auto_editor/__init__.py +1 -1
- auto_editor/__main__.py +3 -1
- auto_editor/edit.py +0 -1
- auto_editor/ffwrapper.py +3 -1
- auto_editor/subcommands/info.py +2 -2
- auto_editor/subcommands/test.py +9 -1
- auto_editor/utils/container.py +2 -0
- auto_editor/validate_input.py +12 -7
- {auto_editor-25.0.0.dist-info → auto_editor-25.0.1.dist-info}/METADATA +1 -1
- {auto_editor-25.0.0.dist-info → auto_editor-25.0.1.dist-info}/RECORD +14 -14
- {auto_editor-25.0.0.dist-info → auto_editor-25.0.1.dist-info}/WHEEL +1 -1
- {auto_editor-25.0.0.dist-info → auto_editor-25.0.1.dist-info}/LICENSE +0 -0
- {auto_editor-25.0.0.dist-info → auto_editor-25.0.1.dist-info}/entry_points.txt +0 -0
- {auto_editor-25.0.0.dist-info → auto_editor-25.0.1.dist-info}/top_level.txt +0 -0
auto_editor/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "25.0.
|
1
|
+
__version__ = "25.0.1"
|
auto_editor/__main__.py
CHANGED
@@ -305,9 +305,11 @@ def main() -> None:
|
|
305
305
|
|
306
306
|
import av
|
307
307
|
|
308
|
+
license = av._core.library_meta["libavcodec"]["license"]
|
309
|
+
|
308
310
|
print(f"OS: {plat.system()} {plat.release()} {plat.machine().lower()}")
|
309
311
|
print(f"Python: {plat.python_version()}")
|
310
|
-
print(f"PyAV: {av.__version__}")
|
312
|
+
print(f"PyAV: {av.__version__} ({license})")
|
311
313
|
print(f"Auto-Editor: {auto_editor.__version__}")
|
312
314
|
return
|
313
315
|
|
auto_editor/edit.py
CHANGED
@@ -262,7 +262,6 @@ def edit_media(paths: list[str], ffmpeg: FFmpeg, args: Args, log: Log) -> None:
|
|
262
262
|
apply_later = False
|
263
263
|
|
264
264
|
ensure = Ensure(ffmpeg, bar, samplerate, log)
|
265
|
-
|
266
265
|
if ctr.default_sub != "none" and not args.sn:
|
267
266
|
sub_output = make_new_subtitles(tl, ensure, log.temp)
|
268
267
|
|
auto_editor/ffwrapper.py
CHANGED
@@ -149,6 +149,7 @@ class VideoStream:
|
|
149
149
|
class AudioStream:
|
150
150
|
codec: str
|
151
151
|
samplerate: int
|
152
|
+
layout: str
|
152
153
|
channels: int
|
153
154
|
duration: float
|
154
155
|
bitrate: int
|
@@ -195,7 +196,7 @@ def initFileInfo(path: str, log: Log) -> FileInfo:
|
|
195
196
|
try:
|
196
197
|
cont = av.open(path, "r")
|
197
198
|
except av.error.FileNotFoundError:
|
198
|
-
log.error(f"
|
199
|
+
log.error(f"Input file doesn't exist: {path}")
|
199
200
|
except av.error.IsADirectoryError:
|
200
201
|
log.error(f"Expected a media file, but got a directory: {path}")
|
201
202
|
except av.error.InvalidDataError:
|
@@ -252,6 +253,7 @@ def initFileInfo(path: str, log: Log) -> FileInfo:
|
|
252
253
|
AudioStream(
|
253
254
|
a_cc.name,
|
254
255
|
0 if a_cc.sample_rate is None else a_cc.sample_rate,
|
256
|
+
a.layout.name,
|
255
257
|
a_cc.channels,
|
256
258
|
adur,
|
257
259
|
0 if a_cc.bit_rate is None else a_cc.bit_rate,
|
auto_editor/subcommands/info.py
CHANGED
@@ -47,7 +47,7 @@ class VideoJson(TypedDict):
|
|
47
47
|
class AudioJson(TypedDict):
|
48
48
|
codec: str
|
49
49
|
samplerate: int
|
50
|
-
|
50
|
+
layout: str
|
51
51
|
duration: float
|
52
52
|
bitrate: int
|
53
53
|
lang: str | None
|
@@ -150,8 +150,8 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None:
|
|
150
150
|
for track, a in enumerate(src.audios):
|
151
151
|
aud: AudioJson = {
|
152
152
|
"codec": a.codec,
|
153
|
+
"layout": a.layout,
|
153
154
|
"samplerate": a.samplerate,
|
154
|
-
"channels": a.channels,
|
155
155
|
"duration": a.duration,
|
156
156
|
"bitrate": a.bitrate,
|
157
157
|
"lang": a.lang,
|
auto_editor/subcommands/test.py
CHANGED
@@ -309,7 +309,7 @@ def main(sys_args: list[str] | None = None):
|
|
309
309
|
"""Input file must have an extension. Throw error if none is given."""
|
310
310
|
|
311
311
|
shutil.copy("example.mp4", "example")
|
312
|
-
run.check(["example", "--no-open"], "must have an extension
|
312
|
+
run.check(["example", "--no-open"], "must have an extension")
|
313
313
|
|
314
314
|
return "example"
|
315
315
|
|
@@ -355,6 +355,13 @@ def main(sys_args: list[str] | None = None):
|
|
355
355
|
def premiere_named_export():
|
356
356
|
run.main(["example.mp4"], ["--export", 'premiere:name="Foo Bar"'])
|
357
357
|
|
358
|
+
def export_subtitles():
|
359
|
+
cn = fileinfo(run.main(["resources/subtitle.mp4"], []))
|
360
|
+
|
361
|
+
assert len(cn.videos) == 1
|
362
|
+
assert len(cn.audios) == 1
|
363
|
+
assert len(cn.subtitles) == 1
|
364
|
+
|
358
365
|
def resolution_and_scale():
|
359
366
|
cn = fileinfo(run.main(["example.mp4"], ["--scale", "1.5"]))
|
360
367
|
|
@@ -743,6 +750,7 @@ def main(sys_args: list[str] | None = None):
|
|
743
750
|
track_tests,
|
744
751
|
codec_tests,
|
745
752
|
premiere_named_export,
|
753
|
+
export_subtitles,
|
746
754
|
export,
|
747
755
|
motion,
|
748
756
|
resolution_and_scale,
|
auto_editor/utils/container.py
CHANGED
@@ -72,6 +72,8 @@ def container_constructor(ext: str) -> Container:
|
|
72
72
|
vdefault = container.default_video_codec
|
73
73
|
adefault = container.default_audio_codec
|
74
74
|
sdefault = container.default_subtitle_codec
|
75
|
+
if sdefault == "none" and ext == "mp4":
|
76
|
+
sdefault = "srt"
|
75
77
|
|
76
78
|
vcodecs = set()
|
77
79
|
acodecs = set()
|
auto_editor/validate_input.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
import os
|
4
3
|
import re
|
5
4
|
import subprocess
|
6
5
|
import sys
|
6
|
+
from os.path import exists, isdir, isfile, lexists, splitext
|
7
7
|
|
8
8
|
from auto_editor.ffwrapper import FFmpeg
|
9
9
|
from auto_editor.utils.func import get_stdout
|
@@ -27,7 +27,7 @@ def download_video(my_input: str, args: Args, ffmpeg: FFmpeg, log: Log) -> str:
|
|
27
27
|
download_format = "bestvideo[ext=mp4]+bestaudio[ext=m4a]"
|
28
28
|
|
29
29
|
if args.output_format is None:
|
30
|
-
output_format = re.sub(r"\W+", "-",
|
30
|
+
output_format = re.sub(r"\W+", "-", splitext(my_input)[0]) + ".%(ext)s"
|
31
31
|
else:
|
32
32
|
output_format = args.output_format
|
33
33
|
|
@@ -57,10 +57,10 @@ def download_video(my_input: str, args: Args, ffmpeg: FFmpeg, log: Log) -> str:
|
|
57
57
|
msg += "pip or your favorite package manager and make sure it's in PATH."
|
58
58
|
log.error(msg)
|
59
59
|
|
60
|
-
if not
|
60
|
+
if not isfile(location):
|
61
61
|
subprocess.run([yt_dlp_path] + cmd)
|
62
62
|
|
63
|
-
if not
|
63
|
+
if not isfile(location):
|
64
64
|
log.error(f"Download file wasn't created: {location}")
|
65
65
|
|
66
66
|
return location
|
@@ -73,11 +73,16 @@ def valid_input(inputs: list[str], ffmpeg: FFmpeg, args: Args, log: Log) -> list
|
|
73
73
|
if my_input.startswith("http://") or my_input.startswith("https://"):
|
74
74
|
result.append(download_video(my_input, args, ffmpeg, log))
|
75
75
|
else:
|
76
|
-
_, ext =
|
76
|
+
_, ext = splitext(my_input)
|
77
77
|
if ext == "":
|
78
|
-
if
|
78
|
+
if isdir(my_input):
|
79
79
|
log.error("Input must be a file or a URL, not a directory.")
|
80
|
-
|
80
|
+
if exists(my_input):
|
81
|
+
log.error(f"Input file must have an extension: {my_input}")
|
82
|
+
if lexists(my_input):
|
83
|
+
log.error(f"Input file is a broken symbolic link: {my_input}")
|
84
|
+
if my_input.startswith("-"):
|
85
|
+
log.error(f"Option/Input file doesn't exist: {my_input}")
|
81
86
|
result.append(my_input)
|
82
87
|
|
83
88
|
return result
|
@@ -1,14 +1,14 @@
|
|
1
|
-
auto_editor/__init__.py,sha256=
|
2
|
-
auto_editor/__main__.py,sha256=
|
1
|
+
auto_editor/__init__.py,sha256=HQ6qfTf_xOT2gRqJKN_PWXCV49oRXl228FqZ7w9Haeg,23
|
2
|
+
auto_editor/__main__.py,sha256=aXFUlP7v15CzBeYtLdEPyIX2hxtynXo_UKWUQlxQGbM,9852
|
3
3
|
auto_editor/analyze.py,sha256=pHoSZ_-wyV1hLJyJpPg9Ha7oecjdGHGJ0a4hbKnb9NY,11779
|
4
|
-
auto_editor/edit.py,sha256=
|
5
|
-
auto_editor/ffwrapper.py,sha256=
|
4
|
+
auto_editor/edit.py,sha256=fe6YT6O8B_hPOb4r4FdubvswbTuyx4_qlzlJTyMKuVc,11267
|
5
|
+
auto_editor/ffwrapper.py,sha256=NnhD4TvKyaap0Y2MQ7aIUQfeLJwfNbjTj5bLUpoMEI4,7888
|
6
6
|
auto_editor/help.py,sha256=BFiP7vBz42TUzum4-zaQIrV1OY7kHeN0pe0MPE0T5xw,7997
|
7
7
|
auto_editor/make_layers.py,sha256=ybTxPRD6bDbEX-7e9qu4OYUvYkrdNb4BjnN9hzwkRiQ,8496
|
8
8
|
auto_editor/output.py,sha256=D8NCJwwmcjDf5rvoBnWKu5XY7QtxF3thxbnTxKAxGu8,8043
|
9
9
|
auto_editor/preview.py,sha256=noWkgyzdE14zwG8ZDYxLDual5iVt6zYTt4HTe-QAgFY,3029
|
10
10
|
auto_editor/timeline.py,sha256=d9Qhup2pBwsj7j9kF-Iw22xHbQvGx-keDq2eLI11Mt4,7117
|
11
|
-
auto_editor/validate_input.py,sha256=
|
11
|
+
auto_editor/validate_input.py,sha256=_9vtbNxodhVPf4PzTAH67LSj2K-HS6kShJOARmUMJdY,2904
|
12
12
|
auto_editor/vanparse.py,sha256=f0vViZ-aYtDxEyVrFHJ5X2pPTQAfqtw3N2gZgzn51kU,10002
|
13
13
|
auto_editor/wavfile.py,sha256=7N2LX_WfFVRnoXrKveLvuyTYpIz2htpGqfCD8tR4kJ8,9168
|
14
14
|
auto_editor/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -31,25 +31,25 @@ auto_editor/render/subtitle.py,sha256=g195kDN0LcwKlZeQMCflXPH5n_74iwCk1RPLSQ5eP3
|
|
31
31
|
auto_editor/render/video.py,sha256=gMVcLehC_QpdtIzNLR_7tv2CZmYeEWisS_5as4ceHV0,12971
|
32
32
|
auto_editor/subcommands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
33
|
auto_editor/subcommands/desc.py,sha256=GDrKJYiHMaeTrplZAceXl1JwoqD78XsV2_5lc0Xd7po,869
|
34
|
-
auto_editor/subcommands/info.py,sha256=
|
34
|
+
auto_editor/subcommands/info.py,sha256=t5n43HLt9hpMFSIfGV777X4zIPBAFugOKlpCfRjiKxY,6921
|
35
35
|
auto_editor/subcommands/levels.py,sha256=ZB8_9jbOA5s1AQUcUNZDiLAjyJOKl7Be2YeVWdkOr0Q,4071
|
36
36
|
auto_editor/subcommands/palet.py,sha256=tbQoRWoT4jR3yu0etGApfprM-oQgXIjC-rIY-QG3nM0,655
|
37
37
|
auto_editor/subcommands/repl.py,sha256=OfxIOBjE7W12UemfaaxMnzHcmV5cUTt7g5328R7rAYU,3116
|
38
38
|
auto_editor/subcommands/subdump.py,sha256=af_XBf7kaevqHn1A71z8C-7x8pS5WKD9FE_ugkCw6rk,665
|
39
|
-
auto_editor/subcommands/test.py,sha256=
|
39
|
+
auto_editor/subcommands/test.py,sha256=d-StLyIZHkvJVaiXmr1gYTzUIwLhbG34tJfYosobmps,25227
|
40
40
|
auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
41
|
auto_editor/utils/bar.py,sha256=RJqkJ8gNr8op_Z-2hh48ExjSonmTPX-RshctK_itv14,3988
|
42
42
|
auto_editor/utils/chunks.py,sha256=J-eGKtEz68gFtRrj1kOSgH4Tj_Yz6prNQ7Xr-d9NQJw,52
|
43
43
|
auto_editor/utils/cmdkw.py,sha256=XApxw7FZBOEJV9N4LHhdw1GVfHbFfCjr-zCZ1gJsSvY,6002
|
44
|
-
auto_editor/utils/container.py,sha256=
|
44
|
+
auto_editor/utils/container.py,sha256=RnpoMmMYmn7o69LmMbBFHW4TsP3K52jYDhG9qzWXmAs,2720
|
45
45
|
auto_editor/utils/encoder.py,sha256=auNYo7HXbcU4iTUCc0LE5lpwFmSvdWvBm6-5KIaRK8w,2983
|
46
46
|
auto_editor/utils/func.py,sha256=kcxCOqe-tg6k-kxutIran8LpffRiHDjKB6rm-ngFiSU,4460
|
47
47
|
auto_editor/utils/log.py,sha256=M2QKeQHMRNLm3HMVUKedZPRprT2u5dipOStiO4miPBk,3613
|
48
48
|
auto_editor/utils/subtitle_tools.py,sha256=TjjVPiT8bWzZJcrZjF7ddpgfIsVkLE4LyxXzBswHAGU,693
|
49
49
|
auto_editor/utils/types.py,sha256=JdAwfuT9Ty_FXUm89GUTo0M8FPFrXbqnlk-g4pWP1_k,11609
|
50
|
-
auto_editor-25.0.
|
51
|
-
auto_editor-25.0.
|
52
|
-
auto_editor-25.0.
|
53
|
-
auto_editor-25.0.
|
54
|
-
auto_editor-25.0.
|
55
|
-
auto_editor-25.0.
|
50
|
+
auto_editor-25.0.1.dist-info/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
|
51
|
+
auto_editor-25.0.1.dist-info/METADATA,sha256=FsEPvrdesILZ7duMkfSr7kRBhXEEN6dJ2ttjSr4Z9qw,6137
|
52
|
+
auto_editor-25.0.1.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
53
|
+
auto_editor-25.0.1.dist-info/entry_points.txt,sha256=-H7zdTw4MqnAcwrN5xTNkGIhzZtJMxS9r6lTMeR9-aA,240
|
54
|
+
auto_editor-25.0.1.dist-info/top_level.txt,sha256=ky1HUkqq9i034c4CUU_0wBw0xZsxxyGEak1eTbdvpyA,12
|
55
|
+
auto_editor-25.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|