Pepguy commited on
Commit
e2290de
·
verified ·
1 Parent(s): 167ff50

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -0
app.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ import subprocess, base64, os, uuid, shutil, whisper
4
+
5
+ app = FastAPI()
6
+ whisper_model = whisper.load_model("tiny")
7
+
8
+ class VideoJsonRequest(BaseModel):
9
+ video_base64: str
10
+
11
+ def to_b64(path):
12
+ with open(path, "rb") as f: return base64.b64encode(f.read()).decode('utf-8')
13
+
14
+ @app.post("/process-video")
15
+ async def process(req: VideoJsonRequest):
16
+ uid = str(uuid.uuid4())
17
+ tmp = f"/tmp/{uid}"
18
+ os.makedirs(tmp)
19
+ v_p = f"{tmp}/v.mp4"
20
+ a_p = f"{tmp}/a.wav"
21
+ try:
22
+ with open(v_p, "wb") as f: f.write(base64.b64decode(req.video_base64))
23
+ probe = subprocess.run(["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", v_p], capture_output=True, text=True).stdout
24
+ dur = float(probe.strip() or 0)
25
+ # Extract 15 frames
26
+ subprocess.run(["ffmpeg", "-y", "-i", v_p, "-vf", f"fps={15/max(dur,1)}", "-vframes", "15", "-q:v", "5", f"{tmp}/f_%03d.jpg"])
27
+ # Transcribe
28
+ subprocess.run(["ffmpeg", "-y", "-i", v_p, "-vn", "-acodec", "pcm_s16le", "-ar", "16000", "-ac", "1", a_p])
29
+ txt = whisper_model.transcribe(a_p)["text"].strip()
30
+ f_names = sorted([f"{tmp}/{f}" for f in os.listdir(tmp) if f.startswith("f_")])
31
+ imgs = [to_b64(f) for f in f_names]
32
+ return {"success": True, "transcript": txt, "frames": imgs, "thumbnail": imgs[0] if imgs else None}
33
+ except Exception as e: return {"success": False, "error": str(e)}
34
+ finally: shutil.rmtree(tmp, ignore_errors=True)