feat: Celery setup and transcription task — Whisper + FFmpeg pipeline
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from app.config import settings
|
||||
|
||||
_model = None
|
||||
|
||||
|
||||
def _get_model():
|
||||
global _model
|
||||
if _model is None:
|
||||
from faster_whisper import WhisperModel
|
||||
_model = WhisperModel(
|
||||
settings.whisper_model,
|
||||
device=settings.whisper_device,
|
||||
compute_type=settings.whisper_compute_type,
|
||||
)
|
||||
return _model
|
||||
|
||||
|
||||
def extract_audio(video_path: str) -> str:
|
||||
audio_path = os.path.join(
|
||||
settings.upload_dir, f"{uuid.uuid4().hex}.wav"
|
||||
)
|
||||
subprocess.run(
|
||||
[
|
||||
"ffmpeg", "-i", video_path,
|
||||
"-vn", "-acodec", "pcm_s16le",
|
||||
"-ar", "16000", "-ac", "1",
|
||||
audio_path, "-y",
|
||||
],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
return audio_path
|
||||
|
||||
|
||||
def transcribe_audio(audio_path: str) -> dict:
|
||||
model = _get_model()
|
||||
start_time = time.time()
|
||||
|
||||
segments_iter, info = model.transcribe(
|
||||
audio_path,
|
||||
beam_size=5,
|
||||
language=None,
|
||||
vad_filter=True,
|
||||
)
|
||||
|
||||
segments = []
|
||||
full_text_parts = []
|
||||
for segment in segments_iter:
|
||||
segments.append({
|
||||
"start": round(segment.start, 2),
|
||||
"end": round(segment.end, 2),
|
||||
"text": segment.text.strip(),
|
||||
})
|
||||
full_text_parts.append(segment.text.strip())
|
||||
|
||||
processing_time = time.time() - start_time
|
||||
|
||||
return {
|
||||
"text": " ".join(full_text_parts),
|
||||
"segments": segments,
|
||||
"language": info.language,
|
||||
"processing_time": round(processing_time, 2),
|
||||
}
|
||||
Reference in New Issue
Block a user