Skip to content

Транскрипция аудио: Ограничения и обработка больших пакетов /v1/audio/transcriptions

Вы можете использовать конечную точку транскрипции аудио POST /v1/audio/transcriptions для преобразования аудиофайлов в текст. Она выглядит как API OpenAI Whisper, но в локальном шлюзе выполняет проверку формата, ограничение размера файла и отправляет аудио как inlineData вышестоящему запросу Gemini.

Чему вы научитесь

  • Использовать curl / OpenAI SDK для вызова POST /v1/audio/transcriptions для преобразования аудио в {"text":"..."}
  • Разобраться в поддерживаемых 6 форматах аудио и реальной форме ошибки ограничения 15MB
  • Понимать значения по умолчанию и способ передачи model / prompt (не гадать о правилах вышестоящего уровня)
  • Найти аудиозапросы в Proxy Monitor и понять источник [Binary Request Data]

Текущие проблемы

Вы хотите преобразовать аудиозаписи встреч, подкастов или телефонных звонков поддержки в текст, но часто застреваете на этих моментах:

  • Разные инструменты по-разному обрабатывают аудиоформаты/формы интерфейса, скрипты и SDK сложно повторно использовать
  • При неудачной загрузке видите только «плохой запрос/ошибка шлюза», не знаете, это формат неправильный или файл слишком большой
  • Вы хотите поместить транскрипцию в «локальный шлюз» Antigravity Tools для единообразного планирования и мониторинга, но не уверены, насколько она совместима

🎒 Подготовка

Предварительные условия

Что такое конечная точка транскрипции аудио (/v1/audio/transcriptions)?

Конечная точка транскрипции аудио — это маршрут, совместимый с OpenAI Whisper, предоставляемый Antigravity Tools. Клиент загружает аудиофайл с помощью multipart/form-data, сервер проверяет расширение и размер, затем преобразует аудио в Base64 inlineData, вызывает вышестоящий generateContent, наконец возвращает только поле text.

Обзор конечных точек и ограничений

ЭлементВыводДоказательство кода
Входной маршрутPOST /v1/audio/transcriptionsРегистрация маршрута в src-tauri/src/proxy/server.rs в handlers::audio::handle_audio_transcription
Поддерживаемые форматыРаспознаются по расширению файла: mp3/wav/m4a/ogg/flac/aiff(aif)src-tauri/src/proxy/audio/mod.rs detect_mime_type()
Размер файлаЖёсткое ограничение 15MB (превышение возвращает 413 + текстовая информация об ошибке)src-tauri/src/proxy/audio/mod.rs exceeds_size_limit(); src-tauri/src/proxy/handlers/audio.rs
Общий limit body проксиНа уровне Axum разрешено до 100MBsrc-tauri/src/proxy/server.rs DefaultBodyLimit::max(100 * 1024 * 1024)
Параметры по умолчаниюmodel="gemini-2.0-flash-exp"; prompt="Generate a transcript of speech."src-tauri/src/proxy/handlers/audio.rs

Пошаговое руководство

Шаг 1: Подтвердите, что шлюз работает (/healthz)

Зачем Сначала исключите проблемы типа неверный порт/сервис не запущен.

bash
curl -s http://127.0.0.1:8045/healthz
powershell
curl http://127.0.0.1:8045/healthz

Что вы должны увидеть: Примерно {"status":"ok"} JSON.

Шаг 2: Подготовьте аудиофайл не более 15MB

Зачем Сервер выполнит проверку 15MB в обработчике, превышение напрямую вернёт 413.

bash
ls -lh audio.mp3
powershell
Get-Item audio.mp3 | Select-Object Length

Что вы должны увидеть: Размер файла не превышает 15MB.

Шаг 3: Вызов /v1/audio/transcriptions с помощью curl

Зачем curl самый прямой, удобен для вас сначала проверить форму протокола и информацию об ошибке.

bash
curl -sS -X POST http://127.0.0.1:8045/v1/audio/transcriptions \
  -F "file=@audio.mp3" \
  -F "model=gemini-2.0-flash-exp" \
  -F "prompt=Generate a transcript of speech."

Что вы должны увидеть: Возвращается JSON, только одно поле text.

json
{
  "text": "..."
}

Шаг 4: Вызов с помощью OpenAI Python SDK

python
from openai import OpenAI

client = OpenAI(
  base_url="http://127.0.0.1:8045/v1",
  api_key="your-proxy-api-key"  # Если включена аутентификация
)

audio_file = open("audio.mp3", "rb")
transcript = client.audio.transcriptions.create(
  model="gemini-2.0-flash-exp",
  file=audio_file
)

print(transcript.text)

Что вы должны увидеть: print(transcript.text) выводит фрагмент текста транскрипции.

Поддерживаемые аудиоформаты

Antigravity Tools определяет тип MIME по расширению файла (а не сниффинг содержимого файла).

ФорматТип MIMEРасширение
MP3audio/mp3.mp3
WAVaudio/wav.wav
AAC (M4A)audio/aac.m4a
OGGaudio/ogg.ogg
FLACaudio/flac.flac
AIFFaudio/aiff.aiff, .aif

Неподдерживаемые форматы

Если расширение не в таблице, вернётся 400, тело ответа — это текст, например: 不支持的音频格式: txt.

Контрольные точки ✅

  • [ ] Тело возврата — это {"text":"..."} (нет дополнительных структур segments, verbose_json и т.д.)
  • [ ] В заголовке ответа содержится X-Account-Email (помечает фактически использованный аккаунт)
  • [ ] На странице «Monitor» видна эта запись запроса

Обработка больших пакетов: почему вы видите 100MB, но всё равно застреваете на 15MB

