A client library for the Voxium real-time transcription service
Project description
Voxium Real-Time Transcription Client
This project provides a Python client library for interacting with the Voxium real-time speech-to-text (ASR) WebSocket service. It captures audio from the microphone, streams it to the Voxium server, and processes the received transcriptions via callbacks.
Key Features:
- Real-time Audio Streaming: Captures microphone audio using
sounddevice. - WebSocket Communication: Connects to and communicates with the Voxium ASR WebSocket endpoint using
websockets. - Asynchronous Operation: Built using
asynciofor efficient non-blocking I/O. - Thread-Safe Audio Handling: Safely transfers audio data from the
sounddevicecallback thread to the mainasyncioevent loop usingasyncio.Queue. - Configurable Parameters: Allows setting language, VAD thresholds, API keys, and other parameters for the Voxium service.
- Callback-Based API: Provides asynchronous callbacks for handling transcription results, errors, connection events (open/close).
- Simplified Usage: Offers a high-level
LiveTranscriberclass with a blockingstart_transcriptionmethod for easy integration.
Table of Contents
- Prerequisites
- Installation
- Configuration
- Usage
- Core Components
- Callbacks
- Logging
- How it Works
- Dependencies
- Troubleshooting
Prerequisites
- Python: Version 3.7+ (due to
asynciousage) - Microphone: A working microphone connected to your system and recognized by
sounddevice. - PortAudio: The
sounddevicelibrary depends on the PortAudio library. Installation varies by OS:- macOS:
brew install portaudio - Debian/Ubuntu:
sudo apt-get install libportaudio2 libportaudiocpp0 portaudio19-dev - Windows: Often included with Python distributions or audio drivers. Check the sounddevice documentation for details.
- macOS:
- Voxium API Key: You need an API key from Voxium to authenticate with the service.
Installation
- From Source
git clone https://github.com/nathanmfrench/voxium-client
pip install -r requirements.txt
- From Package Manager:
pip install voxium
(or you can use your package manager of choice)
Configuration
Configuration is primarily done within your Python script (like example_usage.py):
VOXIUM_API_KEY: Required. Replace the placeholder"YOUR_API_KEY_HERE"with your actual Voxium API key. This is sent as a query parameter (apiKey) for authentication.VOXIUM_SERVER_URL: The WebSocket endpoint URL for the Voxium ASR service. Defaults to"wss://voxium.tech/asr/ws".VOXIUM_LANGUAGE: The language code for transcription (e.g.,"en","es","fr"). Defaults to"en".- Other Parameters: You can customize other parameters when initializing
LiveTranscriberorVoxiumClient:vad_threshold(float): Voice Activity Detection threshold (client-side hint for server).silence_threshold(float): Server-side silence duration parameter, controls length of silence before sending an audio chunk.sample_rate(int): Audio sample rate (hardcoded to 16000 Hz inlive_transcribe.py).input_format(str): Expected audio format on the server after base64 decoding (hardcoded to"base64"inlive_transcribe.pyas the client sends base64).beam_size(int): Beam size controls number of search candidates at each step (set to 1 for greedy decoding).language(str): 2 digit ISO-code for the desired language. 'None' to auto-detect (language and probability passed to client as language, language_probability respectively)
50 Supported languages: Arabic (ar), Armenian (hy), Azerbaijani (az), Belarusian (be), Bosnian (bs), Bulgarian (bg), Catalan (ca), Chinese (zh), Croatian (hr), Czech (cs), Danish (da), Dutch (nl), English (en), Estonian (et), Finnish (fi), French (fr), German (de), Greek (el), Hebrew (he), Hindi (hi), Hungarian (hu), Icelandic (is), Indonesian (id), Italian (it), Japanese (ja), Kannada (kn), Korean (ko), Latvian (lv), Lithuanian (lt), Macedonian (mk), Malay (ms), Nepali (ne), Norwegian (no), Persian (fa), Polish (pl), Portuguese (pt), Romanian (ro), Russian (ru), Serbian (sr), Slovak (sk), Slovenian (sl), Spanish (es), Swedish (sv), Tagalog (tl), Tamil (ta), Thai (th), Turkish (tr), Ukrainian (uk), Urdu (ur), Vietnamese (vi)
Usage
The example_usage.py script demonstrates how to use the LiveTranscriber.
- Import: Import the necessary classes and modules.
- Configure Logging: Set up Python's
loggingmodule (the example provides a basic console logger). - Define Transcription Handler: Create an
asyncfunction that will receive transcription results (dictionaries). This is where you integrate the text into your application logic. - Set Parameters: Define your API key, server URL, and language.
- Initialize
LiveTranscriber: Create an instance, passing the configuration parameters. - Start Transcription: Call the
start_transcriptionmethod, providing your handler function. This method is blocking and will run until interrupted (e.g., Ctrl+C) or a critical error occurs.
import logging
from voxium_client import LiveTranscriber
# --- 1. Configure Logging ---
# This basic setup logs WARNING level messages and above to the console.
# It's sufficient for most examples (you can implement more complex logging if needed).
# Set level=logging.DEBUG for debugging logs, and level=logging.INFO for normal logs.
logging.basicConfig(
level=logging.WARNING,
format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger("MyVoiceAgentExample")
# --- 2. Define Your Transcription Handler (Required) ---
# This asynchronous function will receive transcription results.
async def handle_transcription(result: dict):
"""
Callback function to process transcription results from Voxium.
'result' is a dictionary.
"""
try:
text = result.get('transcription', '')
print("Transcription: ", text)
# Now, you can ntegrate the transcription text into your voice agent's pipeline. For example:
# await send_to_my_agent_logic(text)
except Exception as e:
logger.error(f"Error within handle_transcription callback: {e}", exc_info=True)
# --- 3. Main Execution ---
if __name__ == "__main__":
logger.info("Starting Voxium LiveTranscriber Integration Example...")
# --- Configuration Parameters ---
VOXIUM_API_KEY = "YOUR_API_KEY_HERE"
if VOXIUM_API_KEY == "YOUR_API_KEY_HERE":
logger.warning("Using placeholder API Key. Please set the VOXIUM_API_KEY environment variable or replace the placeholder.")
VOXIUM_SERVER_URL = "wss://voxium.tech/asr/ws"
VOXIUM_LANGUAGE = "en"
# --- Initialize the Transcriber ---
logger.info(f"Initializing LiveTranscriber for {VOXIUM_LANGUAGE}...")
transcriber = LiveTranscriber(
server_url=VOXIUM_SERVER_URL,
language=VOXIUM_LANGUAGE,
api_key=VOXIUM_API_KEY
# Add/override other parameters if needed:
# vad_threshold=0.5,
# silence_threshold=0.5,
)
# --- Start the Transcription Process ---
# This is a blocking call that runs the transcriber until stopped (Ctrl+C or error).
# It requires your 'on_transcription' callback function.
logger.info("Starting transcription. Press Ctrl+C to stop.")
try:
transcriber.start_transcription(
on_transcription=handle_transcription
# --- Optional Callbacks ---
# You can provide your own async functions for other events:
# on_error=my_async_error_handler,
# on_open=my_async_open_handler,
# on_close=my_async_close_handler
)
except Exception as e:
logger.critical(f"Failed to run transcription: {e}", exc_info=True)
logger.info("Transcription process finished.")
Run script from your terminal with
python3 example_usage.py
Core Components
VoxiumClient (client.py)
- Manages the low-level WebSocket connection lifecycle (
connect,close). - Handles URL construction with query parameters (including the API key).
- Formats outgoing audio messages (encodes audio bytes to Base64 JSON).
- Runs a persistent
_receivertask to listen for incoming messages (transcriptions, status, errors) from the server. - Parses incoming JSON messages and routes them to the appropriate asynchronous callbacks.
- Provides setter methods (
set_transcription_callback,set_error_callback, etc.) for registering custom handlers. - Implements
asynccontext manager protocols (__aenter__,__aexit__) for automatic connection setup and teardown. - Handles WebSocket connection errors and state changes.
LiveTranscriber (live_transcribe.py)
- Acts as the primary interface for users.
- Initializes and manages the
VoxiumClient. - Uses
sounddevice.InputStreamto capture audio from the default microphone in a separate thread. - The
_audio_callbackfunction (running in thesounddevicethread) converts audio chunks (numpy.ndarray) to bytes. - Uses
loop.call_soon_threadsafeto safely put the audio bytes onto anasyncio.Queuefrom thesounddevicethread. - An
_audio_loopasynctask runs in the main event loop, consuming audio bytes from the queue. - Sends audio chunks to the server via the
VoxiumClient.send_audio_chunkmethod. - Manages the starting (
start) and stopping (stop,cleanup_audio) of the audio stream and processing loop. - Provides the simplified, blocking
start_transcriptionmethod which:- Sets up default callbacks if user doesn't provide them.
- Assigns user-provided callbacks to the underlying
VoxiumClient. - Checks basic
sounddevicesettings before starting. - Uses
asyncio.run()to manage the event loop and run the mainstartcoroutine. - Handles
KeyboardInterruptfor graceful shutdown.
Callbacks
The LiveTranscriber.start_transcription method accepts several optional async callback functions:
on_transcription(result: dict): (Required) Called whenever a transcription message (partial or final) is received from the server. Theresultdictionary typically contains keys like"transcription"(the text) and"is_final"(boolean).on_error(error: Union[Exception, str]): Called when the server sends an error status message or when certain client-side processing errors occur (like in the audio loop or message handling).on_open(info: dict): Called once after the WebSocket connection is successfully established and the initial server handshake is complete. Theinfodictionary contains details sent by the server (e.g., model info).on_close(code: int, reason: str): Called when the WebSocket connection is closed, either cleanly or due to an error detected by the underlyingwebsocketslibrary within the receiver task. Provides the close code and reason.
If you don't provide on_error, on_open, or on_close, default handlers that log the event will be used.
Note: The underlying VoxiumClient also has a connection_error_callback specifically for errors during the connection phase or WebSocket-level close errors not caught by the receiver loop's ConnectionClosed... exceptions. This isn't directly exposed via start_transcription but is used internally and logs errors.
Logging
The code uses Python's standard logging module.
example_usage.pysets up a basic configuration that logsINFOlevel messages and above to the console.client.pyandlive_transcribe.pyobtain their own loggers (logging.getLogger(__name__)).- You can customize the logging level and format in
example_usage.py(e.g., setlevel=logging.DEBUGfor verbose output, or add file handlers).
How it Works
LiveTranscriber.start_transcriptionis called.- It configures callbacks on the
VoxiumClientinstance. - It runs
asyncio.run(_run_internal), which callsLiveTranscriber.start. LiveTranscriber.startgets the current event loop.- It enters the
VoxiumClientasync context (__aenter__), which callsclient.connect. client.connectestablishes the WebSocket connection, handles authentication, receives initial info, and starts theclient._receivertask in the background.LiveTranscriber.startcallssetup_audio, which creates and startssounddevice.InputStream. The_audio_callbackbegins running in a separate thread._audio_callbackcaptures audio chunks, converts them to bytes, and usesloop.call_soon_threadsafeto put them on theaudio_queue.LiveTranscriber.startstarts the_audio_looptask._audio_loopwaits for audio bytes from theaudio_queue.- When audio arrives,
_audio_loopcallsclient.send_audio_chunk. client.send_audio_chunkbase64 encodes the audio and sends it as a JSON message over the WebSocket.- Concurrently,
client._receiverlistens for messages from the server. - When a transcription message arrives,
_receiverparses it and calls the registeredon_transcriptioncallback (yourhandle_transcriptionfunction). - This continues until
start_transcriptionis interrupted (Ctrl+C) or a fatal error occurs. - On exit (interrupt or completion/error of
start),asyncio.runhandles task cancellation. Thefinallyblocks instartand the client's__aexit__method (close) ensure the audio stream and WebSocket connection are cleaned up.
Dependencies
websockets: For WebSocket client implementation.numpy: For handling audio data arrays fromsounddevice.sounddevice: For accessing the microphone and capturing audio streams.typing: For type checking
Troubleshooting
PortAudioError/ No Sound / "Invalid input device":- Ensure a microphone is plugged in and enabled in your system settings.
- Verify PortAudio is installed correctly (
brew install portaudio,apt-get install ...). - Check if another application is exclusively using the microphone.
- Try specifying a device ID in
sd.InputStream(device=...)if the default is wrong. Usepython -m sounddeviceto list devices. - Ensure the microphone supports the required settings (16000 Hz, Mono, 16-bit Integer -
RATE,CHANNELS,SD_DTYPE).
- Connection Refused / Invalid Status Code / Timeout:
- Double-check the
VOXIUM_SERVER_URL. - Verify your
VOXIUM_API_KEYis correct and valid. - Check your internet connection and any firewall/proxy settings that might block WebSocket connections (port 443 for
wss://).
- Double-check the
- Authentication Errors:
- Ensure the
apiKeyquery parameter is being sent correctly (check logs ifDEBUGlevel enabled) and matches what Voxium expects.
- Ensure the
- No Transcriptions Received:
- Check if the microphone is picking up sound (enable
DEBUGlogging to see audio chunk scheduling/sending). - Verify the correct
VOXIUM_LANGUAGEis set. - Look for error messages in the logs from the client or server.
- Check if the microphone is picking up sound (enable
- Import Errors:
- Ensure the Python files (
client.py,live_transcribe.py) are located where Python can find them (e.g., same directory as your main script, or installed as part of a package). Adjust import statements (from .client ...vsfrom voxium_client ...) as needed based on your project structure.
- Ensure the Python files (
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file voxium-0.2.0.tar.gz.
File metadata
- Download URL: voxium-0.2.0.tar.gz
- Upload date:
- Size: 16.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41059d2d6c9ce2c303363b67d61096bf9d9664d34775d28af469f4ad5c014e12
|
|
| MD5 |
1027ef784d150c5b593d5f852e46c230
|
|
| BLAKE2b-256 |
6fc194357cf861720463733235db6c39983043113d54f12856f197e56fd69466
|
File details
Details for the file voxium-0.2.0-py3-none-any.whl.
File metadata
- Download URL: voxium-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69645d07d1db877037d93b48e57503751455695f15a795d7c73611ff6cba74d3
|
|
| MD5 |
e35a189a93cd72b11eef034ee55c5458
|
|
| BLAKE2b-256 |
f2159af569123e34a989f98bf29d3b9e5bd6f4a18896575b2bc8d78d3858f71a
|