describealign 1.1.0__py3-none-any.whl → 1.1.2__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.
- {describealign-1.1.0.dist-info → describealign-1.1.2.dist-info}/METADATA +14 -13
- describealign-1.1.2.dist-info/RECORD +7 -0
- {describealign-1.1.0.dist-info → describealign-1.1.2.dist-info}/WHEEL +1 -1
- describealign.py +15 -5
- describealign-1.1.0.dist-info/RECORD +0 -7
- {describealign-1.1.0.dist-info → describealign-1.1.2.dist-info}/entry_points.txt +0 -0
- {describealign-1.1.0.dist-info → describealign-1.1.2.dist-info/licenses}/LICENSE +0 -0
- {describealign-1.1.0.dist-info → describealign-1.1.2.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: describealign
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Combines videos with matching audio files (e.g. audio descriptions)
|
|
5
5
|
Author-email: Julian Brown <julbean@proton.me>
|
|
6
6
|
Project-URL: Homepage, https://github.com/julbean/describealign
|
|
@@ -11,17 +11,18 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Requires-Python: >=3.8
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
|
-
Requires-Dist:
|
|
15
|
-
Requires-Dist: static-ffmpeg
|
|
16
|
-
Requires-Dist: matplotlib
|
|
17
|
-
Requires-Dist: numpy
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist: scipy
|
|
20
|
-
Requires-Dist: platformdirs
|
|
21
|
-
Requires-Dist: pytsmod
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
14
|
+
Requires-Dist: ffmpeg_python~=0.2.0
|
|
15
|
+
Requires-Dist: static-ffmpeg~=2.5
|
|
16
|
+
Requires-Dist: matplotlib~=3.5
|
|
17
|
+
Requires-Dist: numpy~=1.21
|
|
18
|
+
Requires-Dist: python_speech_features~=0.6
|
|
19
|
+
Requires-Dist: scipy~=1.10
|
|
20
|
+
Requires-Dist: platformdirs~=4.2
|
|
21
|
+
Requires-Dist: pytsmod~=0.3.7
|
|
22
|
+
Requires-Dist: PySimpleGUIWx~=0.17.2; platform_system == "Windows"
|
|
23
|
+
Requires-Dist: PySimpleGUIQt~=0.35.0; platform_system != "Windows"
|
|
24
|
+
Requires-Dist: PySide2~=5.15; platform_system != "Windows"
|
|
25
|
+
Dynamic: license-file
|
|
25
26
|
|
|
26
27
|
For usage help, simply run the script directly.
|
|
27
28
|
If the Scripts folder has been added to PATH, can be run
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
describealign.py,sha256=d_FI6sjNtUheWmo5GcO28TkqboBAyBau_00162my3VY,69899
|
|
2
|
+
describealign-1.1.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
3
|
+
describealign-1.1.2.dist-info/METADATA,sha256=L_BeZa79bhZNEUbMjkuE35IbRzgIu6R7LEKjl2Jqc7I,1295
|
|
4
|
+
describealign-1.1.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
5
|
+
describealign-1.1.2.dist-info/entry_points.txt,sha256=7o7N6v3r4vFIH_XBdgk7WWhr-vZ_YitY8JWMdzN5xU0,71
|
|
6
|
+
describealign-1.1.2.dist-info/top_level.txt,sha256=VYHWy4TeimBAF5BQAuDj4adGdLaWs2AoYx6qQjGPJ4M,14
|
|
7
|
+
describealign-1.1.2.dist-info/RECORD,,
|
describealign.py
CHANGED
|
@@ -380,7 +380,10 @@ def smooth_align(path, quals, smoothness):
|
|
|
380
380
|
-scipy.sparse.eye(num_fit_points)])
|
|
381
381
|
b_eq = y_diffs[1: ] / x_diffs[1: ] - \
|
|
382
382
|
y_diffs[ :-1] / x_diffs[ :-1]
|
|
383
|
-
fit = scipy.optimize.linprog(c, A_eq=A_eq, b_eq=b_eq)
|
|
383
|
+
fit = scipy.optimize.linprog(c, A_eq=A_eq, b_eq=b_eq, method='highs-ds')
|
|
384
|
+
# if dual simplex solver encounters numerical problems, retry with interior point solver
|
|
385
|
+
if not fit.success and fit.status == 4:
|
|
386
|
+
fit = scipy.optimize.linprog(c, A_eq=A_eq, b_eq=b_eq, method='highs-ipm')
|
|
384
387
|
if not fit.success:
|
|
385
388
|
print(fit)
|
|
386
389
|
raise RuntimeError("Smooth Alignment L1-Min Optimization Failed!")
|
|
@@ -668,7 +671,10 @@ def detect_describer(video_arr, video_spec, video_spec_raw, video_timings,
|
|
|
668
671
|
scipy.sparse.eye(num_fit_points-1),
|
|
669
672
|
-scipy.sparse.eye(num_fit_points-1)])
|
|
670
673
|
b_eq = y_diffs
|
|
671
|
-
fit = scipy.optimize.linprog(c, A_eq=A_eq, b_eq=b_eq)
|
|
674
|
+
fit = scipy.optimize.linprog(c, A_eq=A_eq, b_eq=b_eq, method='highs-ds')
|
|
675
|
+
# if dual simplex solver encounters numerical problems, retry with interior point solver
|
|
676
|
+
if not fit.success and fit.status == 4:
|
|
677
|
+
fit = scipy.optimize.linprog(c, A_eq=A_eq, b_eq=b_eq, method='highs-ipm')
|
|
672
678
|
if not fit.success:
|
|
673
679
|
print(fit)
|
|
674
680
|
raise RuntimeError("Describer Voice Detection L1-Min Optimization Failed!")
|
|
@@ -721,10 +727,10 @@ def encode_fit_as_ffmpeg_expr(smooth_path, clips, video_offset, start_key_frame)
|
|
|
721
727
|
# but that means the video is behind the audio and needs to catch up by playing quicker
|
|
722
728
|
# catchup_spread is the ratio of time to spend catching up to the amount of catching up needed
|
|
723
729
|
catchup_spread = 1./CATCHUP_RATE
|
|
724
|
-
setts_cmd.append(f'+clip(TS-
|
|
730
|
+
setts_cmd.append(f'+clip(TS-{start_key_frame},0,{start_skip*(1+catchup_spread)}/TB)*{-1./(1+catchup_spread)}')
|
|
725
731
|
elif video_offset < 0:
|
|
726
732
|
# if the audio starts before the video, stretch the first frame of the video back to meet it
|
|
727
|
-
setts_cmd.append(f'+clip(TS-
|
|
733
|
+
setts_cmd.append(f'+clip(TS-{start_key_frame},0,{-video_offset/10000.}/TB)*10000')
|
|
728
734
|
# each segment of the linear fit can be encoded as a single clip function
|
|
729
735
|
setts_cmd.append('+(0')
|
|
730
736
|
for clip_start, clip_end in clips:
|
|
@@ -735,7 +741,7 @@ def encode_fit_as_ffmpeg_expr(smooth_path, clips, video_offset, start_key_frame)
|
|
|
735
741
|
audio_desc_length = audio_desc_end - audio_desc_start
|
|
736
742
|
video_length = video_end - video_start
|
|
737
743
|
slope = audio_desc_length / video_length
|
|
738
|
-
setts_cmd.append(f'+clip(TS-
|
|
744
|
+
setts_cmd.append(f'+clip(TS-{start_key_frame}-{video_start:.4f}/TB,0,{max(0,video_length):.4f}/TB)*{slope-1:.9f}')
|
|
739
745
|
setts_cmd.append(')')
|
|
740
746
|
setts_cmd = ''.join(setts_cmd)
|
|
741
747
|
return setts_cmd
|
|
@@ -1202,7 +1208,11 @@ def main_gui():
|
|
|
1202
1208
|
window.enable()
|
|
1203
1209
|
continue
|
|
1204
1210
|
video_files = values['-VIDEO_FILES-'].split(';')
|
|
1211
|
+
if len(video_files) == 1:
|
|
1212
|
+
video_files = video_files[0]
|
|
1205
1213
|
audio_files = values['-AUDIO_FILES-'].split(';')
|
|
1214
|
+
if len(audio_files) == 1:
|
|
1215
|
+
audio_files = audio_files[0]
|
|
1206
1216
|
combine_gui(video_files, audio_files, config_path)
|
|
1207
1217
|
if event == 'Settings':
|
|
1208
1218
|
window.disable()
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
describealign.py,sha256=PU8lZu0zGE7yArhdTX8njT5-JZhylOU_ZVO-soql0Mc,69274
|
|
2
|
-
describealign-1.1.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
3
|
-
describealign-1.1.0.dist-info/METADATA,sha256=NI-ofOnXk29nWuk9iIm50HCRdZxJ8jdeTz364Q2P1M8,1286
|
|
4
|
-
describealign-1.1.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
5
|
-
describealign-1.1.0.dist-info/entry_points.txt,sha256=7o7N6v3r4vFIH_XBdgk7WWhr-vZ_YitY8JWMdzN5xU0,71
|
|
6
|
-
describealign-1.1.0.dist-info/top_level.txt,sha256=VYHWy4TeimBAF5BQAuDj4adGdLaWs2AoYx6qQjGPJ4M,14
|
|
7
|
-
describealign-1.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|