Сервер на уровне Axum поднял limit request body до 100MB (чтобы некоторые большие запросы не были напрямую отклонены фреймворком), но обработчик транскрипции аудио дополнительно выполнит проверку 15MB.

То есть:

  • 15MB < файл <= 100MB: запрос может войти в обработчик, но вернёт 413 + текстовая информация об ошибке
  • файл > 100MB: запрос может напрямую неудачно завершиться на уровне фреймворка (не гарантируется конкретная форма ошибки)

Что вы увидите, когда превышено 15MB

Возвращается код состояния 413 Payload Too Large, тело ответа — это текст (не JSON), содержание примерно:

音频文件过大 (18.5 MB)。最大支持 15 MB (约 16 分钟 MP3)。建议: 1) 压缩音频质量 2) 分段上传

Два выполнимых метода разделения

  1. Сжатие качества аудио (преобразовать WAV в меньший MP3)
bash
ffmpeg -i input.wav -b:a 64k -ac 1 output.mp3
  1. Разделение (разрезать длинное аудио на несколько сегментов)
bash
ffmpeg -i long_audio.mp3 -f segment -segment_time 600 -c copy segment_%03d.mp3

Примечания по сбору журналов

Почему часто нельзя увидеть реальное тело запроса в Monitor

Промежуточное ПО Monitor сначала считывает тело запроса POST для записи журнала:

  • Если тело запроса может быть проанализировано как текст UTF-8, запишет оригинальный текст
  • Иначе запишет как [Binary Request Data]

Транскрипция аудио использует multipart/form-data, внутри есть двоичное аудиосодержимое, поэтому легко попасть во второй случай.

Что вы должны увидеть в Monitor

URL: /v1/audio/transcriptions
Request Body: [Binary Request Data]
Response Body: {"text":"..."}

Пояснение ограничений журнала

В журнале нет самого аудио, но вы всё равно можете быстро судить: это несовместимость протокола, файл слишком большой, или вышестоящий уровень неудачен, через status/duration/X-Account-Email.

Пояснение параметров (не делайте «опытное дополнение»)

Эта конечная точка явно читает только 3 поля формы:

ПолеОбязательно?По умолчаниюСпособ обработки
fileНетДолжен быть предоставлен; отсутствие вернёт 400 + текст 缺少音频文件
modelgemini-2.0-flash-expПередаётся как строка, участвует в получении токена (конкретные правила вышестоящего уровня ориентируются на фактический ответ)
promptGenerate a transcript of speech.Отправляется как первый абзац text вышестоящему уровню, используется для направления транскрипции

Частые ошибки

❌ Ошибка 1: Неправильный параметр curl,导致 не multipart

bash
#Ошибка: напрямую использовать -d
curl -sS -X POST http://127.0.0.1:8045/v1/audio/transcriptions \
  -d "file=@audio.mp3"

Правильный подход:

bash
curl -sS -X POST http://127.0.0.1:8045/v1/audio/transcriptions \
  -F "file=@audio.mp3"

❌ Ошибка 2: Расширение файла не в списке поддержки

bash
curl -sS -X POST http://127.0.0.1:8045/v1/audio/transcriptions \
  -F "file=@document.txt"

Правильный подход: загружайте только аудиофайлы (.mp3, .wav и т.д.).

❌ Ошибка 3: Принять 413 как «шлюз сломался»

413 здесь обычно является триггером проверки 15MB. Сначала выполните сжатие/разделение, это быстрее, чем слепой повтор.

Итог урока

  • Ключевая конечная точка: POST /v1/audio/transcriptions (форма совместимости Whisper)
  • Поддержка форматов: mp3, wav, m4a, ogg, flac, aiff (aif)
  • Ограничение размера: 15MB (при превышении возвращается 413 + текстовая информация об ошибке)
  • Поведение журнала: когда в multipart есть двоичное содержимое, Monitor покажет [Binary Request Data]
  • Ключевые параметры: file / model / prompt (значения по умолчанию см. выше)

Предпросмотр следующего урока

В следующем уроке мы изучим Конечные точки MCP: Раскрыть Web Search/Reader/Vision как вызываемые инструменты.

Вы узнаете:

  • Форма маршрутизации и стратегия аутентификации конечных точек MCP
  • Web Search/Web Reader/Vision использует «пересылку вышестоящего уровня» или «встроенный инструмент»
  • Какие возможности экспериментальны, не наступайте на мину в производстве

Приложение: Справочник по исходному коду

Нажмите, чтобы раскрыть расположение исходного кода

Обновлено: 2026-01-23

ФункцияПуть к файлуСтроки
Регистрация маршрута (/v1/audio/transcriptions + body limit)src-tauri/src/proxy/server.rs120-194
Обработчик транскрипции аудио (multipart/15MB/inlineData)src-tauri/src/proxy/handlers/audio.rs16-162
---------
Промежуточное ПО Monitor (Binary Request Data)src-tauri/src/proxy/middleware/monitor.rs13-337

Ключевые константы:

  • MAX_SIZE = 15 * 1024 * 1024: ограничение размера аудиофайла (15MB)
  • MAX_REQUEST_LOG_SIZE = 100 * 1024 * 1024:上限 чтения тела запроса POST в Monitor (100MB)
  • MAX_RESPONSE_LOG_SIZE = 100 * 1024 * 1024:上限 чтения тела ответа в Monitor (100MB)

Ключевые функции:

  • handle_audio_transcription(): разбор multipart, проверка расширения и размера, сборка inlineData и вызов вышестоящего уровня
  • AudioProcessor::detect_mime_type(): расширение -> MIME
  • AudioProcessor::exceeds_size_limit(): проверка 15MB
  • monitor_middleware(): падать тело запроса/ответа в Proxy Monitor (только UTF-8 полностью запишется)