talks-reducer 0.3.2__tar.gz → 0.3.3__tar.gz
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-0.3.3/PKG-INFO +70 -0
- talks_reducer-0.3.3/README.md +45 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/pyproject.toml +1 -1
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/cli.py +9 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/gui.py +41 -42
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/models.py +3 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/pipeline.py +11 -0
- talks_reducer-0.3.3/talks_reducer.egg-info/PKG-INFO +70 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/tests/test_pipeline_service.py +9 -3
- talks_reducer-0.3.2/PKG-INFO +0 -156
- talks_reducer-0.3.2/README.md +0 -131
- talks_reducer-0.3.2/talks_reducer.egg-info/PKG-INFO +0 -156
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/LICENSE +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/setup.cfg +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/__init__.py +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/__main__.py +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/audio.py +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/chunks.py +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/ffmpeg.py +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/progress.py +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/SOURCES.txt +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/dependency_links.txt +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/entry_points.txt +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/requires.txt +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/top_level.txt +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/tests/test_audio.py +0 -0
- {talks_reducer-0.3.2 → talks_reducer-0.3.3}/tests/test_cli.py +0 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: talks-reducer
|
3
|
+
Version: 0.3.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: pyinstaller>=6.0.0; extra == "dev"
|
24
|
+
Dynamic: license-file
|
25
|
+
|
26
|
+
# Talks Reducer
|
27
|
+
Talks Reducer shortens long-form presentations by removing silent gaps and optionally re-encoding them to smaller files. The
|
28
|
+
project was renamed from **jumpcutter** to emphasize its focus on conference talks and screencasts.
|
29
|
+
|
30
|
+

