HulkToigo's picture
Update app.py
b1cdca3 verified
Raw
History Blame Contribute Delete
4.68 kB
from fastapi import FastAPI, HTTPException, UploadFile, File
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.background import BackgroundTasks
import os, subprocess, traceback, urllib.parse
app = FastAPI()
TMP_DIR = "/tmp/motor_hf"
os.makedirs(TMP_DIR, exist_ok=True)
app.add_middleware(
CORSMiddleware, allow_origins=["*"], allow_credentials=True,
allow_methods=["*"], allow_headers=["*"],
)
# ── Healthcheck leve (usado pelo MyMp3 para o sinal luminoso de status) ─────
@app.get("/")
def home():
return {"status": "online", "servico": "AV Conversion Core"}
# ── MP3 via upload (usado pela OrangePi e pelo LocalServer/Musicas) ─────────
@app.post("/processar_conversao")
async def processar_conversao(audio_bruto: UploadFile = File(...)):
job_id = os.urandom(4).hex()
caminho_bruto = f"{TMP_DIR}/bruto_{job_id}"
caminho_mp3 = f"{TMP_DIR}/saida_{job_id}.mp3"
try:
conteudo = await audio_bruto.read()
with open(caminho_bruto, "wb") as f:
f.write(conteudo)
cmd = ["ffmpeg", "-y", "-i", caminho_bruto, "-q:a", "0", "-map", "a", caminho_mp3]
res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, timeout=180)
if res.returncode != 0 or not os.path.exists(caminho_mp3):
raise Exception(f"Erro FFmpeg: {res.stderr}")
bg = BackgroundTasks()
bg.add_task(os.remove, caminho_bruto)
bg.add_task(os.remove, caminho_mp3)
return FileResponse(caminho_mp3, media_type="audio/mpeg", background=bg)
except Exception as e:
traceback.print_exc()
if os.path.exists(caminho_bruto):
try: os.remove(caminho_bruto)
except Exception: pass
raise HTTPException(status_code=500, detail=str(e))
# ── MP3 via URL direta (busca na CDN, sem upload) ───────────────────────────
@app.get("/converter_stream_direta")
def converter_stream_direta(url_stream_audio: str, titulo_musica: str):
job_id = os.urandom(4).hex()
titulo_limpo = titulo_musica.replace("/", "").replace("\\", "").replace(" ", "_")
caminho_mp3 = f"{TMP_DIR}/{titulo_limpo}_{job_id}.mp3"
try:
url_real = urllib.parse.unquote(url_stream_audio)
cmd = ["ffmpeg", "-y", "-i", url_real, "-q:a", "0", caminho_mp3]
res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, timeout=120)
if res.returncode != 0:
raise Exception(f"Erro FFmpeg no co-processamento: {res.stderr}")
if os.path.exists(caminho_mp3):
bg = BackgroundTasks()
bg.add_task(os.remove, caminho_mp3)
headers = {"Content-Disposition": f'attachment; filename="{urllib.parse.quote(titulo_limpo)}.mp3"'}
return FileResponse(caminho_mp3, media_type="audio/mpeg", headers=headers, background=bg)
raise Exception("Falha ao gerar arquivo MP3")
except Exception as e:
traceback.print_exc()
raise HTTPException(status_code=500, detail=str(e))
# ── MP4 via URL direta (usado pela OrangePi e LocalServer para Clipes) ──────
@app.get("/converter_video_direto")
def converter_video_direto(url_stream_video: str, titulo_video: str):
job_id = os.urandom(4).hex()
titulo_limpo = titulo_video.replace("/", "").replace("\\", "").replace(" ", "_")
caminho_mp4 = f"{TMP_DIR}/{titulo_limpo}_{job_id}.mp4"
try:
url_real = urllib.parse.unquote(url_stream_video)
cmd = [
"ffmpeg", "-y", "-i", url_real,
"-c:v", "libx264", "-preset", "veryfast", "-crf", "23",
"-c:a", "aac", "-b:a", "160k",
"-movflags", "+faststart",
caminho_mp4,
]
res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, timeout=600)
if res.returncode != 0:
raise Exception(f"Erro FFmpeg no co-processamento de video: {res.stderr}")
if os.path.exists(caminho_mp4):
bg = BackgroundTasks()
bg.add_task(os.remove, caminho_mp4)
headers = {"Content-Disposition": f'attachment; filename="{urllib.parse.quote(titulo_limpo)}.mp4"'}
return FileResponse(caminho_mp4, media_type="video/mp4", headers=headers, background=bg)
raise Exception("Falha ao gerar arquivo MP4")
except Exception as e:
traceback.print_exc()
raise HTTPException(status_code=500, detail=str(e))