Voice Transcripts is an Axis ACAP for continuous speech transcription on device microphones.
It supports two user-selectable operating modes:
- Continuous transcription: quality-focused, longer utterances, sentence/pause splitting.
- Voice commands: speed-focused, keyword-gated, fuzzy keyword matching.
- Captures audio from the processed Axis input path (
AudioDevice0Input0). - Runs VAD + utterance segmentation continuously.
- Uses either:
- internal
whisper.cppinference on device, or - external Wyoming Whisper server.
- internal
- Stores transcript history for the web UI/API.
- Publishes transcript events over MQTT.
./build.shProduces an aarch64 .eap package (includes local whisper.cpp + bundled models).
For armv7hf external-only builds:
./build-armv7hf.shEquivalent:
./build.sh armv7hfThis variant excludes local whisper/model assets and requires stt_mode=external.
./install.sh <device-host> <user> <password> aarch64For armv7hf packages:
./install.sh <device-host> <user> <password> armv7hfOpen:
http://<device-host>/local/voice/
Then set:
- STT backend (
internalorexternal) - Language
- Sensitivity / silence timeout / min speech / max utterance
- Use case (
continuousorvoice_commands) - Command keywords (for voice command mode)
- MQTT broker settings
Optimized for transcript quality and long-form capture.
Behavior:
- Splits transcript output on sentence/pause boundaries when possible.
- Ignores transcript fragments shorter than 3 words.
- Publishes accepted transcripts to MQTT topic
voice/transcription.
Optimized for speed and command intent extraction.
Behavior:
- Expects short utterances (typically 3-10 words).
- Ignores utterances shorter than the configured minimum command words (1-5, default 3).
- Requires at least one keyword fuzzy match.
- If no keyword match:
- transcript is still shown in UI history,
- marked as
Ignored, - not published to MQTT.
- Publishes accepted command transcripts to MQTT topic
voice/command.
Fuzzy keyword matching handles:
- exact matches,
- common singular/plural forms,
- minor edit-distance transcription errors.
All endpoints are under:
/local/voice/
Returns app metadata, runtime status snapshot, and settings.
Returns live runtime status keys used by UI.
Returns current settings JSON.
Applies settings immediately.
Example payload:
{
"transcription_use_case": "voice_commands",
"command_keywords": "light,lights,garage,gate",
"command_min_words": 3,
"stt_mode": "external",
"wyoming_host": "bart.internal",
"wyoming_whisper_port": 10300,
"enabled": true,
"input_node": "AudioDevice0Input0",
"language": "sv",
"translate": false,
"sensitivity": "normal",
"silence_timeout_ms": 450,
"min_speech_ms": 180,
"max_utterance_sec": 6,
"inference_threads": 3,
"max_tokens": 32
}Returns transcript history (newest first).
Example entry:
{
"ts": 1783527405123,
"utterance_start_ms": 1783527401044,
"duration_ms": 4079,
"ignored": false,
"language": "sv",
"text": "turn on the garage lights",
"keywords": ["garage", "lights"]
}Clears transcript history and counters.
Gets or updates MQTT connectivity and payload metadata settings.
MQTT_Publish_JSON automatically:
- prepends configured
preTopicif set, - injects
serial, - injects optional
nameandlocationfrom MQTT settings.
- Continuous mode:
voice/transcription - Voice command mode:
voice/command
Final broker topic becomes:
<preTopic>/voice/transcriptionor<preTopic>/voice/command
when preTopic is configured.
{
"language": "sv",
"text": "turn on the garage lights",
"timestamp": 1783527401044,
"keywords": ["garage", "lights"],
"serial": "B8A44F3024BB",
"name": "Lobby Hub",
"location": "Building A Floor 1"
}Field notes:
timestampis epoch milliseconds when utterance start was detected.keywordscontains detected keyword matches. It can be empty in continuous mode.
If stt_mode=external, configure:
wyoming_hostwyoming_whisper_port
Install on the external server:
python3 -m pip install -U wyoming-faster-whisperRun a common base-model service (CPU-friendly default):
python3 -m wyoming_faster_whisper \
--uri tcp://0.0.0.0:10300 \
--data-dir ~/assistant/whisper \
--model base \
--language en \
--device cpu \
--compute-type int8 \
--beam-size 1Typical alternatives:
- Use
--language sv(or other language code) to lock transcription language. - Use
--languageomitted for auto language handling on server side. - Use
--device cuda --compute-type float16for higher throughput on NVIDIA GPU hosts.
Then set in ACAP configuration:
stt_mode = externalwyoming_host = <server-hostname-or-ip>wyoming_whisper_port = 10300
More detailed Wyoming Whisper options and deployment guidance:
Recommended service package versions:
wyoming-faster-whisper>=3.3.1wyoming-piper>=2.2.2(if TTS services are also running on same host)
- armv7hf build is compiled as external-only (
stt_modeforced toexternal). - Local whisper inference is not available in this package.
- Whisper models are not bundled into the armv7hf
.eap. wyoming_hostandwyoming_whisper_portmust be configured for transcription.
Availability:
- Supported by the default aarch64 build.
- Not available in armv7hf external-only build.
Pros:
- No additional servers or network dependencies.
- Simplest deployment and maintenance.
- Better resilience in isolated/offline environments.
Cons:
- Limited by camera/hub compute resources.
- Lower maximum throughput for concurrent or heavy workloads.
- Less flexibility for large model variants.
Pros:
- Higher performance on dedicated CPU/GPU servers.
- Better for high-rate or multi-device transcription workloads.
- Easier to scale model/runtime independently of ACAP package.
Cons:
- Requires additional server setup/operations.
- Depends on network stability and server availability.
- Adds infrastructure complexity (service supervision, updates, monitoring).
enabled ("Continuous listening enabled" in UI):
true: continuously monitors microphone and processes utterances.false: keeps app running but drops utterances (no transcription output).
For implementation details, architecture, extension points, and contributor workflow, see:
- Buy me a coffee: https://www.buymeacoffee.com/fredjuhlinl
- Pull requests are highly appreciated.
BSD 3-Clause with third-party notices.
Initial commit