Spaces:
Sleeping
Sleeping
File size: 4,682 Bytes
11f3a2b ac0d52f 11f3a2b ac0d52f 11f3a2b ac0d52f 11f3a2b b1cdca3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 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)) |