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.
- {videopython-0.52.0 → videopython-0.52.1}/PKG-INFO +1 -1
- {videopython-0.52.0 → videopython-0.52.1}/pyproject.toml +1 -1
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/pipeline.py +41 -40
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/separation.py +1 -6
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/classification.py +0 -4
- {videopython-0.52.0 → videopython-0.52.1}/.gitignore +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/LICENSE +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/README.md +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_device.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_ollama.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_optional.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_predictor.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/_revisions.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/backend.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/catalog.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/editor.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/local.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/models.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/auto_edit/resolve.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/_tts_backend.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/audio_ops.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/config.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/dubber.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/models.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/quality.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/remux.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/timing.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/translation.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/dubbing/voice_sample.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/effects.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/errors.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/audio.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/image.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/generation/video.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/keyframe.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/ops.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/transforms.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/_yolo.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/audio.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/faces.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/image.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/objects.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/temporal.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/analyzer.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/detectors.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/models.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/sampling.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/source_metadata.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/audio/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/audio/analysis.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/audio/audio.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/_dimensions.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/_ffmpeg.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/_video_io.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/description.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/draw_detections.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/exceptions.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Anton-OFL.txt +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Anton-Regular.ttf +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/BebasNeue-OFL.txt +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/BebasNeue-Regular.ttf +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/DejaVuSans.ttf +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/LICENSE_DEJAVU +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Lato-Bold.ttf +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Lato-OFL.txt +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Poppins-Bold.ttf +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/Poppins-OFL.txt +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/fonts/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/transcription.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/base/video.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/_ass.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/_easing.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/_schema.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/audio_ops.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/effects.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/operation.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/streaming.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/transcription_overlay.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/transforms.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/editing/video_edit.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/mcp/__init__.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/mcp/server.py +0 -0
- {videopython-0.52.0 → videopython-0.52.1}/src/videopython/py.typed +0 -0
|
@@ -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
|
-
|
|
359
|
-
|
|
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
|
-
|
|
531
|
-
|
|
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.
|
|
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
|
|
{videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/understanding/classification.py
RENAMED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
{videopython-0.52.0 → videopython-0.52.1}/src/videopython/ai/video_analysis/source_metadata.py
RENAMED
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|