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.
Files changed (27) hide show
  1. talks_reducer-0.3.3/PKG-INFO +70 -0
  2. talks_reducer-0.3.3/README.md +45 -0
  3. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/pyproject.toml +1 -1
  4. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/cli.py +9 -0
  5. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/gui.py +41 -42
  6. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/models.py +3 -0
  7. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/pipeline.py +11 -0
  8. talks_reducer-0.3.3/talks_reducer.egg-info/PKG-INFO +70 -0
  9. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/tests/test_pipeline_service.py +9 -3
  10. talks_reducer-0.3.2/PKG-INFO +0 -156
  11. talks_reducer-0.3.2/README.md +0 -131
  12. talks_reducer-0.3.2/talks_reducer.egg-info/PKG-INFO +0 -156
  13. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/LICENSE +0 -0
  14. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/setup.cfg +0 -0
  15. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/__init__.py +0 -0
  16. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/__main__.py +0 -0
  17. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/audio.py +0 -0
  18. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/chunks.py +0 -0
  19. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/ffmpeg.py +0 -0
  20. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer/progress.py +0 -0
  21. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/SOURCES.txt +0 -0
  22. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/dependency_links.txt +0 -0
  23. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/entry_points.txt +0 -0
  24. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/requires.txt +0 -0
  25. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/talks_reducer.egg-info/top_level.txt +0 -0
  26. {talks_reducer-0.3.2 → talks_reducer-0.3.3}/tests/test_audio.py +0 -0
  27. {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
+ ![Main demo](docs/assets/screencast-main.gif)
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
+ ![Main demo](docs/assets/screencast-main.gif)
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.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "talks-reducer"
7
- version = "0.3.2"
7
+ version = "0.3.3"
8
8
  description = "CLI for speeding up long-form talks by removing silence"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -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(row=0, column=2, sticky="w", padx=(12, 0))
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._append_log(f"Completed: {result.output_file}")
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
- self._set_status("Success")
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
- if "extracting audio" in status.lower() or re.search(
1189
- r"\d{2}:\d{2}:\d{2}.*\d+\.?\d*x", status
1190
- ):
1191
- self.status_label.configure(fg=STATUS_COLORS["processing"])
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
- self.status_var.set(status)
1198
- self._apply_status_style(status)
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"
@@ -36,6 +36,9 @@ class ProcessingResult:
36
36
  output_file: Path
37
37
  frame_rate: float
38
38
  original_duration: float
39
+ output_duration: float
39
40
  chunk_count: int
40
41
  used_cuda: bool
41
42
  max_audio_volume: float
43
+ time_ratio: Optional[float]
44
+ size_ratio: Optional[float]
@@ -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
+ ![Main demo](docs/assets/screencast-main.gif)
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
- monkeypatch.setattr(
91
- "talks_reducer.pipeline.run_timed_ffmpeg_command", lambda *a, **k: None
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
@@ -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.
@@ -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