Озвучка и расшифровка через API

Запросы в форме OpenAI для превращения текста в mp3 и записи в текст. Ответ приходит в том же запросе, а при долгой работе вместо него придёт задача.

Обновлено: 4 мин чтения

Озвучьте текст

Озвучку делают модели с типом speech. Запрос повторяет OpenAI Text-to-Speech, в ответ приходит сам звук.

curl https://epicai.ru/v1/audio/speech \
  -H "Authorization: Bearer $EPICAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "elevenlabs/eleven-v4",
    "input": "Добро пожаловать в epicai.",
    "voice": "sarah"
  }' \
  --output speech.mp3
import os
import requests

reply = requests.post(
    "https://epicai.ru/v1/audio/speech",
    headers={"Authorization": "Bearer " + os.environ["EPICAI_API_KEY"]},
    json={"model": "elevenlabs/eleven-v4", "input": "Добро пожаловать в epicai.", "voice": "sarah"},
)
if reply.status_code == 202:
    print("Не успело, задача", reply.json()["id"])
else:
    reply.raise_for_status()
    with open("speech.mp3", "wb") as out:
        out.write(reply.content)
    print("Списано TOK:", reply.headers["x-epic-cost-tok"])

Ответ 200 несёт audio/mpeg, формат только mp3. Сумма лежит в заголовке x-epic-cost-tok, номер задачи в x-epic-task.

Поля запроса

  • model и текст. Текст передаётся в input или в prompt, оба сразу дают 400 invalid_parameter. Предельная длина текста указана в prompt_max модели, больше даёт 400 prompt_too_long.
  • voice — голос из схемы модели. Если не указан, берётся голос по умолчанию. Значение вне списка даёт 400 invalid_parameter с перечнем допустимых.
  • speed — скорость речи. Есть не у всех моделей, значения берутся из схемы, обычная скорость равна 1. Модель без этого параметра отвечает 400 invalid_parameter.
  • response_format принимает только mp3. Поля instructions и stream_format не поддерживаются, манеру речи задавайте самим текстом.
  • webhook_url и заголовок Idempotency-Key принимаются так же, как в POST /v1/tasks, см. статью Задачи в API.

Голос и скорость можно писать в теле или внутри parameters. Любое другое поле верхнего уровня считается параметром модели, а неизвестное вызывает 400 invalid_parameter.

Если озвучка не успела

Запрос держится открытым до 100 секунд. Если звука за это время нет, придёт 202 с объектом задачи, заголовками Location и Retry-After: 5. Работа не прерывается, готовый mp3 лежит в output задачи, его отдаёт GET /v1/tasks/{id}.

Расшифруйте запись

Расшифровку делают модели с типом transcription. Запрос повторяет OpenAI Speech-to-Text, запись передаётся файлом.

curl https://epicai.ru/v1/audio/transcriptions \
  -H "Authorization: Bearer $EPICAI_API_KEY" \
  -F model=gpt-transcribe \
  -F language=ru \
  -F file=@record.mp3
import os
import requests

with open("record.mp3", "rb") as record:
    reply = requests.post(
        "https://epicai.ru/v1/audio/transcriptions",
        headers={"Authorization": "Bearer " + os.environ["EPICAI_API_KEY"]},
        data={"model": "gpt-transcribe", "language": "ru"},
        files={"file": record},
    )
reply.raise_for_status()
body = reply.json()
print(body["id"] if body.get("object") == "task" else body["text"])
{
  "text": "Добрый день, начинаем встречу.",
  "epicai": {
    "task": "task_5e0b0c2a7d1f4e3a9b8c7d6e",
    "price": {"tokens": 2400, "charged": 2400},
    "expires_at": 1793719429
  }
}

Вместо файла в форме можно прислать JSON, где file — ссылка http(s) или строка data:audio/mpeg;base64,…. Ссылку скачивает сервер, поэтому она должна вести на публичный сервер, порт 80 или 443, без логина и пароля. Запрос держится открытым до 280 секунд, потом отвечает 202 с задачей.

Запись и язык

Форматы и предельный размер записи у каждой модели свои, их показывает поле input_files.audio в GET /v1/models/{id}. Длина записи не больше 3 часов. Запись уходит вендору целиком, одним запросом, без нарезки, поэтому длинную запись ограничивает именно предел размера. Если файл больше, придёт 413 или 400 invalid_input.

Язык задаёт language, это код из схемы модели или auto для автоопределения. Без этого поля берётся значение по умолчанию модели, у одних это русский, у других автоопределение. Для записи на другом языке укажите его явно. Поля prompt, temperature, timestamp_granularities и chunking_strategy принимаются для совместимости с клиентами OpenAI и ни на что не влияют.

Формат ответа

response_formatЧто приходит
jsonОбъект с полями text и epicai. Значение по умолчанию
textЧистый текст, text/plain
verbose_jsonК json добавляются task, language, duration в секундах, а также segments и words с полями start и end, если модель их отдаёт. Где модель различает говорящих, в сегментах есть speaker
srt, vttСубтитры по сегментам. Модель без таймкодов отвечает 400 unsupported_parameter

Запустите то же задачей

Оба адреса можно заменить POST /v1/tasks. Тогда ответ всегда задача, результат лежит в output. Озвучка передаёт текст в prompt и голос в parameters, расшифровка передаёт запись в audios и prompt не использует.

{
  "model": "gpt-transcribe",
  "audios": ["https://example.com/record.mp3"],
  "parameters": {"language": "auto"}
}

У расшифровки в output лежит файл txt и, если модель отдаёт таймкоды, файл json с полями text, language, duration, segments и words.

Цена

Озвучка считается по длине текста. Единица, знаки или байты UTF-8, указана в pricing.examples_for модели. Расшифровка считается по секундам записи, округлённым вверх, длину файла измеряет сервер. Для POST /v1/quote текст передаётся в prompt, а длина записи числом секунд в audios.

{"model": "gpt-transcribe", "audios": [90]}

Цена фиксируется при создании. Если озвучка или расшифровка завершились ошибкой, токены не списываются, коды разобраны в статье Ошибки API.

Не нашли ответ?

Посмотрите частые вопросы или напишите в поддержку.

Войти или создать аккаунт

20 000 токенов в подарок новым пользователям. Без карты и без VPN.

или через сервис

Продолжая, вы получаете сервисные письма.

Для защиты от роботов используется Yandex SmartCaptcha. Условия обработки данных.