videopython 0.52.0__tar.gz → 0.52.1__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 (92) hide show
  1. {videopython-0.52.0 → videopython-0.52.1}/PKG-INFO +1 -1
  2. {videopython-0.52.0 → videopython-0.52.1}/pyproject.toml +1 -1
  3. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/pipeline.py +41 -40
  4. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/separation.py +1 -6
  5. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/classification.py +0 -4
  6. {videopython-0.52.0 → videopython-0.52.1}/.gitignore +0 -0
  7. {videopython-0.52.0 → videopython-0.52.1}/LICENSE +0 -0
  8. {videopython-0.52.0 → videopython-0.52.1}/README.md +0 -0
  9. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/__init__.py +0 -0
  10. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/__init__.py +0 -0
  11. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_device.py +0 -0
  12. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_ollama.py +0 -0
  13. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_optional.py +0 -0
  14. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_predictor.py +0 -0
  15. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_revisions.py +0 -0
  16. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/__init__.py +0 -0
  17. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/backend.py +0 -0
  18. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/catalog.py +0 -0
  19. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/editor.py +0 -0
  20. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/local.py +0 -0
  21. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/models.py +0 -0
  22. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/resolve.py +0 -0
  23. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/__init__.py +0 -0
  24. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/_tts_backend.py +0 -0
  25. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/audio_ops.py +0 -0
  26. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/config.py +0 -0
  27. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/dubber.py +0 -0
  28. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/models.py +0 -0
  29. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/quality.py +0 -0
  30. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/remux.py +0 -0
  31. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/timing.py +0 -0
  32. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/translation.py +0 -0
  33. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/voice_sample.py +0 -0
  34. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/effects.py +0 -0
  35. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/errors.py +0 -0
  36. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/__init__.py +0 -0
  37. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/audio.py +0 -0
  38. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/image.py +0 -0
  39. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/video.py +0 -0
  40. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/keyframe.py +0 -0
  41. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/ops.py +0 -0
  42. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/transforms.py +0 -0
  43. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/__init__.py +0 -0
  44. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/_yolo.py +0 -0
  45. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/audio.py +0 -0
  46. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/faces.py +0 -0
  47. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/image.py +0 -0
  48. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/objects.py +0 -0
  49. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/temporal.py +0 -0
  50. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/__init__.py +0 -0
  51. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/analyzer.py +0 -0
  52. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/detectors.py +0 -0
  53. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/models.py +0 -0
  54. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/sampling.py +0 -0
  55. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/source_metadata.py +0 -0
  56. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/audio/__init__.py +0 -0
  57. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/audio/analysis.py +0 -0
  58. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/audio/audio.py +0 -0
  59. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/__init__.py +0 -0
  60. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/_dimensions.py +0 -0
  61. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/_ffmpeg.py +0 -0
  62. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/_video_io.py +0 -0
  63. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/description.py +0 -0
  64. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/draw_detections.py +0 -0
  65. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/exceptions.py +0 -0
  66. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Anton-OFL.txt +0 -0
  67. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Anton-Regular.ttf +0 -0
  68. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/BebasNeue-OFL.txt +0 -0
  69. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/BebasNeue-Regular.ttf +0 -0
  70. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/DejaVuSans.ttf +0 -0
  71. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/LICENSE_DEJAVU +0 -0
  72. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Lato-Bold.ttf +0 -0
  73. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Lato-OFL.txt +0 -0
  74. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Poppins-Bold.ttf +0 -0
  75. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Poppins-OFL.txt +0 -0
  76. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/__init__.py +0 -0
  77. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/transcription.py +0 -0
  78. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/video.py +0 -0
  79. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/__init__.py +0 -0
  80. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/_ass.py +0 -0
  81. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/_easing.py +0 -0
  82. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/_schema.py +0 -0
  83. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/audio_ops.py +0 -0
  84. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/effects.py +0 -0
  85. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/operation.py +0 -0
  86. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/streaming.py +0 -0
  87. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/transcription_overlay.py +0 -0
  88. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/transforms.py +0 -0
  89. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/video_edit.py +0 -0
  90. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/mcp/__init__.py +0 -0
  91. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/mcp/server.py +0 -0
  92. {videopython-0.52.0 → videopython-0.52.1}/src/videopython/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: videopython
