---
title: "Whisper Integration with Pixeltable: Local Speech-to-Text Columns"
description: "Transcribe Pixeltable Audio columns with OpenAI Whisper running locally. No API key. Split long files, then cache text per segment."
tool: "Whisper"
keywords:
  - Whisper Pixeltable integration
  - openai-whisper computed column
  - local speech to text Python
  - audio_splitter Whisper
  - Whisper transcription Pixeltable
url: "https://www.pixeltable.com/integrations/whisper"
---

# Whisper Integration with Pixeltable: Local Speech-to-Text Columns

Transcribe Pixeltable Audio columns with OpenAI Whisper running locally. No API key. Split long files, then cache text per segment.

## The Problem

Whisper runs locally and needs no API key. Production still needs the audio on a row, a split for long files, and a place to keep the transcript with timestamps. A script that loads each file, calls whisper.transcribe, and writes a .txt next to it will re-run completed files unless you add a cache. Hosted openai.transcriptions is a different UDF and a different bill. Pixeltable already has pxt.Audio. The integration is pixeltable.functions.whisper.transcribe plus audio_splitter when the file is longer than a single Whisper window.

## The Solution

pip install pixeltable openai-whisper. Assign transcribe(audio, model=base.en) on the class, then text = result.text. Models ending in .en are English-only and faster; drop .en for multilingual. For long files, declare a view with audio_splitter(duration=30.0) and transcribe audio_segment on that view. Inserting a video extracts the audio track. There is no OpenAI API key on this path. ffmpeg must be on PATH. The documented how-to for searchable transcripts also embeds the text; this page is the Whisper UDF itself. Hosted Whisper-1 is pixeltable.functions.openai.transcriptions, a different import.

## Implementation

### Store files as an Audio column

A path string is not enough. Splitting and Whisper need a typed column.

```python
import pixeltable as pxt
from pixeltable.functions.audio import audio_splitter
from pixeltable.functions.whisper import transcribe

TableModel = pxt.model_base()

class Recordings(TableModel, name='recordings'):
    title: pxt.String
    audio: pxt.Audio

# pxt schema update app.py whisper_lib -f
```

Insert local paths, https://, or s3:// URIs. A video file is valid: Pixeltable extracts the audio track. openai-whisper and ffmpeg are required.


### Split long files into segments

audio_splitter emits one row per slice with segment_start, segment_end, and audio_segment.

```python
class Segments(
    TableModel,
    name='segments',
    base=Recordings,
    iterator=audio_splitter(audio=Recordings.audio, duration=30.0),
):
    pass
```

Pass exactly one of duration or max_size. duration=30.0 is the documented starting slice for local Whisper. overlap and min_segment_duration are optional. Byte-budget splits use max_size (for example 24 * 1024 * 1024). Short files can skip the view and transcribe Recordings.audio directly.


### Transcribe each segment locally

whisper.transcribe writes a WhisperTranscription dict. .text is the string.

```python
class Segments(
    TableModel,
    name='segments',
    base=Recordings,
    iterator=audio_splitter(audio=Recordings.audio, duration=30.0),
):
    result = transcribe(audio_segment, model='base.en')
    text = result.text

# pxt schema update app.py whisper_lib -f
```

model options include tiny.en, base.en, small.en, medium.en, and large. The English-only .en checkpoints are faster. The return also has segments, language, and word-level fields when the model provides them. A new file transcribes only that file.


### Insert a file and read the text

Insert runs the splitter and Whisper for that recording. Select timestamps plus text.

```python
recordings = pxt.get_table('whisper_lib.recordings')
recordings.insert([{
    'title': 'demo',
    'audio': 'https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/audio-transcription-demo/Lex-Fridman-Podcast-430-Excerpt-0.mp4',
}])
segments = pxt.get_table('whisper_lib.segments')
segments.select(segments.segment_start, segments.segment_end, segments.text).collect()
```

The URL is the sample used in the Whisper cookbook. For searchable transcripts, add a Sentence Transformer EmbeddingIndex on text as in How do I transcribe audio uploads and make them searchable. Word-level speakers are WhisperX, a different cookbook.


## Local Whisper versus hosted transcriptions

|  | whisper.transcribe | openai.transcriptions |
| --- | --- | --- |
| Import | pixeltable.functions.whisper | pixeltable.functions.openai |
| Runs | Local openai-whisper | OpenAI Audio API |
| Key | None | OPENAI_API_KEY |
| Choose it when | The machine can hold the checkpoint | You want hosted Whisper-1 |

## Benefits

- No OpenAI API key: openai-whisper runs on the machine that holds the table
- Per-row cache: completed segments do not transcribe again
- audio_splitter keeps timestamps next to the text
- Video inserts extract audio automatically
- Hosted Whisper-1 stays a separate openai.transcriptions column if you want it

## Use Cases

- Podcast and meeting transcripts stored with the file
- English-only bulk transcription with base.en
- Multilingual audio with a non-.en checkpoint
- Preparing text for an embedding index on the same view
- Local transcription in an environment that cannot call a hosted ASR API

## Performance


| Metric | Value | Description |

| --- | --- | --- |

| API key | None | openai-whisper runs locally; openai.transcriptions is a different, hosted UDF |

| Long files | audio_splitter | One of duration or max_size; 30-second slices are the documented default |

| Recompute | New files only | A new insert transcribes that recording; completed segments stay cached |

## Requirements

- Python 3.11+
- pip install -U 'pixeltable[serve]' openai-whisper
- ffmpeg on PATH
- RAM and disk for the chosen Whisper checkpoint

## Resources

- [Transcribe audio files with Whisper](https://docs.pixeltable.com/howto/cookbooks/audio/audio-transcribe) - audio_splitter, transcribe(), and video-as-audio
- [Whisper functions SDK](https://docs.pixeltable.com/sdk/latest/whisper) - transcribe() and WhisperTranscription
- [Whisper transcription in Pixeltable](https://www.pixeltable.com/blog/whisper-transcription-pixeltable) - Product write-up of the local ASR path
- [How do I transcribe audio and search it?](https://www.pixeltable.com/learn/how-to/transcribe-audio-and-search-it) - Splitter, Whisper, embedding index, and HTTP upload