Files
WhisperLive/examples/manual_audio_chunking.py
T

79 lines
3.1 KiB
Python

"""
Manual audio chunking example for WhisperLive.
Streams an audio file to a running WhisperLive server in real-time sized chunks,
printing partial transcripts when speech is detected and committed transcripts
when each segment is finalized.
Usage:
python examples/manual_audio_chunking.py --file assets/jfk.flac
"""
import argparse
import os
import sys
import time
import wave
try:
from whisper_live.client import StreamingTranscriptionClient
from whisper_live.utils import resample
except ImportError: # just in case whisper_live isn't installed.
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
print("[INFO] whisper_live not installed or the current version does not have StreamingTranscriptionClient. Will attempt to import from local source.")
from whisper_live.client import StreamingTranscriptionClient
from whisper_live.utils import resample
SAMPLE_RATE = 16000
def stream_audio_file(path: str, client: StreamingTranscriptionClient, chunk_ms: int = 50) -> None:
"""Read an audio file, resample to 16 kHz mono if needed, and pace chunks in real time."""
resampled_path = resample(path)
try:
with wave.open(resampled_path, "rb") as wf:
frames_per_chunk = SAMPLE_RATE * chunk_ms // 1000
chunk_duration = frames_per_chunk / SAMPLE_RATE
while chunk := wf.readframes(frames_per_chunk):
client.send(chunk, pcm_format="int16")
time.sleep(chunk_duration)
finally:
os.remove(resampled_path)
def main():
parser = argparse.ArgumentParser(description="Stream an audio file to WhisperLive.")
parser.add_argument("--file", "-f", required=True, help="Audio file to transcribe (any format supported by ffmpeg).")
parser.add_argument("--server", "-s", default="localhost")
parser.add_argument("--port", "-p", type=int, default=9090)
parser.add_argument("--model", "-m", default="small")
parser.add_argument("--lang", "-l", default="en")
parser.add_argument("--chunk_ms", type=int, default=50, help="Chunk size in ms.")
args = parser.parse_args()
client = StreamingTranscriptionClient(
args.server, args.port,
lang=args.lang,
model=args.model,
on_session_started=lambda: print("[INFO] Server ready.\n"),
on_partial_transcript=lambda text, _: print(f"\r{text:<80}", end="", flush=True),
on_committed_transcript=lambda text, _: print(f"\r{text:<80}"),
on_error=lambda e: print(f"\n[ERROR] {e}"),
on_close=lambda: print("\n[INFO] Connection closed."),
)
with client:
print(f"[INFO] Streaming {args.file} in {args.chunk_ms} ms chunks.")
stream_audio_file(args.file, client, chunk_ms=args.chunk_ms)
print("\n[INFO] Final transcript:")
for seg in client.transcript:
print(f" [{float(seg['start']):.2f}s → {float(seg['end']):.2f}s] {seg['text'].strip()}")
seg = client.last_partial
if seg:
print(f" [{float(seg['start']):.2f}s → {float(seg['end']):.2f}s] {seg['text'].strip()} (partial)")
if __name__ == "__main__":
main()