Skip to content

examples.closed_captions

Closed Captions (CC) - Real-time Subtitles Ultra low-latency transcription for live subtitles/closed captions.

View the complete module source at #L1-L166.

API details

Each callable below includes its exact signature, type annotations, inputs, defaults, return contract, documented exceptions, implementation source, and parsed docstring sections when the source provides them.

examples.closed_captions

Closed Captions (CC) - Real-time Subtitles

Ultra low-latency transcription for live subtitles/closed captions. Small chunks, fast processing, continuous output.

Usage

python examples/closed_captions.py python examples/closed_captions.py --language es

Requirements

pip install sounddevice soundfile numpy

examples.closed_captions.MODEL_ALIASES module-attribute

MODEL_ALIASES = {'whisper-small': 'mlx-community/whisper-small-mlx', 'whisper-medium': 'mlx-community/whisper-medium-mlx', 'whisper-large-v3': 'mlx-community/whisper-large-v3-mlx', 'whisper-turbo': 'mlx-community/whisper-large-v3-turbo', 'parakeet': 'mlx-community/parakeet-tdt-0.6b-v2'}

examples.closed_captions.SAMPLE_RATE module-attribute

SAMPLE_RATE = 16000

examples.closed_captions.ClosedCaptions

ClosedCaptions(model_name: str, language: str = None, chunk_sec: float = 1.5)

Real-time closed captions.

Source code in examples/closed_captions.py
def __init__(self, model_name: str, language: str = None, chunk_sec: float = 1.5):
    self.model_name = model_name
    self.language = language
    self.chunk_sec = chunk_sec
    self.chunk_samples = int(SAMPLE_RATE * chunk_sec)

    self.audio_queue = queue.Queue()
    self.running = False
    self.engine = None

    # For display
    self.current_line = ""
    self.lines = []

examples.closed_captions.ClosedCaptions.model_name instance-attribute

model_name = model_name

examples.closed_captions.ClosedCaptions.language instance-attribute

language = language

examples.closed_captions.ClosedCaptions.chunk_sec instance-attribute

chunk_sec = chunk_sec

examples.closed_captions.ClosedCaptions.chunk_samples instance-attribute

chunk_samples = int(SAMPLE_RATE * chunk_sec)

examples.closed_captions.ClosedCaptions.audio_queue instance-attribute

audio_queue = queue.Queue()

examples.closed_captions.ClosedCaptions.running instance-attribute

running = False

examples.closed_captions.ClosedCaptions.engine instance-attribute

engine = None

examples.closed_captions.ClosedCaptions.current_line instance-attribute

current_line = ''

examples.closed_captions.ClosedCaptions.lines instance-attribute

lines = []

examples.closed_captions.ClosedCaptions.load_model

load_model()
Source code in examples/closed_captions.py
def load_model(self):
    from vllm_mlx.audio.stt import STTEngine
    self.engine = STTEngine(self.model_name)
    self.engine.load()

examples.closed_captions.ClosedCaptions.audio_callback

audio_callback(indata, frames, time_info, status)
Source code in examples/closed_captions.py
def audio_callback(self, indata, frames, time_info, status):
    if self.running:
        self.audio_queue.put(indata.copy().flatten())

examples.closed_captions.ClosedCaptions.transcribe

transcribe(audio)
Source code in examples/closed_captions.py
def transcribe(self, audio):
    import soundfile as sf
    with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
        path = f.name
    try:
        sf.write(path, audio, SAMPLE_RATE)
        result = self.engine.transcribe(path, language=self.language)
        return result.text.strip()
    finally:
        os.unlink(path)

examples.closed_captions.ClosedCaptions.display_caption

display_caption(text)

Display caption like subtitles.

Source code in examples/closed_captions.py
def display_caption(self, text):
    """Display caption like subtitles."""
    if not text or text in [".", ""]:
        return

    # Move cursor up and clear, then print new caption
    print(f"\r\033[K  {text}", flush=True)

examples.closed_captions.ClosedCaptions.process_loop

process_loop()

Process audio continuously.

