Разработка AI-системы транскрибации с веб-интерфейсом
Веб-интерфейс транскрибации — полноценный SaaS-продукт или внутренний инструмент компании: загрузка файлов, управление задачами, редактирование транскрипта, экспорт. Пользователь не должен разбираться в технической части.
Стек
- Backend: FastAPI + Celery + Redis
- Frontend: React + TypeScript + Tailwind
- STT: faster-whisper (GPU) + облачный fallback
- Storage: S3 (MinIO для on-premise)
- DB: PostgreSQL
Backend API
from fastapi import FastAPI, UploadFile, BackgroundTasks
from celery import Celery
import uuid
app = FastAPI()
celery = Celery('transcription', broker='redis://localhost:6379/0')
@app.post("/api/transcription/upload")
async def upload_audio(
file: UploadFile,
language: str = "ru",
speakers: int = None,
user_id: str = Depends(get_current_user)
):
# Сохраняем файл
job_id = str(uuid.uuid4())
file_path = await save_to_storage(file, job_id)
# Создаём задачу
job = await db.transcription_jobs.insert_one({
"id": job_id,
"user_id": user_id,
"status": "queued",
"file_path": file_path,
"language": language,
"created_at": datetime.utcnow()
})
# Ставим в очередь
celery.send_task(
'transcribe_audio',
args=[job_id, file_path, language, speakers]
)
return {"job_id": job_id, "status": "queued"}
@app.get("/api/transcription/{job_id}")
async def get_transcription(job_id: str, user_id = Depends(get_current_user)):
job = await db.transcription_jobs.find_one({"id": job_id, "user_id": user_id})
if not job:
raise HTTPException(404)
return job
React компонент загрузки
const TranscriptionUploader: React.FC = () => {
const [status, setStatus] = useState<'idle'|'uploading'|'processing'|'done'>('idle');
const [jobId, setJobId] = useState<string>();
const [transcript, setTranscript] = useState<string>();
const handleUpload = async (file: File) => {
setStatus('uploading');
const form = new FormData();
form.append('file', file);
form.append('language', 'ru');
const { job_id } = await api.post('/transcription/upload', form);
setJobId(job_id);
setStatus('processing');
// Polling статуса
const interval = setInterval(async () => {
const job = await api.get(`/transcription/${job_id}`);
if (job.status === 'completed') {
setTranscript(job.transcript);
setStatus('done');
clearInterval(interval);
}
}, 3000);
};
return (
<div>
<FileDropzone onFile={handleUpload} accept="audio/*,video/*" />
{status === 'processing' && <ProgressSpinner jobId={jobId} />}
{transcript && <TranscriptEditor text={transcript} jobId={jobId} />}
</div>
);
};
Редактор транскрипта
Встроенный редактор с подсветкой неуверенных слов (confidence < 0.7), кликабельными временными метками, авторедирован через грамматический чекер.
Экспорт
Форматы: TXT, DOCX, PDF, SRT, VTT, JSON.
Сроки: MVP с загрузкой и базовым UI — 2–3 недели. Полная система с редактором и командными функциями — 1.5–2 месяца.







