ffmpeg_cats / app.py
Pepguy's picture
Update app.py
f07a195 verified
Raw History Blame Contribute Delete
2.92 kB
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
import subprocess, base64, os, uuid, shutil, whisper
app = FastAPI()
whisper_model = whisper.load_model("tiny")
# 🚨 DYNAMIC SCHEMA
class VideoJsonRequest(BaseModel):
video_base64: str
num_frames: Optional[int] = 15 # Default to 15
get_transcript: Optional[bool] = True # Default to True
def to_b64(path):
with open(path, "rb") as f: return base64.b64encode(f.read()).decode('utf-8')
@app.get("/")
async def index():
return {"success": True, "engine": "Dynamic Viral Cat Media Server"}
@app.post("/process-video")
async def process(req: VideoJsonRequest):
uid = str(uuid.uuid4())
tmp = f"/tmp/{uid}"
os.makedirs(tmp)
v_p = f"{tmp}/v.mp4"
a_p = f"{tmp}/a.wav"
try:
with open(v_p, "wb") as f: f.write(base64.b64decode(req.video_base64))
# Get Duration
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
dur = float(probe.strip() or 0)
# 🚨 DYNAMIC FRAME MATH: Spreads requested frames evenly across duration
calc_fps = req.num_frames / max(dur, 1)
print("-------------------")
print(f"Requested Frames: {req.num_frames} | Duration: {dur:.2f}s | Calculated FPS: {calc_fps:.2f}")
print(f"Transcript requested: {req.get_transcript}")
print("-------------------")
# Extract X frames
subprocess.run(["ffmpeg", "-y",
"-loglevel", "error",
"-i", v_p, "-vf", f"fps={calc_fps}",
"-vframes", str(req.num_frames),
"-q:v", "5", f"{tmp}/f_%03d.jpg"])
# 🚨 CONDITIONAL TRANSCRIPT
txt = ""
if req.get_transcript:
subprocess.run(["ffmpeg", "-y",
"-loglevel", "error",
"-i", v_p, "-vn", "-acodec", "pcm_s16le", "-ar", "16000", "-ac", "1", a_p])
if os.path.exists(a_p):
result = whisper_model.transcribe(a_p)
lines = [f"[{s['start']:.2f}] {s['text'].strip()}" for s in result["segments"]]
txt = "\n".join(lines)
# Gather frames
f_names = sorted([f"{tmp}/{f}" for f in os.listdir(tmp) if f.startswith("f_")])
imgs = [to_b64(f) for f in f_names]
print("-------------------")
print(f"Successfully extracted {len(imgs)} images.")
print("-------------------")
return {"success": True, "transcript": txt, "frames": imgs, "thumbnail": imgs[0] if imgs else None}
except Exception as e: return {"success": False, "error": str(e)}
finally: shutil.rmtree(tmp, ignore_errors=True)