Source code in examples/closed_captions.py
def process_loop(self):
    """Process audio continuously."""
    buffer = np.array([], dtype=np.float32)
    silence_threshold = 0.008

    while self.running:
        try:
            chunk = self.audio_queue.get(timeout=0.05)
            buffer = np.concatenate([buffer, chunk])

            # Process when buffer is full
            if len(buffer) >= self.chunk_samples:
                audio = buffer[:self.chunk_samples]
                buffer = buffer[self.chunk_samples // 2:]  # 50% overlap

                # Skip if too quiet
                level = np.sqrt(np.mean(audio ** 2))
                if level < silence_threshold:
                    continue

                text = self.transcribe(audio)
                self.display_caption(text)

        except queue.Empty:
            continue

examples.closed_captions.ClosedCaptions.run

run()
Source code in examples/closed_captions.py
def run(self):
    print()
    print("┌" + "─" * 58 + "┐")
    print("│" + "  🎬 CLOSED CAPTIONS - Real-time Subtitles".center(58) + "│")
    print("└" + "─" * 58 + "┘")
    print()
    print(f"  Chunk: {self.chunk_sec}s | Model: {self.model_name.split('/')[-1]}")
    print()
    print("  Ctrl+C para salir")
    print()
    print("─" * 60)
    print()

    self.running = True

    # Start processor
    processor = threading.Thread(target=self.process_loop, daemon=True)
    processor.start()

    # Audio stream
    stream = sd.InputStream(
        samplerate=SAMPLE_RATE,
        channels=1,
        dtype=np.float32,
        callback=self.audio_callback,
        blocksize=int(SAMPLE_RATE * 0.1)
    )

    try:
        with stream:
            while True:
                time.sleep(0.1)
    except KeyboardInterrupt:
        self.running = False
        print("\n")

examples.closed_captions.main

main()
Source code in examples/closed_captions.py
def main():
    parser = argparse.ArgumentParser(description="Closed Captions - Real-time Subtitles")
    parser.add_argument("--model", "-m", default="whisper-large-v3")
    parser.add_argument("--language", "-l", default=None, help="es, en, etc.")
    parser.add_argument("--chunk", "-c", type=float, default=3.0, help="Chunk size (default: 3.0s)")
    args = parser.parse_args()

    model = MODEL_ALIASES.get(args.model, args.model)

    print("\n  Cargando modelo...")
    cc = ClosedCaptions(model, args.language, args.chunk)
    cc.load_model()
    print("  ¡Listo!")

    cc.run()

Complete contract reference

Expand any definition for its exact inputs, annotations, defaults, return contract, directly raised exceptions, source-grounded behavior, and immutable line link. This section includes private and nested definitions that ordinary API generators omit.

examples.closed_captions.ClosedCaptions · class
examples.closed_captions.ClosedCaptions(model_name: str, language: str = None, chunk_sec: float = 1.5)

Real-time closed captions.

Parameters

Name Type Required Default Description
model_name str yes none Required positional or keyword input.
language str no None Optional positional or keyword input; defaults to None.
chunk_sec float no 1.5 Optional positional or keyword input; defaults to 1.5.

Returns

  • Constructs: examples.closed_captions.ClosedCaptions

Exceptions and behavior

Class ClosedCaptions declares 7 direct member(s). No direct raise statement appears in this definition.

View source #L40-L145.

examples.closed_captions.ClosedCaptions.__init__ · method
examples.closed_captions.ClosedCaptions.__init__(model_name: str, language: str = None, chunk_sec: float = 1.5) -> not annotated

Method ClosedCaptions.__init__ updates self.model_name, self.language, self.chunk_sec, self.chunk_samples; calls int, queue.Queue.

Parameters

Name Type Required Default Description
model_name str yes none Required positional or keyword input.
language str no None Optional positional or keyword input; defaults to None.
chunk_sec float no 1.5 Optional positional or keyword input; defaults to 1.5.

Returns

  • Type: not annotated

Exceptions and behavior

Method ClosedCaptions.__init__ updates self.model_name, self.language, self.chunk_sec, self.chunk_samples; calls int, queue.Queue. No direct raise statement appears in this definition.

View source #L43-L55.

examples.closed_captions.ClosedCaptions.load_model · method
examples.closed_captions.ClosedCaptions.load_model() -> not annotated

Method ClosedCaptions.load_model updates self.engine; calls STTEngine, self.engine.load.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Method ClosedCaptions.load_model updates self.engine; calls STTEngine, self.engine.load. No direct raise statement appears in this definition.

View source #L57-L60.

examples.closed_captions.ClosedCaptions.audio_callback · method
examples.closed_captions.ClosedCaptions.audio_callback(indata, frames, time_info, status) -> not annotated

Method ClosedCaptions.audio_callback calls self.audio_queue.put, indata.copy().flatten, indata.copy.

Parameters

Name Type Required Default Description
indata not annotated yes none Required positional or keyword input.
frames not annotated yes none Required positional or keyword input.
time_info not annotated yes none Required positional or keyword input.
status not annotated yes none Required positional or keyword input.

Returns

  • Type: not annotated

Exceptions and behavior

Method ClosedCaptions.audio_callback calls self.audio_queue.put, indata.copy().flatten, indata.copy. No direct raise statement appears in this definition.

View source #L62-L64.

examples.closed_captions.ClosedCaptions.transcribe · method
examples.closed_captions.ClosedCaptions.transcribe(audio) -> not annotated

Method ClosedCaptions.transcribe calls tempfile.NamedTemporaryFile, sf.write, self.engine.transcribe, result.text.strip; returns result.text.strip().

Parameters

Name Type Required Default Description
audio not annotated yes none Required positional or keyword input.

Returns

  • Type: not annotated
  • Direct return expressions: result.text.strip()

Exceptions and behavior

Method ClosedCaptions.transcribe calls tempfile.NamedTemporaryFile, sf.write, self.engine.transcribe, result.text.strip; returns result.text.strip(). No direct raise statement appears in this definition.

View source #L66-L75.

examples.closed_captions.ClosedCaptions.display_caption · method
examples.closed_captions.ClosedCaptions.display_caption(text) -> not annotated

Display caption like subtitles.

Parameters

Name Type Required Default Description
text not annotated yes none Required positional or keyword input.

Returns

  • Type: not annotated
  • Direct return expressions: None

Exceptions and behavior

Method ClosedCaptions.display_caption calls print; returns None. No direct raise statement appears in this definition.

View source #L77-L83.

examples.closed_captions.ClosedCaptions.process_loop · method
examples.closed_captions.ClosedCaptions.process_loop() -> not annotated

Process audio continuously.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Method ClosedCaptions.process_loop calls np.array, self.audio_queue.get, np.concatenate, len. No direct raise statement appears in this definition.

View source #L85-L109.

examples.closed_captions.ClosedCaptions.run · method
examples.closed_captions.ClosedCaptions.run() -> not annotated

Method ClosedCaptions.run updates self.running; calls print, ' 🎬 CLOSED CAPTIONS - Real-time Subtitles'.center, self.model_name.split, threading.Thread.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Method ClosedCaptions.run updates self.running; calls print, ' 🎬 CLOSED CAPTIONS - Real-time Subtitles'.center, self.model_name.split, threading.Thread. No direct raise statement appears in this definition.

View source #L111-L145.

examples.closed_captions.main · function
examples.closed_captions.main() -> not annotated

Function main calls argparse.ArgumentParser, parser.add_argument, parser.parse_args, MODEL_ALIASES.get.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Function main calls argparse.ArgumentParser, parser.add_argument, parser.parse_args, MODEL_ALIASES.get. No direct raise statement appears in this definition.

View source #L148-L162.

Complete symbol map

This map also includes private definitions and nested helpers. The signature column exposes every explicit input even when an internal helper has no dedicated parameter prose.

Symbol Kind Signature and inputs What it does Source
ClosedCaptions class ClosedCaptions(model_name: str, language: str = None, chunk_sec: float = 1.5) Real-time closed captions. #L40-L145
ClosedCaptions.__init__ method ClosedCaptions.__init__(model_name: str, language: str = None, chunk_sec: float = 1.5) -> not annotated Method ClosedCaptions.__init__ updates self.model_name, self.language, self.chunk_sec, self.chunk_samples; calls int, queue.Queue. #L43-L55
ClosedCaptions.load_model method ClosedCaptions.load_model() -> not annotated Method ClosedCaptions.load_model updates self.engine; calls STTEngine, self.engine.load. #L57-L60
ClosedCaptions.audio_callback method ClosedCaptions.audio_callback(indata, frames, time_info, status) -> not annotated Method ClosedCaptions.audio_callback calls self.audio_queue.put, indata.copy().flatten, indata.copy. #L62-L64
ClosedCaptions.transcribe method ClosedCaptions.transcribe(audio) -> not annotated Method ClosedCaptions.transcribe calls tempfile.NamedTemporaryFile, sf.write, self.engine.transcribe, result.text.strip; returns result.text.strip(). #L66-L75
ClosedCaptions.display_caption method ClosedCaptions.display_caption(text) -> not annotated Display caption like subtitles. #L77-L83
ClosedCaptions.process_loop method ClosedCaptions.process_loop() -> not annotated Process audio continuously. #L85-L109
ClosedCaptions.run method ClosedCaptions.run() -> not annotated Method ClosedCaptions.run updates self.running; calls print, ' 🎬 CLOSED CAPTIONS - Real-time Subtitles'.center, self.model_name.split, threading.Thread. #L111-L145
main function main() -> not annotated Function main calls argparse.ArgumentParser, parser.add_argument, parser.parse_args, MODEL_ALIASES.get. #L148-L162