Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,18 @@ jobs:
- name: Install Python dependencies (Ubuntu, <=3.12)
if: matrix.os == 'ubuntu-latest' && matrix.python-version != '3.13'
run: |
python -m pip install .[dev,audio,pocketsphinx,google-cloud,whisper-local,faster-whisper,openai,groq]
python -m pip install .[dev,audio,pocketsphinx,google-cloud,whisper-local,faster-whisper,openai,groq,vosk]
- name: Install Python dependencies (Ubuntu, 3.13)
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
run: |
python -m pip install standard-aifc setuptools
python -m pip install --no-build-isolation .[dev,audio,pocketsphinx,google-cloud,openai,groq]
python -m pip install --no-build-isolation .[dev,audio,pocketsphinx,google-cloud,openai,groq,vosk]
- name: Install Python dependencies (Windows)
if: matrix.os == 'windows-latest'
run: |
python -m pip install .[dev,whisper-local,faster-whisper,google-cloud,openai,groq]
python -m pip install .[dev,whisper-local,faster-whisper,google-cloud,openai,groq,vosk]
- name: Set up vosk model
run: pipx run setup_vosk.py
Copy link

Copilot AI May 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] If setup_vosk.py is a local script rather than an installed package, consider using 'python setup_vosk.py' to ensure reliable execution within the workflow.

Suggested change
run: pipx run setup_vosk.py
run: python setup_vosk.py

Copilot uses AI. Check for mistakes.
- name: Test with unittest
run: |
pytest --doctest-modules -v speech_recognition/recognizers/ tests/
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ groq =
httpx < 0.28
assemblyai =
requests
vosk =
vosk
51 changes: 51 additions & 0 deletions setup_vosk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# /// script
# requires-python = ">=3.9"
# dependencies = [
# "requests",
# "tqdm",
# ]
# ///
import os
import shutil
import tempfile
import zipfile

import requests
from tqdm import tqdm


def setup_vosk_model(model_url: str, model_dir: str) -> None:
model_filename = os.path.basename(model_url)
model_name = os.path.splitext(model_filename)[0]

print(f"Downloading model {model_filename} ...")
response = requests.get(model_url, stream=True)
response.raise_for_status()
total_size = int(response.headers.get("content-length", 0))

with tempfile.TemporaryDirectory() as temp_dir:
download_path = os.path.join(temp_dir, model_filename)
with open(download_path, "wb") as f:
with tqdm(total=total_size, unit="B", unit_scale=True) as pbar:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
pbar.update(len(chunk))

print("Unzip model...")
with zipfile.ZipFile(download_path, "r") as zip_ref:
zip_ref.extractall(temp_dir)

extracted_dir = os.path.join(temp_dir, model_name)
if os.path.exists(model_dir):
shutil.rmtree(model_dir)
shutil.copytree(extracted_dir, model_dir)

print(f"Setup complete! Model is placed in the directory: {model_dir}")


if __name__ == "__main__":
model_url = (
"https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip"
)
setup_vosk_model(model_url, "model")
18 changes: 18 additions & 0 deletions tests/recognizers/test_vosk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pathlib import Path

from speech_recognition import AudioData, Recognizer


def test_recognize_vosk():
audio_file = str(Path(__file__).parent.parent / "english.wav")
audio_data = AudioData.from_file(audio_file)
sut = Recognizer()

actual = sut.recognize_vosk(audio_data)

expected = """\
{
"text" : "one two three"
}\
"""
assert actual == expected