|
31
|
+
|
32
|
+
## Example
|
33
|
+
- 1h 37m, 571 MB — Original OBS video recording
|
34
|
+
- 1h 19m, 751 MB — Talks Reducer
|
35
|
+
- 1h 19m, 171 MB — Talks Reducer `--small`
|
36
|
+
|
37
|
+
## Changelog
|
38
|
+
|
39
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
40
|
+
|
41
|
+
## Install GUI (Windows, macOS)
|
42
|
+
Go to the [releases page](https://github.com/popstas/talks-reducer/releases) and download the appropriate artifact:
|
43
|
+
|
44
|
+
- **Windows** — `talks-reducer-windows.zip`
|
45
|
+
- **macOS** — `talks-reducer.app.zip` (but it doesn't work for me)
|
46
|
+
|
47
|
+
## Install CLI (Linux, Windows, macOS)
|
48
|
+
```
|
49
|
+
pip install talks-reducer
|
50
|
+
```
|
51
|
+
|
52
|
+
**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.
|
53
|
+
|
54
|
+
The `--small` preset applies a 720p video scale and 128 kbps audio bitrate, making it useful for sharing talks over constrained
|
55
|
+
connections. Without `--small`, the script aims to preserve original quality while removing silence.
|
56
|
+
|
57
|
+
Example CLI usage:
|
58
|
+
|
59
|
+
```sh
|
60
|
+
talks-reducer --small input.mp4
|
61
|
+
```
|
62
|
+
|
63
|
+
When CUDA-capable hardware is available the pipeline leans on GPU encoders to keep export times low, but it still runs great on
|
64
|
+
CPUs.
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
See `CONTRIBUTION.md` for development setup details and guidance on sharing improvements.
|
68
|
+
|
69
|
+
## License
|
70
|
+
Talks Reducer is released under the MIT License. See `LICENSE` for the full text.
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Talks Reducer
|
2
|
+
Talks Reducer shortens long-form presentations by removing silent gaps and optionally re-encoding them to smaller files. The
|
3
|
+
project was renamed from **jumpcutter** to emphasize its focus on conference talks and screencasts.
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
## Example
|
8
|
+
- 1h 37m, 571 MB — Original OBS video recording
|
9
|
+
- 1h 19m, 751 MB — Talks Reducer
|
10
|
+
- 1h 19m, 171 MB — Talks Reducer `--small`
|
11
|
+
|
12
|
+
## Changelog
|
13
|
+
|
14
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
15
|
+
|
16
|
+
## Install GUI (Windows, macOS)
|
17
|
+
Go to the [releases page](https://github.com/popstas/talks-reducer/releases) and download the appropriate artifact:
|
18
|
+
|
19
|
+
- **Windows** — `talks-reducer-windows.zip`
|
20
|
+
- **macOS** — `talks-reducer.app.zip` (but it doesn't work for me)
|
21
|
+
|
22
|
+
## Install CLI (Linux, Windows, macOS)
|
23
|
+
```
|
24
|
+
pip install talks-reducer
|
25
|
+
```
|
26
|
+
|
27
|
+
**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.
|
28
|
+
|
29
|
+
The `--small` preset applies a 720p video scale and 128 kbps audio bitrate, making it useful for sharing talks over constrained
|
30
|
+
connections. Without `--small`, the script aims to preserve original quality while removing silence.
|
31
|
+
|
32
|
+
Example CLI usage:
|
33
|
+
|
34
|
+
```sh
|
35
|
+
talks-reducer --small input.mp4
|
36
|
+
```
|
37
|
+
|
38
|
+
When CUDA-capable hardware is available the pipeline leans on GPU encoders to keep export times low, but it still runs great on
|
39
|
+
CPUs.
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
See `CONTRIBUTION.md` for development setup details and guidance on sharing improvements.
|
43
|
+
|
44
|
+
## License
|
45
|
+
Talks Reducer is released under the MIT License. See `LICENSE` for the full text.
|
@@ -196,6 +196,15 @@ def main(argv: Optional[Sequence[str]] = None) -> None:
|
|
196
196
|
sys.exit(1)
|
197
197
|
|
198
198
|
reporter.log(f"Completed: {result.output_file}")
|
199
|
+
summary_parts = []
|
200
|
+
time_ratio = getattr(result, "time_ratio", None)
|
201
|
+
size_ratio = getattr(result, "size_ratio", None)
|
202
|
+
if time_ratio is not None:
|
203
|
+
summary_parts.append(f"{time_ratio * 100:.0f}% time")
|
204
|
+
if size_ratio is not None:
|
205
|
+
summary_parts.append(f"{size_ratio * 100:.0f}% size")
|
206
|
+
if summary_parts:
|
207
|
+
reporter.log("Result: " + ", ".join(summary_parts))
|
199
208
|
|
200
209
|
end_time = time.time()
|
201
210
|
total_time = end_time - start_time
|
@@ -291,6 +291,8 @@ class TalksReducerGUI:
|
|
291
291
|
|
292
292
|
self._processing_thread: Optional[threading.Thread] = None
|
293
293
|
self._last_output: Optional[Path] = None
|
294
|
+
self._last_time_ratio: Optional[float] = None
|
295
|
+
self._last_size_ratio: Optional[float] = None
|
294
296
|
self._status_state = "Idle"
|
295
297
|
self.status_var = tk.StringVar(value=self._status_state)
|
296
298
|
self._status_animation_job: Optional[str] = None
|
@@ -445,7 +447,9 @@ class TalksReducerGUI:
|
|
445
447
|
variable=self.simple_mode_var,
|
446
448
|
command=self._toggle_simple_mode,
|
447
449
|
)
|
448
|
-
self.simple_mode_check.grid(
|
450
|
+
self.simple_mode_check.grid(
|
451
|
+
row=1, column=0, columnspan=3, sticky="w", pady=(8, 0)
|
452
|
+
)
|
449
453
|
|
450
454
|
self.advanced_visible = self.tk.BooleanVar(value=False)
|
451
455
|
self.advanced_button = self.ttk.Button(
|
@@ -980,7 +984,15 @@ class TalksReducerGUI:
|
|
980
984
|
options = self._build_options(Path(file), args)
|
981
985
|
result = speed_up_video(options, reporter=reporter)
|
982
986
|
self._last_output = result.output_file
|
983
|
-
self.
|
987
|
+
self._last_time_ratio = result.time_ratio
|
988
|
+
self._last_size_ratio = result.size_ratio
|
989
|
+
|
990
|
+
# Create completion message with ratios if available
|
991
|
+
completion_msg = f"Completed: {result.output_file}"
|
992
|
+
if result.time_ratio is not None and result.size_ratio is not None:
|
993
|
+
completion_msg += f" (Time: {result.time_ratio:.2%}, Size: {result.size_ratio:.2%})"
|
994
|
+
|
995
|
+
self._append_log(completion_msg)
|
984
996
|
if open_after_convert:
|
985
997
|
self._notify(
|
986
998
|
lambda path=result.output_file: self._open_in_file_manager(
|
@@ -1135,17 +1147,22 @@ class TalksReducerGUI:
|
|
1135
1147
|
def _update_status_from_message(self, message: str) -> None:
|
1136
1148
|
normalized = message.strip().lower()
|
1137
1149
|
if "all jobs finished successfully" in normalized:
|
1138
|
-
|
1150
|
+
# Create status message with ratios if available
|
1151
|
+
status_msg = "Success"
|
1152
|
+
if self._last_time_ratio is not None and self._last_size_ratio is not None:
|
1153
|
+
status_msg = f"Time: {self._last_time_ratio:.0%}, Size: {self._last_size_ratio:.0%}"
|
1154
|
+
|
1155
|
+
self._set_status("success", status_msg)
|
1139
1156
|
self._set_progress(100) # 100% on success
|
1140
1157
|
self._video_duration_seconds = None # Reset for next video
|
1141
1158
|
elif normalized.startswith("extracting audio"):
|
1142
|
-
self._set_status("Extracting audio...")
|
1159
|
+
self._set_status("processing", "Extracting audio...")
|
1143
1160
|
self._set_progress(0) # 0% on start
|
1144
1161
|
self._video_duration_seconds = None # Reset for new processing
|
1145
1162
|
elif normalized.startswith("starting processing") or normalized.startswith(
|
1146
1163
|
"processing"
|
1147
1164
|
):
|
1148
|
-
self._set_status("Processing")
|
1165
|
+
self._set_status("processing", "Processing")
|
1149
1166
|
self._set_progress(0) # 0% on start
|
1150
1167
|
self._video_duration_seconds = None # Reset for new processing
|
1151
1168
|
|
@@ -1174,10 +1191,10 @@ class TalksReducerGUI:
|
|
1174
1191
|
percentage = min(
|
1175
1192
|
100, int((current_seconds / self._video_duration_seconds) * 100)
|
1176
1193
|
)
|
1177
|
-
self._set_status(f"{time_str}, {speed_str}x ({percentage}%)")
|
1194
|
+
self._set_status("processing", f"{time_str}, {speed_str}x ({percentage}%)")
|
1178
1195
|
self._set_progress(percentage) # Update progress bar
|
1179
1196
|
else:
|
1180
|
-
self._set_status(f"{time_str}, {speed_str}x")
|
1197
|
+
self._set_status("processing", f"{time_str}, {speed_str}x")
|
1181
1198
|
|
1182
1199
|
def _apply_status_style(self, status: str) -> None:
|
1183
1200
|
color = STATUS_COLORS.get(status.lower())
|
@@ -1185,30 +1202,36 @@ class TalksReducerGUI:
|
|
1185
1202
|
self.status_label.configure(fg=color)
|
1186
1203
|
else:
|
1187
1204
|
# For extracting audio or FFmpeg progress messages, use processing color
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1205
|
+
# Also handle the new "Time: X%, Size: Y%" format as success
|
1206
|
+
status_lower = status.lower()
|
1207
|
+
if ("extracting audio" in status_lower or
|
1208
|
+
re.search(r"\d{2}:\d{2}:\d{2}.*\d+\.?\d*x", status) or
|
1209
|
+
("time:" in status_lower and "size:" in status_lower)):
|
1210
|
+
if "time:" in status_lower and "size:" in status_lower:
|
1211
|
+
# This is our new success format with ratios
|
1212
|
+
self.status_label.configure(fg=STATUS_COLORS["success"])
|
1213
|
+
else:
|
1214
|
+
self.status_label.configure(fg=STATUS_COLORS["processing"])
|
1192
1215
|
|
1193
|
-
def _set_status(self, status: str) -> None:
|
1216
|
+
def _set_status(self, status: str, status_msg: str = "") -> None:
|
1194
1217
|
def apply() -> None:
|
1195
|
-
self._stop_status_animation()
|
1196
1218
|
self._status_state = status
|
1197
|
-
|
1198
|
-
|
1219
|
+
# Use status_msg if provided, otherwise use status
|
1220
|
+
display_text = status_msg if status_msg else status
|
1221
|
+
self.status_var.set(display_text)
|
1222
|
+
self._apply_status_style(status) # Colors depend on status, not display text
|
1199
1223
|
self._set_progress_bar_style(status)
|
1200
1224
|
lowered = status.lower()
|
1201
1225
|
is_processing = lowered == "processing" or "extracting audio" in lowered
|
1202
1226
|
|
1203
1227
|
if is_processing:
|
1204
|
-
self._start_status_animation()
|
1205
1228
|
# Show stop button during processing
|
1206
1229
|
if hasattr(self, "status_frame"):
|
1207
1230
|
self.status_frame.grid()
|
1208
1231
|
self.stop_button.grid()
|
1209
1232
|
self.drop_hint_button.grid_remove()
|
1210
1233
|
|
1211
|
-
if lowered == "success":
|
1234
|
+
if lowered == "success" or "time:" in lowered and "size:" in lowered:
|
1212
1235
|
if self.simple_mode_var.get() and hasattr(self, "status_frame"):
|
1213
1236
|
self.status_frame.grid()
|
1214
1237
|
self.stop_button.grid_remove()
|
@@ -1232,30 +1255,6 @@ class TalksReducerGUI:
|
|
1232
1255
|
|
1233
1256
|
self.root.after(0, apply)
|
1234
1257
|
|
1235
|
-
def _start_status_animation(self) -> None:
|
1236
|
-
self._status_animation_phase = 0
|
1237
|
-
self._schedule_status_animation()
|
1238
|
-
|
1239
|
-
def _schedule_status_animation(self) -> None:
|
1240
|
-
if self._status_state.lower() != "processing":
|
1241
|
-
return
|
1242
|
-
|
1243
|
-
dots = self._status_animation_phase % 4
|
1244
|
-
suffix = "." * dots
|
1245
|
-
text = "Processing" + suffix
|
1246
|
-
self.status_var.set(text)
|
1247
|
-
self._status_animation_phase = (self._status_animation_phase + 1) % 4
|
1248
|
-
self._status_animation_job = self.root.after(
|
1249
|
-
400, self._schedule_status_animation
|
1250
|
-
)
|
1251
|
-
|
1252
|
-
def _stop_status_animation(self) -> None:
|
1253
|
-
if self._status_animation_job is not None:
|
1254
|
-
self.root.after_cancel(self._status_animation_job)
|
1255
|
-
self._status_animation_job = None
|
1256
|
-
if self._status_state.lower() != "processing":
|
1257
|
-
self.status_var.set(self._status_state)
|
1258
|
-
|
1259
1258
|
def _calculate_gradient_color(self, percentage: int, darken: float = 1.0) -> str:
|
1260
1259
|
"""Calculate color gradient from red (0%) to green (100%).
|
1261
1260
|
|
@@ -1334,7 +1333,7 @@ class TalksReducerGUI:
|
|
1334
1333
|
def updater() -> None:
|
1335
1334
|
# Map status to progress bar style
|
1336
1335
|
status_lower = status.lower()
|
1337
|
-
if status_lower == "success":
|
1336
|
+
if status_lower == "success" or ("time:" in status_lower and "size:" in status_lower):
|
1338
1337
|
style = "Success.Horizontal.TProgressbar"
|
1339
1338
|
elif status_lower == "error":
|
1340
1339
|
style = "Error.Horizontal.TProgressbar"
|
@@ -270,12 +270,23 @@ def speed_up_video(
|
|
270
270
|
finally:
|
271
271
|
_delete_path(temp_path)
|
272
272
|
|
273
|
+
output_metadata = _extract_video_metadata(output_path, frame_rate)
|
274
|
+
output_duration = output_metadata.get("duration", 0.0)
|
275
|
+
time_ratio = output_duration / original_duration if original_duration > 0 else None
|
276
|
+
|
277
|
+
input_size = input_path.stat().st_size if input_path.exists() else 0
|
278
|
+
output_size = output_path.stat().st_size if output_path.exists() else 0
|
279
|
+
size_ratio = (output_size / input_size) if input_size > 0 else None
|
280
|
+
|
273
281
|
return ProcessingResult(
|
274
282
|
input_file=input_path,
|
275
283
|
output_file=output_path,
|
276
284
|
frame_rate=frame_rate,
|
277
285
|
original_duration=original_duration,
|
286
|
+
output_duration=output_duration,
|
278
287
|
chunk_count=len(chunks),
|
279
288
|
used_cuda=use_cuda_encoder,
|
280
289
|
max_audio_volume=max_audio_volume,
|
290
|
+
time_ratio=time_ratio,
|
291
|
+
size_ratio=size_ratio,
|
281
292
|
)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: talks-reducer
|
3
|
+
Version: 0.3.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: pyinstaller>=6.0.0; extra == "dev"
|
24
|
+
Dynamic: license-file
|
25
|
+
|
26
|
+
# Talks Reducer
|
27
|
+
Talks Reducer shortens long-form presentations by removing silent gaps and optionally re-encoding them to smaller files. The
|
28
|
+
project was renamed from **jumpcutter** to emphasize its focus on conference talks and screencasts.
|
29
|
+
|
30
|
+

|
31
|
+
|
32
|
+
## Example
|
33
|
+
- 1h 37m, 571 MB — Original OBS video recording
|
34
|
+
- 1h 19m, 751 MB — Talks Reducer
|
35
|
+
- 1h 19m, 171 MB — Talks Reducer `--small`
|
36
|
+
|
37
|
+
## Changelog
|
38
|
+
|
39
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
40
|
+
|
41
|
+
## Install GUI (Windows, macOS)
|
42
|
+
Go to the [releases page](https://github.com/popstas/talks-reducer/releases) and download the appropriate artifact:
|
43
|
+
|
44
|
+
- **Windows** — `talks-reducer-windows.zip`
|
45
|
+
- **macOS** — `talks-reducer.app.zip` (but it doesn't work for me)
|
46
|
+
|
47
|
+
## Install CLI (Linux, Windows, macOS)
|
48
|
+
```
|
49
|
+
pip install talks-reducer
|
50
|
+
```
|
51
|
+
|
52
|
+
**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.
|
53
|
+
|
54
|
+
The `--small` preset applies a 720p video scale and 128 kbps audio bitrate, making it useful for sharing talks over constrained
|
55
|
+
connections. Without `--small`, the script aims to preserve original quality while removing silence.
|
56
|
+
|
57
|
+
Example CLI usage:
|
58
|
+
|
59
|
+
```sh
|
60
|
+
talks-reducer --small input.mp4
|
61
|
+
```
|
62
|
+
|
63
|
+
When CUDA-capable hardware is available the pipeline leans on GPU encoders to keep export times low, but it still runs great on
|
64
|
+
CPUs.
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
See `CONTRIBUTION.md` for development setup details and guidance on sharing improvements.
|
68
|
+
|
69
|
+
## License
|
70
|
+
Talks Reducer is released under the MIT License. See `LICENSE` for the full text.
|
@@ -87,13 +87,19 @@ def test_speed_up_video_returns_result(monkeypatch, tmp_path):
|
|
87
87
|
monkeypatch.setattr(
|
88
88
|
"talks_reducer.pipeline.chunk_utils.get_tree_expression", lambda _chunks: "X"
|
89
89
|
)
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
|
91
|
+
def fake_run(command, *args, **kwargs):
|
92
|
+
if command == "render":
|
93
|
+
options.output_file.write_bytes(b"fake")
|
94
|
+
return None
|
95
|
+
|
96
|
+
monkeypatch.setattr("talks_reducer.pipeline.run_timed_ffmpeg_command", fake_run)
|
93
97
|
|
94
98
|
result = speed_up_video(options, reporter=reporter)
|
95
99
|
|
96
100
|
assert isinstance(result, ProcessingResult)
|
97
101
|
assert result.output_file == options.output_file
|
98
102
|
assert result.chunk_count == 1
|
103
|
+
assert result.time_ratio == 1.0
|
104
|
+
assert result.size_ratio == 1.0
|
99
105
|
assert reporter.messages # progress logs should be collected
|
talks_reducer-0.3.2/PKG-INFO
DELETED
@@ -1,156 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: talks-reducer
|
3
|
-
Version: 0.3.2
|
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: pyinstaller>=6.0.0; extra == "dev"
|
24
|
-
Dynamic: license-file
|
25
|
-
|
26
|
-
# Talks Reducer
|
27
|
-
Talks Reducer shortens long-form presentations by removing silent gaps and optionally re-encoding them to smaller files. The
|
28
|
-
project was renamed from **jumpcutter** to emphasize its focus on conference talks and screencasts.
|
29
|
-
|
30
|
-
## Example
|
31
|
-
- 1h 37m, 571 MB — Original OBS video recording
|
32
|
-
- 1h 19m, 751 MB — Talks Reducer
|
33
|
-
- 1h 19m, 171 MB — Talks Reducer `--small`
|
34
|
-
|
35
|
-
## Changelog
|
36
|
-
|
37
|
-
See [CHANGELOG.md](CHANGELOG.md).
|
38
|
-
|
39
|
-
## Install GUI (Windows, macOS)
|
40
|
-
Go to the [releases page](https://github.com/popstas/talks-reducer/releases) and download the appropriate artifact:
|
41
|
-
|
42
|
-
- **Windows** — `talks-reducer-gui.exe`
|
43
|
-
- **macOS** — `talks-reducer-gui-macos-universal` (requires macOS 10.13 High Sierra or
|
44
|
-
newer). The bundle is built as a universal (`x86_64` + `arm64`) app so it runs
|
45
|
-
natively on Apple Silicon without Rosetta.
|
46
|
-
|
47
|
-
## Install CLI (Linux, Windows, macOS)
|
48
|
-
```
|
49
|
-
pip install talks-reducer
|
50
|
-
```
|
51
|
-
|
52
|
-
**Note:** FFmpeg is now bundled automatically with the package, so you don't need to install it separately. However, if you have FFmpeg already installed on your system, it will be used instead of the bundled version.
|
53
|
-
|
54
|
-
The `--small` preset applies a 720p video scale and 128 kbps audio bitrate, making it useful for sharing talks over constrained
|
55
|
-
connections. Without `--small`, the script aims to preserve original quality while removing silence.
|
56
|
-
|
57
|
-
> **Tip:** The `talks-reducer` and `talks-reducer-gui` commands now behave the same way: launching them without arguments opens
|
58
|
-
> the Tkinter interface, while passing regular CLI options (for example, `talks-reducer --small input.mp4`) executes the
|
59
|
-
> command-line pipeline. You can keep a single shortcut for both workflows.
|
60
|
-
|
61
|
-
When CUDA-capable hardware is available the pipeline leans on GPU encoders to keep export times low, but it still runs great on
|
62
|
-
CPUs.
|
63
|
-
|
64
|
-
### macOS codesigning and notarization
|
65
|
-
|
66
|
-
Maintainers with Apple Developer credentials can optionally sign and notarize
|
67
|
-
the GUI release to avoid Gatekeeper warnings on download:
|
68
|
-
|
69
|
-
1. Export or create a keychain profile for `notarytool` (see `man
|
70
|
-
notarytool`) and note the profile name.
|
71
|
-
2. Set the following environment variables before running `scripts/build-gui.sh`:
|
72
|
-
- `MACOS_CODESIGN_IDENTITY` — the signing identity, for example
|
73
|
-
`Developer ID Application: Example Corp (TEAMID)`.
|
74
|
-
- `MACOS_CODESIGN_ENTITLEMENTS` *(optional)* — path to an entitlements plist
|
75
|
-
used during codesigning.
|
76
|
-
- `MACOS_NOTARIZE_PROFILE` *(optional)* — the keychain profile name to submit
|
77
|
-
the archive for notarization. When present, the script zips the `.app`,
|
78
|
-
submits it with `notarytool --wait`, and staples the returned ticket.
|
79
|
-
|
80
|
-
The codesigning step executes only when the variables are provided, so the build
|
81
|
-
continues to work unchanged for local development.
|
82
|
-
|
83
|
-
### Graphical Interface
|
84
|
-
|
85
|
-
- **Simple mode** — the default experience shrinks the window to a large drop
|
86
|
-
zone, hides the manual run controls and log, and automatically processes new
|
87
|
-
files as soon as you drop them. Uncheck the box to return to the full layout
|
88
|
-
with file pickers, the Run button, and detailed logging.
|
89
|
-
- **Input drop zone** — drag files or folders from your desktop, click to open
|
90
|
-
the system file picker, or add them via the Explorer/Finder dialog; duplicates
|
91
|
-
are ignored.
|
92
|
-
- **Small video** — toggles the `--small` preset used by the CLI.
|
93
|
-
- **Open after convert** — controls whether the exported file is revealed in
|
94
|
-
your system file manager as soon as each job finishes.
|
95
|
-
- **Advanced** — reveals optional controls for the output path, temp folder,
|
96
|
-
timing/audio knobs mirrored from the command line, and an appearance picker
|
97
|
-
that can force dark or light mode or follow your operating system.
|
98
|
-
|
99
|
-
Progress updates stream into the 10-line log panel while the processing runs in
|
100
|
-
a background thread. Once every queued job succeeds an **Open last output**
|
101
|
-
button appears so you can jump straight to the exported file in your system
|
102
|
-
file manager.
|
103
|
-
|
104
|
-
The GUI stores your last-used Simple mode, Small video, Open after convert, and
|
105
|
-
theme preferences in a cross-platform configuration file so they persist across
|
106
|
-
launches.
|
107
|
-
|
108
|
-
## Repository Structure
|
109
|
-
- `talks_reducer/` — Python package that exposes the CLI and reusable pipeline:
|
110
|
-
- `cli.py` parses arguments and dispatches to the pipeline.
|
111
|
-
- `pipeline.py` orchestrates FFmpeg, audio processing, and temporary assets.
|
112
|
-
- `audio.py` handles audio validation, volume analysis, and phase vocoder processing.
|
113
|
-
- `chunks.py` builds timing metadata and FFmpeg expressions for frame selection.
|
114
|
-
- `ffmpeg.py` discovers the FFmpeg binary, checks CUDA availability, and assembles command strings.
|
115
|
-
- `requirements.txt` — Python dependencies for local development.
|
116
|
-
- `default.nix` — reproducible environment definition for Nix users.
|
117
|
-
- `CONTRIBUTION.md` — development workflow, formatting expectations, and release checklist.
|
118
|
-
- `AGENTS.md` — maintainer tips and coding conventions for this repository.
|
119
|
-
|
120
|
-
## Highlights
|
121
|
-
- Builds on gegell's classic jumpcutter workflow with more efficient frame and audio processing
|
122
|
-
- Generates FFmpeg filter graphs instead of writing temporary frames to disk
|
123
|
-
- Streams audio transformations in memory to avoid slow intermediate files
|
124
|
-
- Accepts multiple inputs or directories of recordings in a single run
|
125
|
-
- Provides progress feedback via `tqdm`
|
126
|
-
- Automatically detects NVENC availability, so you no longer need to pass `--cuda`
|
127
|
-
|
128
|
-
## Processing Pipeline
|
129
|
-
1. Validate that each input file contains an audio stream using `ffprobe`.
|
130
|
-
2. Extract audio and calculate loudness to identify silent regions.
|
131
|
-
3. Stretch the non-silent segments with `audiotsm` to maintain speech clarity.
|
132
|
-
4. Stitch the processed audio and video together with FFmpeg, using NVENC if the GPU encoders are detected.
|
133
|
-
|
134
|
-
## Recent Updates
|
135
|
-
- **October 2025** — Project renamed to *Talks Reducer* across documentation and scripts.
|
136
|
-
- **October 2025** — Added `--small` preset with 720p/128 kbps defaults for bandwidth-friendly exports.
|
137
|
-
- **October 2025** — Removed the `--cuda` flag; CUDA/NVENC support is now auto-detected.
|
138
|
-
|
139
|
-
## Changelog
|
140
|
-
Major and minor releases are tracked in `CHANGELOG.md`. The log is generated from
|
141
|
-
Conventional Commits that start with either `feat:` or `fix:`. Only tags in the
|
142
|
-
form `v<major>.<minor>.0` are included so patch releases (for example,
|
143
|
-
`v1.1.1`) are omitted. Regenerate the file whenever you cut a release:
|
144
|
-
|
145
|
-
```bash
|
146
|
-
python scripts/generate_changelog.py
|
147
|
-
```
|
148
|
-
|
149
|
-
CI will fail if the generated changelog does not match the committed version, so
|
150
|
-
run the script before opening a pull request that updates release tags.
|
151
|
-
|
152
|
-
## Contributing
|
153
|
-
See `CONTRIBUTION.md` for development setup details and guidance on sharing improvements.
|
154
|
-
|
155
|
-
## License
|
156
|
-
Talks Reducer is released under the MIT License. See `LICENSE` for the full text.
|
talks_reducer-0.3.2/README.md
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
# Talks Reducer
|
2
|
-
Talks Reducer shortens long-form presentations by removing silent gaps and optionally re-encoding them to smaller files. The
|
3
|
-
project was renamed from **jumpcutter** to emphasize its focus on conference talks and screencasts.
|
4
|
-
|
5
|
-
## Example
|
6
|
-
- 1h 37m, 571 MB — Original OBS video recording
|
7
|
-
- 1h 19m, 751 MB — Talks Reducer
|
8
|
-
- 1h 19m, 171 MB — Talks Reducer `--small`
|
9
|
-
|
10
|
-
## Changelog
|
11
|
-
|
12
|
-
See [CHANGELOG.md](CHANGELOG.md).
|
13
|
-
|
14
|
-
## Install GUI (Windows, macOS)
|
15
|
-
Go to the [releases page](https://github.com/popstas/talks-reducer/releases) and download the appropriate artifact:
|
16
|
-
|
17
|
-
- **Windows** — `talks-reducer-gui.exe`
|
18
|
-
- **macOS** — `talks-reducer-gui-macos-universal` (requires macOS 10.13 High Sierra or
|
19
|
-
newer). The bundle is built as a universal (`x86_64` + `arm64`) app so it runs
|
20
|
-
natively on Apple Silicon without Rosetta.
|
21
|
-
|
22
|
-
## Install CLI (Linux, Windows, macOS)
|
23
|
-
```
|
24
|
-
pip install talks-reducer
|
25
|
-
```
|
26
|
-
|
27
|
-
**Note:** FFmpeg is now bundled automatically with the package, so you don't need to install it separately. However, if you have FFmpeg already installed on your system, it will be used instead of the bundled version.
|
28
|
-
|
29
|
-
The `--small` preset applies a 720p video scale and 128 kbps audio bitrate, making it useful for sharing talks over constrained
|
30
|
-
connections. Without `--small`, the script aims to preserve original quality while removing silence.
|
31
|
-
|
32
|
-
> **Tip:** The `talks-reducer` and `talks-reducer-gui` commands now behave the same way: launching them without arguments opens
|
33
|
-
> the Tkinter interface, while passing regular CLI options (for example, `talks-reducer --small input.mp4`) executes the
|
34
|
-
> command-line pipeline. You can keep a single shortcut for both workflows.
|
35
|
-
|
36
|
-
When CUDA-capable hardware is available the pipeline leans on GPU encoders to keep export times low, but it still runs great on
|
37
|
-
CPUs.
|
38
|
-
|
39
|
-
### macOS codesigning and notarization
|
40
|
-
|
41
|
-
Maintainers with Apple Developer credentials can optionally sign and notarize
|
42
|
-
the GUI release to avoid Gatekeeper warnings on download:
|
43
|
-
|
44
|
-
1. Export or create a keychain profile for `notarytool` (see `man
|
45
|
-
notarytool`) and note the profile name.
|
46
|
-
2. Set the following environment variables before running `scripts/build-gui.sh`:
|
47
|
-
- `MACOS_CODESIGN_IDENTITY` — the signing identity, for example
|
48
|
-
`Developer ID Application: Example Corp (TEAMID)`.
|
49
|
-
- `MACOS_CODESIGN_ENTITLEMENTS` *(optional)* — path to an entitlements plist
|
50
|
-
used during codesigning.
|
51
|
-
- `MACOS_NOTARIZE_PROFILE` *(optional)* — the keychain profile name to submit
|
52
|
-
the archive for notarization. When present, the script zips the `.app`,
|
53
|
-
submits it with `notarytool --wait`, and staples the returned ticket.
|
54
|
-
|
55
|
-
The codesigning step executes only when the variables are provided, so the build
|
56
|
-
continues to work unchanged for local development.
|
57
|
-
|
58
|
-
### Graphical Interface
|
59
|
-
|
60
|
-
- **Simple mode** — the default experience shrinks the window to a large drop
|
61
|
-
zone, hides the manual run controls and log, and automatically processes new
|
62
|
-
files as soon as you drop them. Uncheck the box to return to the full layout
|
63
|
-
with file pickers, the Run button, and detailed logging.
|
64
|
-
- **Input drop zone** — drag files or folders from your desktop, click to open
|
65
|
-
the system file picker, or add them via the Explorer/Finder dialog; duplicates
|
66
|
-
are ignored.
|
67
|
-
- **Small video** — toggles the `--small` preset used by the CLI.
|
68
|
-
- **Open after convert** — controls whether the exported file is revealed in
|
69
|
-
your system file manager as soon as each job finishes.
|
70
|
-
- **Advanced** — reveals optional controls for the output path, temp folder,
|
71
|
-
timing/audio knobs mirrored from the command line, and an appearance picker
|
72
|
-
that can force dark or light mode or follow your operating system.
|
73
|
-
|
74
|
-
Progress updates stream into the 10-line log panel while the processing runs in
|
75
|
-
a background thread. Once every queued job succeeds an **Open last output**
|
76
|
-
button appears so you can jump straight to the exported file in your system
|
77
|
-
file manager.
|
78
|
-
|
79
|
-
The GUI stores your last-used Simple mode, Small video, Open after convert, and
|
80
|
-
theme preferences in a cross-platform configuration file so they persist across
|
81
|
-
launches.
|
82
|
-
|
83
|
-
## Repository Structure
|
84
|
-
- `talks_reducer/` — Python package that exposes the CLI and reusable pipeline:
|
85
|
-
- `cli.py` parses arguments and dispatches to the pipeline.
|
86
|
-
- `pipeline.py` orchestrates FFmpeg, audio processing, and temporary assets.
|
87
|
-
- `audio.py` handles audio validation, volume analysis, and phase vocoder processing.
|
88
|
-
- `chunks.py` builds timing metadata and FFmpeg expressions for frame selection.
|
89
|
-
- `ffmpeg.py` discovers the FFmpeg binary, checks CUDA availability, and assembles command strings.
|
90
|
-
- `requirements.txt` — Python dependencies for local development.
|
91
|
-
- `default.nix` — reproducible environment definition for Nix users.
|
92
|
-
- `CONTRIBUTION.md` — development workflow, formatting expectations, and release checklist.
|
93
|
-
- `AGENTS.md` — maintainer tips and coding conventions for this repository.
|
94
|
-
|
95
|
-
## Highlights
|
96
|
-
- Builds on gegell's classic jumpcutter workflow with more efficient frame and audio processing
|
97
|
-
- Generates FFmpeg filter graphs instead of writing temporary frames to disk
|
98
|
-
- Streams audio transformations in memory to avoid slow intermediate files
|
99
|
-
- Accepts multiple inputs or directories of recordings in a single run
|
100
|
-
- Provides progress feedback via `tqdm`
|
101
|
-
- Automatically detects NVENC availability, so you no longer need to pass `--cuda`
|
102
|
-
|
103
|
-
## Processing Pipeline
|
104
|
-
1. Validate that each input file contains an audio stream using `ffprobe`.
|
105
|
-
2. Extract audio and calculate loudness to identify silent regions.
|
106
|
-
3. Stretch the non-silent segments with `audiotsm` to maintain speech clarity.
|
107
|
-
4. Stitch the processed audio and video together with FFmpeg, using NVENC if the GPU encoders are detected.
|
108
|
-
|
109
|
-
## Recent Updates
|
110
|
-
- **October 2025** — Project renamed to *Talks Reducer* across documentation and scripts.
|
111
|
-
- **October 2025** — Added `--small` preset with 720p/128 kbps defaults for bandwidth-friendly exports.
|
112
|
-
- **October 2025** — Removed the `--cuda` flag; CUDA/NVENC support is now auto-detected.
|
113
|
-
|
114
|
-
## Changelog
|
115
|
-
Major and minor releases are tracked in `CHANGELOG.md`. The log is generated from
|
116
|
-
Conventional Commits that start with either `feat:` or `fix:`. Only tags in the
|
117
|
-
form `v<major>.<minor>.0` are included so patch releases (for example,
|
118
|
-
`v1.1.1`) are omitted. Regenerate the file whenever you cut a release:
|
119
|
-
|
120
|
-
```bash
|
121
|
-
python scripts/generate_changelog.py
|
122
|
-
```
|
123
|
-
|
124
|
-
CI will fail if the generated changelog does not match the committed version, so
|
125
|
-
run the script before opening a pull request that updates release tags.
|
126
|
-
|
127
|
-
## Contributing
|
128
|
-
See `CONTRIBUTION.md` for development setup details and guidance on sharing improvements.
|
129
|
-
|
130
|
-
## License
|
131
|
-
Talks Reducer is released under the MIT License. See `LICENSE` for the full text.
|
@@ -1,156 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: talks-reducer
|
3
|
-
Version: 0.3.2
|
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: pyinstaller>=6.0.0; extra == "dev"
|
24
|
-
Dynamic: license-file
|
25
|
-
|
26
|
-
# Talks Reducer
|
27
|
-
Talks Reducer shortens long-form presentations by removing silent gaps and optionally re-encoding them to smaller files. The
|
28
|
-
project was renamed from **jumpcutter** to emphasize its focus on conference talks and screencasts.
|
29
|
-
|
30
|
-
## Example
|
31
|
-
- 1h 37m, 571 MB — Original OBS video recording
|
32
|
-
- 1h 19m, 751 MB — Talks Reducer
|
33
|
-
- 1h 19m, 171 MB — Talks Reducer `--small`
|
34
|
-
|
35
|
-
## Changelog
|
36
|
-
|
37
|
-
See [CHANGELOG.md](CHANGELOG.md).
|
38
|
-
|
39
|
-
## Install GUI (Windows, macOS)
|
40
|
-
Go to the [releases page](https://github.com/popstas/talks-reducer/releases) and download the appropriate artifact:
|
41
|
-
|
42
|
-
- **Windows** — `talks-reducer-gui.exe`
|
43
|
-
- **macOS** — `talks-reducer-gui-macos-universal` (requires macOS 10.13 High Sierra or
|
44
|
-
newer). The bundle is built as a universal (`x86_64` + `arm64`) app so it runs
|
45
|
-
natively on Apple Silicon without Rosetta.
|
46
|
-
|
47
|
-
## Install CLI (Linux, Windows, macOS)
|
48
|
-
```
|
49
|
-
pip install talks-reducer
|
50
|
-
```
|
51
|
-
|
52
|
-
**Note:** FFmpeg is now bundled automatically with the package, so you don't need to install it separately. However, if you have FFmpeg already installed on your system, it will be used instead of the bundled version.
|
53
|
-
|
54
|
-
The `--small` preset applies a 720p video scale and 128 kbps audio bitrate, making it useful for sharing talks over constrained
|
55
|
-
connections. Without `--small`, the script aims to preserve original quality while removing silence.
|
56
|
-
|
57
|
-
> **Tip:** The `talks-reducer` and `talks-reducer-gui` commands now behave the same way: launching them without arguments opens
|
58
|
-
> the Tkinter interface, while passing regular CLI options (for example, `talks-reducer --small input.mp4`) executes the
|
59
|
-
> command-line pipeline. You can keep a single shortcut for both workflows.
|
60
|
-
|
61
|
-
When CUDA-capable hardware is available the pipeline leans on GPU encoders to keep export times low, but it still runs great on
|
62
|
-
CPUs.
|
63
|
-
|
64
|
-
### macOS codesigning and notarization
|
65
|
-
|
66
|
-
Maintainers with Apple Developer credentials can optionally sign and notarize
|
67
|
-
the GUI release to avoid Gatekeeper warnings on download:
|
68
|
-
|
69
|
-
1. Export or create a keychain profile for `notarytool` (see `man
|
70
|
-
notarytool`) and note the profile name.
|
71
|
-
2. Set the following environment variables before running `scripts/build-gui.sh`:
|
72
|
-
- `MACOS_CODESIGN_IDENTITY` — the signing identity, for example
|
73
|
-
`Developer ID Application: Example Corp (TEAMID)`.
|
74
|
-
- `MACOS_CODESIGN_ENTITLEMENTS` *(optional)* — path to an entitlements plist
|
75
|
-
used during codesigning.
|
76
|
-
- `MACOS_NOTARIZE_PROFILE` *(optional)* — the keychain profile name to submit
|
77
|
-
the archive for notarization. When present, the script zips the `.app`,
|
78
|
-
submits it with `notarytool --wait`, and staples the returned ticket.
|
79
|
-
|
80
|
-
The codesigning step executes only when the variables are provided, so the build
|
81
|
-
continues to work unchanged for local development.
|
82
|
-
|
83
|
-
### Graphical Interface
|
84
|
-
|
85
|
-
- **Simple mode** — the default experience shrinks the window to a large drop
|
86
|
-
zone, hides the manual run controls and log, and automatically processes new
|
87
|
-
files as soon as you drop them. Uncheck the box to return to the full layout
|
88
|
-
with file pickers, the Run button, and detailed logging.
|
89
|
-
- **Input drop zone** — drag files or folders from your desktop, click to open
|
90
|
-
the system file picker, or add them via the Explorer/Finder dialog; duplicates
|
91
|
-
are ignored.
|
92
|
-
- **Small video** — toggles the `--small` preset used by the CLI.
|
93
|
-
- **Open after convert** — controls whether the exported file is revealed in
|
94
|
-
your system file manager as soon as each job finishes.
|
95
|
-
- **Advanced** — reveals optional controls for the output path, temp folder,
|
96
|
-
timing/audio knobs mirrored from the command line, and an appearance picker
|
97
|
-
that can force dark or light mode or follow your operating system.
|
98
|
-
|
99
|
-
Progress updates stream into the 10-line log panel while the processing runs in
|
100
|
-
a background thread. Once every queued job succeeds an **Open last output**
|
101
|
-
button appears so you can jump straight to the exported file in your system
|
102
|
-
file manager.
|
103
|
-
|
104
|
-
The GUI stores your last-used Simple mode, Small video, Open after convert, and
|
105
|
-
theme preferences in a cross-platform configuration file so they persist across
|
106
|
-
launches.
|
107
|
-
|
108
|
-
## Repository Structure
|
109
|
-
- `talks_reducer/` — Python package that exposes the CLI and reusable pipeline:
|
110
|
-
- `cli.py` parses arguments and dispatches to the pipeline.
|
111
|
-
- `pipeline.py` orchestrates FFmpeg, audio processing, and temporary assets.
|
112
|
-
- `audio.py` handles audio validation, volume analysis, and phase vocoder processing.
|
113
|
-
- `chunks.py` builds timing metadata and FFmpeg expressions for frame selection.
|
114
|
-
- `ffmpeg.py` discovers the FFmpeg binary, checks CUDA availability, and assembles command strings.
|
115
|
-
- `requirements.txt` — Python dependencies for local development.
|
116
|
-
- `default.nix` — reproducible environment definition for Nix users.
|
117
|
-
- `CONTRIBUTION.md` — development workflow, formatting expectations, and release checklist.
|
118
|
-
- `AGENTS.md` — maintainer tips and coding conventions for this repository.
|
119
|
-
|
120
|
-
## Highlights
|
121
|
-
- Builds on gegell's classic jumpcutter workflow with more efficient frame and audio processing
|
122
|
-
- Generates FFmpeg filter graphs instead of writing temporary frames to disk
|
123
|
-
- Streams audio transformations in memory to avoid slow intermediate files
|
124
|
-
- Accepts multiple inputs or directories of recordings in a single run
|
125
|
-
- Provides progress feedback via `tqdm`
|
126
|
-
- Automatically detects NVENC availability, so you no longer need to pass `--cuda`
|
127
|
-
|
128
|
-
## Processing Pipeline
|
129
|
-
1. Validate that each input file contains an audio stream using `ffprobe`.
|
130
|
-
2. Extract audio and calculate loudness to identify silent regions.
|
131
|
-
3. Stretch the non-silent segments with `audiotsm` to maintain speech clarity.
|
132
|
-
4. Stitch the processed audio and video together with FFmpeg, using NVENC if the GPU encoders are detected.
|
133
|
-
|
134
|
-
## Recent Updates
|
135
|
-
- **October 2025** — Project renamed to *Talks Reducer* across documentation and scripts.
|
136
|
-
- **October 2025** — Added `--small` preset with 720p/128 kbps defaults for bandwidth-friendly exports.
|
137
|
-
- **October 2025** — Removed the `--cuda` flag; CUDA/NVENC support is now auto-detected.
|
138
|
-
|
139
|
-
## Changelog
|
140
|
-
Major and minor releases are tracked in `CHANGELOG.md`. The log is generated from
|
141
|
-
Conventional Commits that start with either `feat:` or `fix:`. Only tags in the
|
142
|
-
form `v<major>.<minor>.0` are included so patch releases (for example,
|
143
|
-
`v1.1.1`) are omitted. Regenerate the file whenever you cut a release:
|
144
|
-
|
145
|
-
```bash
|
146
|
-
python scripts/generate_changelog.py
|
147
|
-
```
|
148
|
-
|
149
|
-
CI will fail if the generated changelog does not match the committed version, so
|
150
|
-
run the script before opening a pull request that updates release tags.
|
151
|
-
|
152
|
-
## Contributing
|
153
|
-
See `CONTRIBUTION.md` for development setup details and guidance on sharing improvements.
|
154
|
-
|
155
|
-
## License
|
156
|
-
Talks Reducer is released under the MIT License. See `LICENSE` for the full text.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|