| aligner | ||
| audio | ||
| bot | ||
| ingestor | ||
| old | ||
| storage | ||
| .env.example | ||
| .gitignore | ||
| config.py | ||
| docker-compose.yml | ||
| folders.txt | ||
| main.py | ||
| README.md | ||
| requirements.txt | ||
| setup_directus.py | ||
Call-to-Text
Транскрипция звонков из Novofon DATA API с сохранением в Directus.
Архитектура
Novofon DATA API ──► call-to-text ──► Directus (Postgres)
│ │
│ ┌──────┴──────┐
│ calls calls_* contacts
│
┌────┴────┐
│ FFmpeg │ конвертация аудио → WAV 16 кГц
└────┬────┘
│
┌────┴──────────┐
│ faster-whisper │ распознавание речи (модель turbo / large-v3)
└────┬──────────┘
│
┌────┴──────┐
│ aligner │ маркировка спикеров: caller / callee
└───────────┘
- Звонки получаются через JSON-RPC API (
get.calls_report) - Аудио скачивается по прямой ссылке
- Стерео-файлы разделяются на каналы: левый = callee, правый = caller
- Каждый канал транскрибируется через faster-whisper на CUDA
- Результат сохраняется в Directus (коллекции
calls/calls_*)
Требования
- Python 3.10+
- FFmpeg (в PATH) — для конвертации аудио
- NVIDIA GPU с CUDA (опционально, для ускорения)
- Docker + Docker Compose (для Directus + Postgres)
Установка и запуск
1. Клонировать
git clone https://git.itoservice.ru/dosnav/call-to-text.git
cd call-to-text
2. Настроить окружение
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Linux
pip install -r requirements.txt
3. Поднять Directus
docker compose up -d
Создадутся контейнеры:
postgres(порт не наружу)directus(порт8055)
После первого запуска инициализировать коллекции:
python setup_directus.py
Создаст коллекции: calls, calls_74951284933, contacts — с полной схемой полей.
4. Настроить .env
Скопировать .env.example → .env и заполнить:
# Novofon DATA API
NOVOFON_ACCESS_TOKEN=ваш_токен
NOVOFON_DATE_FROM=2024-01-01
# Directus
DIRECTUS_URL=http://localhost:8055
DIRECTUS_TOKEN=call-to-text-admin-token
# Whisper
WHISPER_MODEL_SIZE=turbo # tiny/base/small/medium/large-v3/turbo
WHISPER_DEVICE=cuda # cpu / cuda
WHISPER_COMPUTE_TYPE=float16 # int8 / float16
5. Настроить Novofon
IP-адрес сервера, откуда будет запускаться скрипт, должен быть внесён в белый список в админ-панели Novofon:
Настройки → Правила и настройки безопасности → API
Токен доступа (permanent API key) создаётся там же.
6. Загрузить звонки
python -m main process --limit 50
Первая загрузка — модель Whisper скачается автоматически (HuggingFace Hub).
CLI-команды
process
Пакетная загрузка и транскрипция звонков из Novofon API.
python -m main process --limit 100 --date-from "2024-06-01"
Опции:
--limit N— максимальное количество звонков за запуск--date-from YYYY-MM-DD— начальная дата (по умолчанию из .env)
process-file
Транскрипция одного аудиофайла (для тестов).
python -m main process-file --file "путь/к/файлу.wav" --caller "79161234567" --callee "74951284933"
export
Выгрузка всех звонков из Directus в JSON.
python -m main export --output calls.json
daemon
Фоновый режим — проверяет новые звонки каждые 5 минут.
python -m main daemon --max 10 --hours-back 6
Модели Whisper
| Модель | Размер | Качество | Скорость |
|---|---|---|---|
tiny |
39 MB | низкое | 🚀 |
base |
74 MB | среднее | 🚀 |
small |
244 MB | хорошее | ⚡ |
medium |
769 MB | очень хорошее | ⚡ |
large-v3 |
1.5 GB | лучшее | 🐢 |
turbo |
809 MB | как large-v3 | 🚀 (в 5x быстрее) |
Рекомендуется turbo — качество large-v3 при заметно меньшем времени транскрипции.
Переключение — одной строкой в .env:
WHISPER_MODEL_SIZE=turbo
Модель кешируется после первой загрузки в ~/.cache/huggingface/hub/.
Структура проекта
├── main.py # CLI-точка входа
├── config.py # Настройки из .env
├── setup_directus.py # Инициализация Directus
├── requirements.txt # Зависимости
├── docker-compose.yml # Directus + Postgres
├── .env # Локальные настройки (в .gitignore)
├── .env.example # Шаблон настроек
│
├── ingestor/
│ ├── novofon_api.py # Клиент Novofon DATA API
│ └── downloader.py # Скачивание аудио по URL
│
├── audio/
│ ├── stt.py # Распознавание (faster-whisper)
│ ├── preprocessor.py # FFmpeg конвертация, разделение каналов
│ └── diarization.py # Диаризация (pyannote)
│
├── aligner/
│ └── aligner.py # Маркировка спикеров
│
├── storage/
│ ├── directus.py # HTTP-клиент Directus
│ ├── contacts.py # Поиск контактов по номеру
│ └── exporter.py # Экспорт в JSON
│
├── old/ # Архив: email-парсинг (не используется)
└── temp/ # Временные WAV-файлы (в .gitignore)
Управление Directus
Админка: http://localhost:8055/admin
Данные по умолчанию:
- Email:
admin@example.com - Пароль:
admin-password-123
Остановить:
docker compose down
Удалить данные:
docker compose down -v
Коллекции Directus
calls
Основная коллекция звонков (не на номер 74951284933).
calls_74951284933
Звонки, где одна из сторон — 74951284933.
contacts
Телефонная книга. Поля: phone_number, name, company, notes.
При транскрипции номера автоматически резолвятся в имена из contacts.
Принцип работы
get.calls_reportполучает звонки чанками по 90 дней (максимум API)- Скачивается аудио по
full_record_file_linkилиcall_records - FFmpeg конвертирует в WAV: 16 кГц, pcm_s16le, моно или стерео
- Если каналы разные (реальное стерео) — левый = callee, правый = caller
- Каждый канал транскрибируется faster-whisper на CUDA (float16)
- Сегменты выравниваются по времени и маркируются спикером
- Результат сохраняется в Directus
- Звонки с
talk_duration=0и без аудио — пропускаются