Speech-to-text transcription using whisper.cpp, OpenAI's Whisper model
Compatibility Matrix
This table covers all DuckDB releases that have not reached end-of-life, including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.
| Platform | 1.4.4 | 1.4.5 | 1.5.5 | 1.5.6 | 2.0.0 |
|---|---|---|---|---|---|
| Linux AMD64 | |||||
| Linux ARM64 | |||||
| macOS AMD64 | |||||
| macOS ARM64 | |||||
| Windows AMD64 | |||||
| Windows ARM64 | |||||
| WebAssembly |
Installing and Loading
INSTALL whisper FROM community;
LOAD whisper;
Example
-- Transcribe an audio file
D SELECT whisper_transcribe('audio.wav', 'tiny.en');
┌──────────────────────────────────────────────────┐
│ whisper_transcribe(...) │
│ varchar │
├──────────────────────────────────────────────────┤
│ Hello, this is a test of the whisper extension. │
└──────────────────────────────────────────────────┘
-- Get detailed transcription segments with timestamps
D SELECT * FROM whisper_transcribe_segments('audio.wav', 'tiny.en');
┌────────────┬────────────┬──────────┬────────────────────┬────────────┬──────────┐
│ segment_id │ start_time │ end_time │ text │ confidence │ language │
│ int32 │ double │ double │ varchar │ double │ varchar │
├────────────┼────────────┼──────────┼────────────────────┼────────────┼──────────┤
│ 0 │ 0.00 │ 2.50 │ Hello, this is a │ 0.95 │ en │
│ 1 │ 2.50 │ 4.00 │ test of whisper. │ 0.92 │ en │
└────────────┴────────────┴──────────┴────────────────────┴────────────┴──────────┘
-- List available models
D SELECT model_name, size_mb, is_downloaded FROM whisper_list_models() LIMIT 3;
┌────────────┬─────────┬───────────────┐
│ model_name │ size_mb │ is_downloaded │
│ varchar │ int64 │ boolean │
├────────────┼─────────┼───────────────┤
│ tiny │ 75 │ false │
│ tiny.en │ 75 │ true │
│ base │ 142 │ false │
└────────────┴─────────┴───────────────┘
About whisper
A DuckDB extension for speech-to-text transcription using whisper.cpp, the C/C++ port of OpenAI's Whisper model.
Transcribe audio files directly from SQL queries in DuckDB, making it easy to process and analyze audio data alongside your other data.
Features
- Transcribe audio files (WAV, MP3, FLAC, OGG, and more)
- Live recording and transcription from microphone
- Voice-to-SQL: speak natural language questions, get query results
- Support for all Whisper models (tiny, base, small, medium, large)
- Detailed transcription segments with timestamps and confidence scores
- Automatic language detection or specify target language
- Works with file paths, BLOB data, or remote URLs
Quick Start
Download a Model
Models must be downloaded before use. They are stored in ~/.duckdb/whisper/models/.
mkdir -p ~/.duckdb/whisper/models
curl -L -o ~/.duckdb/whisper/models/ggml-tiny.en.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin
Check available models and download status:
SELECT * FROM whisper_list_models();
Transcribe an Audio File
-- Simple transcription
SELECT whisper_transcribe('audio.wav', 'tiny.en');
-- Get detailed segments with timestamps
SELECT * FROM whisper_transcribe_segments('audio.wav', 'tiny.en');
-- Translate foreign audio to English
SELECT whisper_translate('german_speech.mp3', 'small');
Example Use Cases
Transcribe Remote Audio
INSTALL httpfs;
LOAD httpfs;
SELECT whisper_transcribe(content, 'tiny.en')
FROM read_blob('https://example.com/audio.mp3');
Batch Transcribe Multiple Files
SELECT file, whisper_transcribe(file, 'tiny.en') as transcript
FROM glob('audio/*.wav');
Search Within Transcriptions
SELECT * FROM whisper_transcribe_segments('meeting.wav', 'base.en')
WHERE text ILIKE '%action item%';
Generate Subtitles (SRT Format)
SELECT
segment_id + 1 as id,
printf('%02d:%02d:%02d,%03d',
(start_time/3600)::int, ((start_time%3600)/60)::int,
(start_time%60)::int, ((start_time - start_time::int) * 1000)::int
) || ' --> ' ||
printf('%02d:%02d:%02d,%03d',
(end_time/3600)::int, ((end_time%3600)/60)::int,
(end_time%60)::int, ((end_time - end_time::int) * 1000)::int
) as timestamp,
trim(text) as text
FROM whisper_transcribe_segments('video.mp4', 'small.en');
Recording (requires microphone)
Setup Audio Device
Before using microphone recording or voice query features:
-- List all available audio input devices
SELECT * FROM whisper_list_devices();
-- Set the device ID (use a device_id from the list above)
SET whisper_device_id = 0;
-- Verify your microphone is working
SELECT whisper_mic_level(3);
Record and Transcribe
-- Record for 5 seconds
SELECT whisper_record(5, 'tiny.en');
-- Record until silence (max 30 seconds)
SELECT whisper_record_auto(30);
-- Record and translate to English
SELECT whisper_record_translate(5, 'small');
Voice-to-SQL (Experimental)
Speak natural language questions about your data and receive SQL query results.
Requires text-to-sql-proxy running locally.
-- Create test data
CREATE TABLE customers (id INT, name VARCHAR, revenue DECIMAL);
INSERT INTO customers VALUES (1, 'Acme', 100000), (2, 'Beta', 50000);
-- Get SQL from voice (doesn't execute)
SELECT whisper_voice_to_sql();
-- Execute voice query directly
FROM whisper_voice_query();
-- Include generated SQL in results
FROM whisper_voice_query_with_sql();
Available Models
| Model | Size | Description |
|---|---|---|
| tiny/tiny.en | ~75MB | Fastest |
| base/base.en | ~142MB | Fast |
| small/small.en | ~466MB | Good balance |
| medium/medium.en | ~1.5GB | High quality |
| large-v1/v2/v3 | ~2.9GB | Best quality |
| large-v3-turbo | ~1.6GB | Fast + accurate |
Models with .en suffix are optimized for English.
Supported Audio Formats
The extension uses FFmpeg for audio decoding: WAV, MP3, FLAC, OGG/Vorbis, AAC/M4A, and many more. Audio is automatically converted to 16kHz mono as required by Whisper.
Function Reference
Transcription Functions
-
whisper_transcribe(audio, [model])- Transcribes audio and returns the full text -
whisper_translate(audio, [model])- Translates audio from any language to English -
whisper_transcribe_segments(audio, [model], [language], [translate])- Returns table of segments with timestamps
Recording Functions
-
whisper_list_devices()- Lists available audio input devices -
whisper_record(duration_seconds, [model], [device_id])- Records and transcribes -
whisper_record_auto(max_seconds, [silence_seconds], [model], [threshold], [device_id])- Records until silence -
whisper_record_translate(duration_seconds, [model], [device_id])- Records and translates to English -
whisper_mic_level(duration_seconds, [device_id])- Check microphone amplitude levels
Voice-to-SQL Functions
-
whisper_voice_to_sql([model], [device_id])- Records voice and returns generated SQL -
whisper_voice_query([model], [device_id])- Records voice, generates SQL, executes it -
whisper_voice_query_with_sql([model], [device_id])- Same as above with SQL columns
Model Management Functions
-
whisper_list_models()- Lists all available models and download status -
whisper_download_model(model_name)- Downloads a model into the model directory
Utility Functions
-
whisper_version()- Returns extension and whisper.cpp version info -
whisper_check_audio(file_path)- Validates that an audio file can be read -
whisper_audio_info(file_path)- Returns audio file metadata -
whisper_get_config()- Returns current whisper configuration settings
Configuration
Configure settings using standard SET statements:
-- Model settings
SET whisper_model = 'small.en';
SET whisper_model_path = '/custom/path/models';
SET whisper_language = 'en';
SET whisper_threads = 4;
-- Recording settings
SET whisper_device_id = 0;
SET whisper_max_duration = 30;
SET whisper_silence_duration = 2;
SET whisper_silence_threshold = 0.005;
-- Voice query settings
SET whisper_text_to_sql_url = 'http://localhost:8080/generate-sql';
SET whisper_text_to_sql_timeout = 60;
SET whisper_voice_query_show_sql = true;
-- View all whisper settings
SELECT * FROM duckdb_settings() WHERE name LIKE 'whisper_%';
See the GitHub repository for full documentation.
Added Functions
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| whisper_transcribe | scalar | Transcribes speech from an audio file path (VARCHAR) or from audio bytes (BLOB) and returns the full text. The optional model overrides the whisper_model setting. | NULL | [SELECT whisper_transcribe('audio.wav', 'tiny.en');] |
| whisper_translate | scalar | Translates speech in any supported language from an audio file path (VARCHAR) or from audio bytes (BLOB) into English text. Requires a multilingual (non-.en) model. | NULL | [SELECT whisper_translate('german_speech.mp3', 'small');] |
| whisper_transcribe_segments | table | Transcribes an audio file path (VARCHAR) or audio bytes (BLOB) into timestamped segments: segment_id, start_time, end_time, text, confidence and language. Optional arguments override the model and language settings; translate = true translates the speech to English. | NULL | [SELECT start_time, end_time, text FROM whisper_transcribe_segments('audio.wav', 'tiny.en');] |
| whisper_list_models | table | Lists all supported Whisper models with their download status: name, is_downloaded, file_size, file_path and description. | NULL | [SELECT * FROM whisper_list_models() WHERE is_downloaded;] |
| whisper_download_model | scalar | Downloads a Whisper model into the whisper_model_path directory and returns a status message. Does nothing if the model is already downloaded. | NULL | [SELECT whisper_download_model('tiny.en');] |
| whisper_model_info | table | Returns one row describing the currently configured model: current_model, model_path, is_downloaded, file_size, language and threads. | NULL | [SELECT * FROM whisper_model_info();] |
| whisper_list_devices | table | Lists the available audio input devices (device_id, device_name). Use a device_id with the recording functions or the whisper_device_id setting. | NULL | [SELECT * FROM whisper_list_devices();] |
| whisper_record | scalar | Records audio from the microphone for a fixed number of seconds and returns the transcribed text. Optional arguments override the model and input device. | NULL | [SELECT whisper_record(5, 'tiny.en');] |
| whisper_record_auto | scalar | Records audio from the microphone until silence_seconds of silence are detected or max_seconds is reached, then returns the transcribed text. Omitted arguments fall back to the whisper_silence_duration, whisper_model and whisper_silence_threshold settings. | NULL | [SELECT whisper_record_auto(30, 2.0, 'tiny.en');] |
| whisper_record_translate | scalar | Records audio from the microphone for a fixed number of seconds and returns the speech translated to English. Requires a multilingual (non-.en) model. | NULL | [SELECT whisper_record_translate(5, 'small');] |
| whisper_mic_level | scalar | Samples the microphone for a few seconds and reports the peak and RMS amplitude with a suggested whisper_silence_threshold value. | NULL | [SELECT whisper_mic_level(3);] |
| whisper_voice_to_sql | scalar | Records a spoken question from the microphone and returns the SQL generated by the text-to-SQL proxy at whisper_text_to_sql_url, without executing it. | Requires text-to-sql-proxy | [SELECT whisper_voice_to_sql();] |
| whisper_voice_query | table | Records a spoken question from the microphone, converts it to SQL via the text-to-SQL proxy at whisper_text_to_sql_url, executes the query and returns its result. | Requires text-to-sql-proxy | [SELECT * FROM whisper_voice_query();] |
| whisper_voice_query_with_sql | table | Like whisper_voice_query, but prepends _generated_sql and _transcription columns to the query result. | Requires text-to-sql-proxy | [SELECT * FROM whisper_voice_query_with_sql();] |
| whisper_version | scalar | Returns the whisper extension version and the bundled whisper.cpp version. | NULL | [SELECT whisper_version();] |
| whisper_check_audio | scalar | Checks whether an audio file can be opened and decoded by FFmpeg. Returns 'OK' on success, or 'Error: |
NULL | [SELECT whisper_check_audio('audio.wav');] |
| whisper_audio_info | table | Returns one row of audio file metadata: file_path, duration_seconds, sample_rate, channels, format and file_size. | NULL | [SELECT * FROM whisper_audio_info('audio.wav');] |
| whisper_get_config | scalar | Returns all effective whisper settings as a comma-separated key=value string. | NULL | [SELECT whisper_get_config();] |
| whisper_get_device_id | scalar | Returns the current whisper_device_id setting (-1 means the default device). | NULL | [SELECT whisper_get_device_id();] |
| whisper_get_max_duration | scalar | Returns the current whisper_max_duration setting in seconds. | NULL | [SELECT whisper_get_max_duration();] |
| whisper_get_silence_duration | scalar | Returns the current whisper_silence_duration setting in seconds. | NULL | [SELECT whisper_get_silence_duration();] |
| whisper_get_silence_threshold | scalar | Returns the current whisper_silence_threshold setting (RMS amplitude). | NULL | [SELECT whisper_get_silence_threshold();] |
| whisper_get_text_to_sql_url | scalar | Returns the current whisper_text_to_sql_url setting (the text-to-SQL proxy URL). | NULL | [SELECT whisper_get_text_to_sql_url();] |
| whisper_get_text_to_sql_timeout | scalar | Returns the current whisper_text_to_sql_timeout setting in seconds. | NULL | [SELECT whisper_get_text_to_sql_timeout();] |
| whisper_get_voice_query_show_sql | scalar | Returns the current whisper_voice_query_show_sql setting. | NULL | [SELECT whisper_get_voice_query_show_sql();] |
Overloaded Functions
This extension does not add any function overloads.
Added Types
This extension does not add any types.
Added Settings
| name | description | input_type | scope | aliases | typed_value |
|---|---|---|---|---|---|
| temp_directory | Set the directory to which temporary files are written. | VARCHAR | GLOBAL | [] | post.db.tmp |
| whisper_device_id | Audio input device ID (-1 = system default) | INTEGER | GLOBAL | [] | -1 |
| whisper_ffmpeg_logging | Enable FFmpeg log output (warnings, info messages) | BOOLEAN | GLOBAL | [] | false |
| whisper_language | Target language code or 'auto' for detection | VARCHAR | GLOBAL | [] | auto |
| whisper_max_duration | Maximum recording duration in seconds | DOUBLE | GLOBAL | [] | 15.0 |
| whisper_model | Whisper model name (e.g., tiny.en, base.en, small, medium, large-v3) | VARCHAR | GLOBAL | [] | base.en |
| whisper_model_path | Path to store Whisper models | VARCHAR | GLOBAL | [] | /home/runner/.duckdb/whisper/models |
| whisper_silence_duration | Silence duration to stop recording (seconds) | DOUBLE | GLOBAL | [] | 1.0 |
| whisper_silence_threshold | Amplitude threshold for silence detection | DOUBLE | GLOBAL | [] | 0.001 |
| whisper_text_to_sql_timeout | Timeout for text-to-sql proxy requests (seconds) | INTEGER | GLOBAL | [] | 15 |
| whisper_text_to_sql_url | URL of the text-to-sql proxy service | VARCHAR | GLOBAL | [] | http://localhost:4000/generate-sql |
| whisper_threads | Number of processing threads (0 = auto-detect) | INTEGER | GLOBAL | [] | 0 |
| whisper_use_gpu | Use GPU acceleration if available (Metal on macOS) | BOOLEAN | GLOBAL | [] | true |
| whisper_verbose | Show status messages during recording and voice query operations | BOOLEAN | GLOBAL | [] | false |
| whisper_voice_query_show_sql | Show generated SQL in voice query output | BOOLEAN | GLOBAL | [] | false |
| whisper_voice_query_timeout | Timeout for entire voice query operation (seconds) | INTEGER | GLOBAL | [] | 30 |