Evgeny Naumov
Добавлена асинхронная транскрипция с отслеживанием прогресса и увеличенными таймаутами
6232404
# Whisper API Документация
## Обзор
Whisper API предоставляет REST API для транскрипции аудио файлов с использованием моделей Whisper. API работает на порту 3001 и поддерживает как синхронные, так и асинхронные запросы для длинных транскрипций.
**Базовый URL:** `http://localhost:3001/api`
## Endpoints
### 1. Проверка здоровья сервера
**GET** `/health`
Проверяет, что сервер работает.
**Ответ:**
```json
{
"status": "ok",
"message": "Whisper API сервер работает",
"timestamp": "2024-01-01T12:00:00.000Z"
}
```
### 2. Асинхронная транскрипция аудио файла
**POST** `/transcribe`
Загружает и транскрибирует аудио файл асинхронно. Возвращает ID задачи для отслеживания прогресса.
**Параметры:**
- `audio` (file) - аудио файл (обязательно)
- `language` (string) - язык аудио (по умолчанию: "auto")
- `model` (string) - модель Whisper (по умолчанию: "base")
**Поддерживаемые форматы:** mp3, wav, m4a, webm, ogg
**Максимальный размер файла:** 50MB
**Пример запроса (cURL):**
```bash
curl -X POST http://localhost:3001/api/transcribe \
-F "audio=@/path/to/audio.mp3" \
-F "language=ru" \
-F "model=base"
```
**Ответ:**
```json
{
"success": true,
"taskId": "abc123def456",
"status": "processing",
"message": "Транскрипция началась",
"timestamp": "2024-01-01T12:00:00.000Z"
}
```
### 3. Проверка статуса задачи
**GET** `/status/{taskId}`
Проверяет статус и прогресс транскрипции.
**Пример запроса:**
```bash
curl http://localhost:3001/api/status/abc123def456
```
**Ответ:**
```json
{
"success": true,
"task": {
"id": "abc123def456",
"filename": "audio.mp3",
"language": "ru",
"model": "base",
"status": "processing",
"progress": 45,
"result": null,
"error": null,
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:05:00.000Z"
},
"timestamp": "2024-01-01T12:05:00.000Z"
}
```
### 4. Получение результата транскрипции
**GET** `/result/{taskId}`
Получает готовый результат транскрипции.
**Пример запроса:**
```bash
curl http://localhost:3001/api/result/abc123def456
```
**Ответ (если транскрипция завершена):**
```json
{
"success": true,
"status": "completed",
"transcription": {
"text": "Транскрибированный текст",
"language": "ru",
"model": "base",
"duration": 120.5,
"segments": [
{
"start": 0,
"end": 10,
"text": "Первая часть текста"
}
],
"timestamp": "2024-01-01T12:10:00.000Z"
},
"timestamp": "2024-01-01T12:10:00.000Z"
}
```
**Ответ (если транскрипция еще выполняется):**
```json
{
"success": true,
"status": "processing",
"progress": 75,
"message": "Транскрипция еще выполняется"
}
```
**Ответ (если произошла ошибка):**
```json
{
"success": false,
"status": "error",
"error": "Описание ошибки"
}
```
### 5. Асинхронная транскрипция по URL
**POST** `/transcribe/url`
Транскрибирует аудио файл по URL асинхронно.
**Тело запроса:**
```json
{
"url": "https://example.com/audio.mp3",
"language": "ru",
"model": "base"
}
```
**Пример запроса (cURL):**
```bash
curl -X POST http://localhost:3001/api/transcribe/url \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/audio.mp3",
"language": "ru",
"model": "base"
}'
```
**Ответ:**
```json
{
"success": true,
"taskId": "def456ghi789",
"status": "processing",
"message": "Транскрипция по URL началась",
"timestamp": "2024-01-01T12:00:00.000Z"
}
```
### 6. Список доступных моделей
**GET** `/models`
Возвращает список доступных моделей Whisper.
**Ответ:**
```json
{
"models": [
{
"id": "tiny",
"name": "Tiny",
"size": "39 MB",
"languages": "multilingual"
},
{
"id": "base",
"name": "Base",
"size": "74 MB",
"languages": "multilingual"
},
{
"id": "small",
"name": "Small",
"size": "244 MB",
"languages": "multilingual"
},
{
"id": "medium",
"name": "Medium",
"size": "769 MB",
"languages": "multilingual"
},
{
"id": "large",
"name": "Large",
"size": "1550 MB",
"languages": "multilingual"
}
],
"default": "base"
}
```
### 7. Список поддерживаемых языков
**GET** `/languages`
Возвращает список поддерживаемых языков.
**Ответ:**
```json
{
"languages": [
{
"code": "auto",
"name": "Автоопределение"
},
{
"code": "ru",
"name": "Русский"
},
{
"code": "en",
"name": "English"
},
{
"code": "es",
"name": "Español"
},
{
"code": "fr",
"name": "Français"
},
{
"code": "de",
"name": "Deutsch"
},
{
"code": "it",
"name": "Italiano"
},
{
"code": "pt",
"name": "Português"
},
{
"code": "pl",
"name": "Polski"
},
{
"code": "tr",
"name": "Türkçe"
},
{
"code": "ja",
"name": "日本語"
},
{
"code": "ko",
"name": "한국어"
},
{
"code": "zh",
"name": "中文"
}
],
"default": "auto"
}
```
## Коды ошибок
- **400** - Неверный запрос (отсутствует файл, неподдерживаемый формат)
- **404** - Endpoint не найден или задача не найдена
- **500** - Внутренняя ошибка сервера
- **202** - Задача в процессе выполнения (для `/result/{taskId}`)
## Таймауты
- **Таймаут сервера:** 1 час (3600000 мс)
- **Таймаут запроса:** 1 час
- **Таймаут ответа:** 1 час
## Примеры использования
### Python
```python
import requests
import time
# Асинхронная транскрипция файла
with open('audio.mp3', 'rb') as f:
files = {'audio': f}
data = {'language': 'ru', 'model': 'base'}
response = requests.post('http://localhost:3001/api/transcribe', files=files, data=data)
result = response.json()
task_id = result['taskId']
print(f"Задача создана: {task_id}")
# Проверка статуса
while True:
status_response = requests.get(f'http://localhost:3001/api/status/{task_id}')
status_data = status_response.json()
if status_data['task']['status'] == 'completed':
break
elif status_data['task']['status'] == 'error':
print(f"Ошибка: {status_data['task']['error']}")
break
print(f"Прогресс: {status_data['task']['progress']}%")
time.sleep(5) # Проверяем каждые 5 секунд
# Получение результата
result_response = requests.get(f'http://localhost:3001/api/result/{task_id}')
final_result = result_response.json()
print(f"Транскрипция: {final_result['transcription']['text']}")
# Асинхронная транскрипция по URL
data = {
'url': 'https://example.com/audio.mp3',
'language': 'ru',
'model': 'base'
}
response = requests.post('http://localhost:3001/api/transcribe/url', json=data)
result = response.json()
task_id = result['taskId']
# Ожидание завершения и получение результата
while True:
result_response = requests.get(f'http://localhost:3001/api/result/{task_id}')
result_data = result_response.json()
if result_data['status'] == 'completed':
print(f"Транскрипция: {result_data['transcription']['text']}")
break
elif result_data['status'] == 'error':
print(f"Ошибка: {result_data['error']}")
break
print(f"Статус: {result_data['status']}, Прогресс: {result_data.get('progress', 0)}%")
time.sleep(5)
```
### JavaScript
```javascript
// Асинхронная транскрипция файла
async function transcribeFile(file) {
const formData = new FormData();
formData.append('audio', file);
formData.append('language', 'ru');
formData.append('model', 'base');
const response = await fetch('http://localhost:3001/api/transcribe', {
method: 'POST',
body: formData
});
const result = await response.json();
return result.taskId;
}
// Проверка статуса
async function checkStatus(taskId) {
const response = await fetch(`http://localhost:3001/api/status/${taskId}`);
return await response.json();
}
// Получение результата
async function getResult(taskId) {
const response = await fetch(`http://localhost:3001/api/result/${taskId}`);
return await response.json();
}
// Полный процесс транскрипции
async function transcribeWithProgress(file) {
const taskId = await transcribeFile(file);
console.log(`Задача создана: ${taskId}`);
while (true) {
const status = await checkStatus(taskId);
if (status.task.status === 'completed') {
const result = await getResult(taskId);
console.log(`Транскрипция: ${result.transcription.text}`);
break;
} else if (status.task.status === 'error') {
console.error(`Ошибка: ${status.task.error}`);
break;
}
console.log(`Прогресс: ${status.task.progress}%`);
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
```
### C#
```csharp
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class TranscriptionClient
{
private readonly HttpClient _client;
private readonly string _baseUrl = "http://localhost:3001/api";
public TranscriptionClient()
{
_client = new HttpClient();
}
public async Task<string> TranscribeFileAsync(string filePath, string language = "ru", string model = "base")
{
using var form = new MultipartFormDataContent();
using var fileStream = File.OpenRead(filePath);
form.Add(new StreamContent(fileStream), "audio", Path.GetFileName(filePath));
form.Add(new StringContent(language), "language");
form.Add(new StringContent(model), "model");
var response = await _client.PostAsync($"{_baseUrl}/transcribe", form);
var result = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<dynamic>(result);
return data.taskId.ToString();
}
public async Task<dynamic> GetStatusAsync(string taskId)
{
var response = await _client.GetAsync($"{_baseUrl}/status/{taskId}");
var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<dynamic>(result);
}
public async Task<dynamic> GetResultAsync(string taskId)
{
var response = await _client.GetAsync($"{_baseUrl}/result/{taskId}");
var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<dynamic>(result);
}
public async Task<string> TranscribeWithProgressAsync(string filePath)
{
var taskId = await TranscribeFileAsync(filePath);
Console.WriteLine($"Задача создана: {taskId}");
while (true)
{
var status = await GetStatusAsync(taskId);
if (status.task.status == "completed")
{
var result = await GetResultAsync(taskId);
return result.transcription.text.ToString();
}
else if (status.task.status == "error")
{
throw new Exception($"Ошибка транскрипции: {status.task.error}");
}
Console.WriteLine($"Прогресс: {status.task.progress}%");
await Task.Delay(5000);
}
}
}
```
## Развертывание
### Локально
```bash
cd whisper-web
npm install
npm run build
node server/simple-server.js
```
### На Hugging Face Spaces
Проект автоматически развертывается на Hugging Face Spaces с использованием Gradio интерфейса. Сервер запускается на порту 3001.
## Примечания
- Все транскрипции выполняются асинхронно для предотвращения таймаутов
- Прогресс транскрипции можно отслеживать через endpoint `/status/{taskId}`
- Результаты сохраняются в памяти сервера (не в базе данных)
- Таймауты увеличены до 1 часа для поддержки длинных аудио файлов