3
- Version: 0.52.0
3
+ Version: 0.52.1
4
4
  Summary: Minimal video generation and processing library.
5
5
  Project-URL: Homepage, https://videopython.com
6
6
  Project-URL: Repository, https://github.com/bartwojtowicz/videopython/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "videopython"
3
- version = "0.52.0"
3
+ version = "0.52.1"
4
4
  description = "Minimal video generation and processing library."
5
5
  authors = [
6
6
  { name = "Bartosz Wójtowicz", email = "bartoszwojtowicz@outlook.com" },
@@ -229,6 +229,43 @@ class LocalDubbingPipeline:
229
229
  """Initialize the timing synchronizer."""
230
230
  self._synchronizer = TimingSynchronizer()
231
231
 
232
+ def _separate(
233
+ self,
234
+ source_audio: Audio,
235
+ transcription: Transcription,
236
+ progress_fraction: float,
237
+ report_progress: Callable[[str, float], None],
238
+ ) -> tuple[SeparatedAudio | None, Audio, Audio | None]:
239
+ """Demucs source separation over the speech regions; shared by process()/revoice().
240
+
241
+ Limits Demucs to the speech-bearing portion of the audio: the transcription
242
+ has already located every speech region, and separating outside those is pure
243
+ overhead (no vocals to isolate). On talk-heavy sources with silence/music gaps
244
+ this roughly halves separation time; when speech covers most of the track,
245
+ separate_regions falls back to a full-track separate().
246
+
247
+ Returns ``(separated_audio, vocal_audio, background_audio)``. In low_memory
248
+ mode the ``SeparatedAudio`` container is dropped (returned as ``None``) so
249
+ vocals and background release as soon as their last local reference goes.
250
+ """
251
+ report_progress("Separating audio", progress_fraction)
252
+ if self._separator is None:
253
+ self._init_separator()
254
+
255
+ from videopython.ai.dubbing.separation import merge_regions
256
+
257
+ speech_regions = merge_regions(
258
+ [(s.start, s.end) for s in transcription.segments],
259
+ audio_duration=source_audio.metadata.duration_seconds,
260
+ )
261
+ separated_audio = self._separator.separate_regions(source_audio, speech_regions)
262
+ self._maybe_unload("_separator")
263
+ vocal_audio = separated_audio.vocals
264
+ background_audio = separated_audio.background
265
+ if self.config.low_memory:
266
+ separated_audio = None
267
+ return separated_audio, vocal_audio, background_audio
268
+
232
269
  def _finalise_audio(
233
270
  self,
234
271
  dubbed_speech: Audio,
@@ -355,32 +392,9 @@ class LocalDubbingPipeline:
355
392
  background_audio: Audio | None = None
356
393
 
357
394
  if preserve_background:
358
- report_progress("Separating audio", 0.15)
359
- if self._separator is None:
360
- self._init_separator()
361
-
362
- # Limit Demucs to the speech-bearing portion of the audio. The
363
- # transcription has already located every speech region; running
364
- # source separation outside those is pure overhead (no vocals to
365
- # isolate). On talk-heavy sources with silence/music gaps this
366
- # roughly halves separation time. When speech covers most of the
367
- # track separate_regions falls back to a full-track separate().
368
- from videopython.ai.dubbing.separation import merge_regions
369
-
370
- speech_regions = merge_regions(
371
- [(s.start, s.end) for s in transcription.segments],
372
- audio_duration=source_audio.metadata.duration_seconds,
395
+ separated_audio, vocal_audio, background_audio = self._separate(
396
+ source_audio, transcription, 0.15, report_progress
373
397
  )
374
- separated_audio = self._separator.separate_regions(source_audio, speech_regions)
375
- self._maybe_unload("_separator")
376
- vocal_audio = separated_audio.vocals
377
- background_audio = separated_audio.background
378
- # In low_memory mode, drop the SeparatedAudio container so vocals
379
- # and background can be released as soon as their last local
380
- # reference goes (after voice-sample extraction and final overlay
381
- # respectively). The result will report separated_audio=None.
382
- if self.config.low_memory:
383
- separated_audio = None
384
398
 
385
399
  voice_samples: dict[str, Audio] = {}
386
400
  if voice_clone:
@@ -527,22 +541,9 @@ class LocalDubbingPipeline:
527
541
  background_audio: Audio | None = None
528
542
 
529
543
  if preserve_background:
530
- report_progress("Separating audio", 0.20)
531
- if self._separator is None:
532
- self._init_separator()
533
-
534
- from videopython.ai.dubbing.separation import merge_regions
535
-
536
- speech_regions = merge_regions(
537
- [(s.start, s.end) for s in transcription.segments],
538
- audio_duration=source_audio.metadata.duration_seconds,
544
+ separated_audio, vocal_audio, background_audio = self._separate(
545
+ source_audio, transcription, 0.20, report_progress
539
546
  )
540
- separated_audio = self._separator.separate_regions(source_audio, speech_regions)
541
- self._maybe_unload("_separator")
542
- vocal_audio = separated_audio.vocals
543
- background_audio = separated_audio.background
544
- if self.config.low_memory:
545
- separated_audio = None
546
547
 
547
548
  report_progress("Extracting voice sample", 0.40)
548
549
  chosen_sample: Audio | None = None
@@ -59,14 +59,9 @@ def merge_regions(
59
59
  class AudioSeparator(ManagedPredictor):
60
60
  """Separates audio into vocals and background components using Demucs."""
61
61
 
62
- SUPPORTED_MODELS: list[str] = ["htdemucs", "htdemucs_ft", "htdemucs_6s", "mdx_extra"]
63
62
  STEM_NAMES = ["drums", "bass", "other", "vocals"]
64
- STEM_NAMES_6S = ["drums", "bass", "other", "vocals", "guitar", "piano"]
65
63
 
66
64
  def __init__(self, model_name: str = "htdemucs", device: str | None = None):
67
- if model_name not in self.SUPPORTED_MODELS:
68
- raise ValueError(f"Model '{model_name}' not supported. Supported: {self.SUPPORTED_MODELS}")
69
-
70
65
  self.model_name = model_name
71
66
  self.device = device
72
67
  self._model: Any = None
@@ -129,7 +124,7 @@ class AudioSeparator(ManagedPredictor):
129
124
  sources_np = sources[0].cpu().numpy()
130
125
  del sources
131
126
 
132
- stem_names = self.STEM_NAMES_6S if self.model_name == "htdemucs_6s" else self.STEM_NAMES
127
+ stem_names = self.STEM_NAMES
133
128
  vocals_idx = stem_names.index("vocals")
134
129
  non_vocal_indices = [i for i in range(len(stem_names)) if i != vocals_idx]
135
130
 
@@ -23,7 +23,6 @@ class AudioClassifier(ManagedPredictor):
23
23
  """Audio event and sound classification using AST."""
24
24
 
25
25
  _model_attrs = ("_model", "_processor")
26
- SUPPORTED_MODELS: list[str] = ["MIT/ast-finetuned-audioset-10-10-0.4593"]
27
26
  AST_SAMPLE_RATE: int = 16000
28
27
  AST_CHUNK_SECONDS: float = 10.0
29
28
  AST_HOP_SECONDS: float = 5.0
@@ -35,9 +34,6 @@ class AudioClassifier(ManagedPredictor):
35
34
  top_k: int = 10,
36
35
  device: str | None = None,
37
36
  ):
38
- if model_name not in self.SUPPORTED_MODELS:
39
- raise ValueError(f"Model '{model_name}' not supported. Supported: {self.SUPPORTED_MODELS}")
40
-
41
37
  self.model_name = model_name
42
38
  self.confidence_threshold = confidence_threshold
43
39
  self.top_k = top_k
File without changes
File without changes
File without changes