talks-reducer 0.3.3__py3-none-any.whl → 0.3.5__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.
- talks_reducer/__about__.py +5 -0
- talks_reducer/__init__.py +2 -1
- talks_reducer/cli.py +19 -5
- talks_reducer/gui.py +18 -10
- {talks_reducer-0.3.3.dist-info → talks_reducer-0.3.5.dist-info}/METADATA +71 -70
- talks_reducer-0.3.5.dist-info/RECORD +17 -0
- talks_reducer-0.3.3.dist-info/RECORD +0 -16
- {talks_reducer-0.3.3.dist-info → talks_reducer-0.3.5.dist-info}/WHEEL +0 -0
- {talks_reducer-0.3.3.dist-info → talks_reducer-0.3.5.dist-info}/entry_points.txt +0 -0
- {talks_reducer-0.3.3.dist-info → talks_reducer-0.3.5.dist-info}/licenses/LICENSE +0 -0
- {talks_reducer-0.3.3.dist-info → talks_reducer-0.3.5.dist-info}/top_level.txt +0 -0
talks_reducer/__init__.py
CHANGED
talks_reducer/cli.py
CHANGED
@@ -7,11 +7,16 @@ import os
|
|
7
7
|
import sys
|
8
8
|
import time
|
9
9
|
from importlib import import_module
|
10
|
-
from importlib.metadata import version
|
10
|
+
from importlib.metadata import PackageNotFoundError, version
|
11
11
|
from pathlib import Path
|
12
12
|
from typing import Dict, List, Optional, Sequence
|
13
13
|
|
14
14
|
from . import audio
|
15
|
+
|
16
|
+
try:
|
17
|
+
from .__about__ import __version__ as _about_version
|
18
|
+
except Exception: # pragma: no cover - fallback if metadata file missing
|
19
|
+
_about_version = ""
|
15
20
|
from .ffmpeg import FFmpegNotFoundError
|
16
21
|
from .models import ProcessingOptions
|
17
22
|
from .pipeline import speed_up_video
|
@@ -26,10 +31,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
26
31
|
)
|
27
32
|
|
28
33
|
# Add version argument
|
29
|
-
|
30
|
-
pkg_version = version("talks-reducer")
|
31
|
-
except Exception:
|
32
|
-
pkg_version = "unknown"
|
34
|
+
pkg_version = _resolve_version()
|
33
35
|
|
34
36
|
parser.add_argument(
|
35
37
|
"--version",
|
@@ -99,6 +101,18 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
99
101
|
return parser
|
100
102
|
|
101
103
|
|
104
|
+
def _resolve_version() -> str:
|
105
|
+
"""Determine the package version for CLI reporting."""
|
106
|
+
|
107
|
+
if _about_version:
|
108
|
+
return _about_version
|
109
|
+
|
110
|
+
try:
|
111
|
+
return version("talks-reducer")
|
112
|
+
except (PackageNotFoundError, Exception):
|
113
|
+
return "unknown"
|
114
|
+
|
115
|
+
|
102
116
|
def gather_input_files(paths: List[str]) -> List[str]:
|
103
117
|
"""Expand provided paths into a flat list of files that contain audio streams."""
|
104
118
|
|
talks_reducer/gui.py
CHANGED
@@ -386,7 +386,7 @@ class TalksReducerGUI:
|
|
386
386
|
|
387
387
|
self.drop_zone = self.tk.Label(
|
388
388
|
input_frame,
|
389
|
-
text="Drop
|
389
|
+
text="Drop video here",
|
390
390
|
relief=self.tk.FLAT,
|
391
391
|
borderwidth=0,
|
392
392
|
padx=self.PADDING,
|
@@ -986,12 +986,12 @@ class TalksReducerGUI:
|
|
986
986
|
self._last_output = result.output_file
|
987
987
|
self._last_time_ratio = result.time_ratio
|
988
988
|
self._last_size_ratio = result.size_ratio
|
989
|
-
|
989
|
+
|
990
990
|
# Create completion message with ratios if available
|
991
991
|
completion_msg = f"Completed: {result.output_file}"
|
992
992
|
if result.time_ratio is not None and result.size_ratio is not None:
|
993
993
|
completion_msg += f" (Time: {result.time_ratio:.2%}, Size: {result.size_ratio:.2%})"
|
994
|
-
|
994
|
+
|
995
995
|
self._append_log(completion_msg)
|
996
996
|
if open_after_convert:
|
997
997
|
self._notify(
|
@@ -1151,7 +1151,7 @@ class TalksReducerGUI:
|
|
1151
1151
|
status_msg = "Success"
|
1152
1152
|
if self._last_time_ratio is not None and self._last_size_ratio is not None:
|
1153
1153
|
status_msg = f"Time: {self._last_time_ratio:.0%}, Size: {self._last_size_ratio:.0%}"
|
1154
|
-
|
1154
|
+
|
1155
1155
|
self._set_status("success", status_msg)
|
1156
1156
|
self._set_progress(100) # 100% on success
|
1157
1157
|
self._video_duration_seconds = None # Reset for next video
|
@@ -1191,7 +1191,9 @@ class TalksReducerGUI:
|
|
1191
1191
|
percentage = min(
|
1192
1192
|
100, int((current_seconds / self._video_duration_seconds) * 100)
|
1193
1193
|
)
|
1194
|
-
self._set_status(
|
1194
|
+
self._set_status(
|
1195
|
+
"processing", f"{time_str}, {speed_str}x ({percentage}%)"
|
1196
|
+
)
|
1195
1197
|
self._set_progress(percentage) # Update progress bar
|
1196
1198
|
else:
|
1197
1199
|
self._set_status("processing", f"{time_str}, {speed_str}x")
|
@@ -1204,9 +1206,11 @@ class TalksReducerGUI:
|
|
1204
1206
|
# For extracting audio or FFmpeg progress messages, use processing color
|
1205
1207
|
# Also handle the new "Time: X%, Size: Y%" format as success
|
1206
1208
|
status_lower = status.lower()
|
1207
|
-
if (
|
1208
|
-
|
1209
|
-
("
|
1209
|
+
if (
|
1210
|
+
"extracting audio" in status_lower
|
1211
|
+
or re.search(r"\d{2}:\d{2}:\d{2}.*\d+\.?\d*x", status)
|
1212
|
+
or ("time:" in status_lower and "size:" in status_lower)
|
1213
|
+
):
|
1210
1214
|
if "time:" in status_lower and "size:" in status_lower:
|
1211
1215
|
# This is our new success format with ratios
|
1212
1216
|
self.status_label.configure(fg=STATUS_COLORS["success"])
|
@@ -1219,7 +1223,9 @@ class TalksReducerGUI:
|
|
1219
1223
|
# Use status_msg if provided, otherwise use status
|
1220
1224
|
display_text = status_msg if status_msg else status
|
1221
1225
|
self.status_var.set(display_text)
|
1222
|
-
self._apply_status_style(
|
1226
|
+
self._apply_status_style(
|
1227
|
+
status
|
1228
|
+
) # Colors depend on status, not display text
|
1223
1229
|
self._set_progress_bar_style(status)
|
1224
1230
|
lowered = status.lower()
|
1225
1231
|
is_processing = lowered == "processing" or "extracting audio" in lowered
|
@@ -1333,7 +1339,9 @@ class TalksReducerGUI:
|
|
1333
1339
|
def updater() -> None:
|
1334
1340
|
# Map status to progress bar style
|
1335
1341
|
status_lower = status.lower()
|
1336
|
-
if status_lower == "success" or (
|
1342
|
+
if status_lower == "success" or (
|
1343
|
+
"time:" in status_lower and "size:" in status_lower
|
1344
|
+
):
|
1337
1345
|
style = "Success.Horizontal.TProgressbar"
|
1338
1346
|
elif status_lower == "error":
|
1339
1347
|
style = "Error.Horizontal.TProgressbar"
|
@@ -1,70 +1,71 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: talks-reducer
|
3
|
-
Version: 0.3.
|
4
|
-
Summary: CLI for speeding up long-form talks by removing silence
|
5
|
-
Author: Talks Reducer Maintainers
|
6
|
-
License-Expression: MIT
|
7
|
-
Requires-Python: >=3.9
|
8
|
-
Description-Content-Type: text/markdown
|
9
|
-
License-File: LICENSE
|
10
|
-
Requires-Dist: audiotsm>=0.1.2
|
11
|
-
Requires-Dist: scipy>=1.10.0
|
12
|
-
Requires-Dist: numpy>=1.22.0
|
13
|
-
Requires-Dist: tqdm>=4.65.0
|
14
|
-
Requires-Dist: tkinterdnd2>=0.3.0
|
15
|
-
Requires-Dist: Pillow>=9.0.0
|
16
|
-
Requires-Dist: imageio-ffmpeg>=0.4.8
|
17
|
-
Provides-Extra: dev
|
18
|
-
Requires-Dist: build>=1.0.0; extra == "dev"
|
19
|
-
Requires-Dist: twine>=4.0.0; extra == "dev"
|
20
|
-
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
21
|
-
Requires-Dist: black>=23.0.0; extra == "dev"
|
22
|
-
Requires-Dist: isort>=5.12.0; extra == "dev"
|
23
|
-
Requires-Dist:
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Talks Reducer
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
- 1h
|
35
|
-
- 1h 19m,
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
- **
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: talks-reducer
|
3
|
+
Version: 0.3.5
|
4
|
+
Summary: CLI for speeding up long-form talks by removing silence
|
5
|
+
Author: Talks Reducer Maintainers
|
6
|
+
License-Expression: MIT
|
7
|
+
Requires-Python: >=3.9
|
8
|
+
Description-Content-Type: text/markdown
|
9
|
+
License-File: LICENSE
|
10
|
+
Requires-Dist: audiotsm>=0.1.2
|
11
|
+
Requires-Dist: scipy>=1.10.0
|
12
|
+
Requires-Dist: numpy>=1.22.0
|
13
|
+
Requires-Dist: tqdm>=4.65.0
|
14
|
+
Requires-Dist: tkinterdnd2>=0.3.0
|
15
|
+
Requires-Dist: Pillow>=9.0.0
|
16
|
+
Requires-Dist: imageio-ffmpeg>=0.4.8
|
17
|
+
Provides-Extra: dev
|
18
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
19
|
+
Requires-Dist: twine>=4.0.0; extra == "dev"
|
20
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
21
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
22
|
+
Requires-Dist: isort>=5.12.0; extra == "dev"
|
23
|
+
Requires-Dist: bump-my-version>=0.5.0; extra == "dev"
|
24
|
+
Requires-Dist: pyinstaller>=6.0.0; extra == "dev"
|
25
|
+
Dynamic: license-file
|
26
|
+
|
27
|
+
# Talks Reducer
|
28
|
+
Talks Reducer shortens long-form presentations by removing silent gaps and optionally re-encoding them to smaller files. The
|
29
|
+
project was renamed from **jumpcutter** to emphasize its focus on conference talks and screencasts.
|
30
|
+
|
31
|
+

|
32
|
+
|
33
|
+
## Example
|
34
|
+
- 1h 37m, 571 MB — Original OBS video recording
|
35
|
+
- 1h 19m, 751 MB — Talks Reducer
|
36
|
+
- 1h 19m, 171 MB — Talks Reducer `--small`
|
37
|
+
|
38
|
+
## Changelog
|
39
|
+
|
40
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
41
|
+
|
42
|
+
## Install GUI (Windows, macOS)
|
43
|
+
Go to the [releases page](https://github.com/popstas/talks-reducer/releases) and download the appropriate artifact:
|
44
|
+
|
45
|
+
- **Windows** — `talks-reducer-windows.zip`
|
46
|
+
- **macOS** — `talks-reducer.app.zip` (but it doesn't work for me)
|
47
|
+
|
48
|
+
## Install CLI (Linux, Windows, macOS)
|
49
|
+
```
|
50
|
+
pip install talks-reducer
|
51
|
+
```
|
52
|
+
|
53
|
+
**Note:** FFmpeg is now bundled automatically with the package, so you don't need to install it separately. You you need, don't know actually.
|
54
|
+
|
55
|
+
The `--small` preset applies a 720p video scale and 128 kbps audio bitrate, making it useful for sharing talks over constrained
|
56
|
+
connections. Without `--small`, the script aims to preserve original quality while removing silence.
|
57
|
+
|
58
|
+
Example CLI usage:
|
59
|
+
|
60
|
+
```sh
|
61
|
+
talks-reducer --small input.mp4
|
62
|
+
```
|
63
|
+
|
64
|
+
When CUDA-capable hardware is available the pipeline leans on GPU encoders to keep export times low, but it still runs great on
|
65
|
+
CPUs.
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
See `CONTRIBUTION.md` for development setup details and guidance on sharing improvements.
|
69
|
+
|
70
|
+
## License
|
71
|
+
Talks Reducer is released under the MIT License. See `LICENSE` for the full text.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
talks_reducer/__about__.py,sha256=Pu7V_1mwVcMr0GN-D_gDEEmMod7EV9DzhaAm-O0EW-0,92
|
2
|
+
talks_reducer/__init__.py,sha256=Kzh1hXaw6Vq3DyTqrnJGOq8pn0P8lvaDcsg1bFUjFKk,208
|
3
|
+
talks_reducer/__main__.py,sha256=azR_vh8HFPLaOnh-L6gUFWsL67I6iHtbeH5rQhsipGY,299
|
4
|
+
talks_reducer/audio.py,sha256=sjHMeY0H9ESG-Gn5BX0wFRBX7sXjWwsgS8u9Vb0bJ88,4396
|
5
|
+
talks_reducer/chunks.py,sha256=IpdZxRFPURSG5wP-OQ_p09CVP8wcKwIFysV29zOTSWI,2959
|
6
|
+
talks_reducer/cli.py,sha256=OYmahiEo7ivhix4861pN9Kp1DkRvU7WBj6fBE2cVVWU,7377
|
7
|
+
talks_reducer/ffmpeg.py,sha256=CVrxwNcWHrzvxTzoALtx5UdNWXxxfOFYF3FES7lvaO4,11680
|
8
|
+
talks_reducer/gui.py,sha256=xsJj1uO1WX14rNVSrkQf2b4K6BdNDbeZ-A1bB0fsSIM,54463
|
9
|
+
talks_reducer/models.py,sha256=vdQLliiHKUuYtNlZzS796kGK39cbtjkUfYcT95KwwKE,1197
|
10
|
+
talks_reducer/pipeline.py,sha256=nfAX8dooN3-009WqMyYTv4nINNMtVmbWtsmzQeBM9Wg,9415
|
11
|
+
talks_reducer/progress.py,sha256=Mh43M6VWhjjUv9CI22xfD2EJ_7Aq3PCueqefQ9Bd5-o,4565
|
12
|
+
talks_reducer-0.3.5.dist-info/licenses/LICENSE,sha256=jN17mHNR3e84awmH3AbpWBcBDBzPxEH0rcOFoj1s7sQ,1124
|
13
|
+
talks_reducer-0.3.5.dist-info/METADATA,sha256=RMh8bCSQ1yCh3ZEwh59cwPuzIxYow1gIuQnDrFJ5lhk,2443
|
14
|
+
talks_reducer-0.3.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
+
talks_reducer-0.3.5.dist-info/entry_points.txt,sha256=LCzfSnh_7VXhvl9twoFSAj0C3sG7bayWs2LkxpH7hoI,100
|
16
|
+
talks_reducer-0.3.5.dist-info/top_level.txt,sha256=pJWGcy__LR9JIEKH3QJyFmk9XrIsiFtqvuMNxFdIzDU,14
|
17
|
+
talks_reducer-0.3.5.dist-info/RECORD,,
|
@@ -1,16 +0,0 @@
|
|
1
|
-
talks_reducer/__init__.py,sha256=lb50C4_o_SLERyMyVpQfgHnXf49FJOIF9j05MZ8KAvM,158
|
2
|
-
talks_reducer/__main__.py,sha256=azR_vh8HFPLaOnh-L6gUFWsL67I6iHtbeH5rQhsipGY,299
|
3
|
-
talks_reducer/audio.py,sha256=sjHMeY0H9ESG-Gn5BX0wFRBX7sXjWwsgS8u9Vb0bJ88,4396
|
4
|
-
talks_reducer/chunks.py,sha256=IpdZxRFPURSG5wP-OQ_p09CVP8wcKwIFysV29zOTSWI,2959
|
5
|
-
talks_reducer/cli.py,sha256=SKQznseHAGQ8yHPk22aO3XtM1wftzxNi26CmKRm-oZE,7000
|
6
|
-
talks_reducer/ffmpeg.py,sha256=CVrxwNcWHrzvxTzoALtx5UdNWXxxfOFYF3FES7lvaO4,11680
|
7
|
-
talks_reducer/gui.py,sha256=qqnZhGbBeOnunpXQG9Z9jIGEhbcglNCaHVHhUwMx9TY,54399
|
8
|
-
talks_reducer/models.py,sha256=vdQLliiHKUuYtNlZzS796kGK39cbtjkUfYcT95KwwKE,1197
|
9
|
-
talks_reducer/pipeline.py,sha256=nfAX8dooN3-009WqMyYTv4nINNMtVmbWtsmzQeBM9Wg,9415
|
10
|
-
talks_reducer/progress.py,sha256=Mh43M6VWhjjUv9CI22xfD2EJ_7Aq3PCueqefQ9Bd5-o,4565
|
11
|
-
talks_reducer-0.3.3.dist-info/licenses/LICENSE,sha256=jN17mHNR3e84awmH3AbpWBcBDBzPxEH0rcOFoj1s7sQ,1124
|
12
|
-
talks_reducer-0.3.3.dist-info/METADATA,sha256=z8XIj-8B0_4AYqkPFos7GnXfo3VRMygQVDAIGvjVgXk,2459
|
13
|
-
talks_reducer-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
14
|
-
talks_reducer-0.3.3.dist-info/entry_points.txt,sha256=LCzfSnh_7VXhvl9twoFSAj0C3sG7bayWs2LkxpH7hoI,100
|
15
|
-
talks_reducer-0.3.3.dist-info/top_level.txt,sha256=pJWGcy__LR9JIEKH3QJyFmk9XrIsiFtqvuMNxFdIzDU,14
|
16
|
-
talks_reducer-0.3.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|