aio / app.py
fareldevelopers's picture
Update app.py
997ce57 verified
Raw
History Blame Contribute Delete
5.98 kB
import os
import glob
import time
import subprocess
from fastapi import FastAPI, Query, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse
app = FastAPI(
title="⚡ Studio Engine API",
description="High-speed media acquisition endpoint returning JSON payload.",
version="3.0.0",
docs_url="/",
redoc_url=None
)
DOWNLOAD_DIR = "downloads"
if not os.path.exists(DOWNLOAD_DIR):
os.makedirs(DOWNLOAD_DIR)
def delete_file_after_delay(file_path: str, delay: int = 300):
"""Menghapus file dari folder penyimpanan setelah 5 menit (300 detik)"""
time.sleep(delay)
if os.path.exists(file_path):
try:
os.remove(file_path)
print(f"[Auto-Delete] File hangus berhasil dihapus: {file_path}")
except Exception as e:
print(f"[Auto-Delete] Gagal menghapus file {file_path}: {e}")
@app.get('/api/mp3', summary="Get JSON Info for MP3 Audio")
def download_mp3(
background_tasks: BackgroundTasks,
url: str = Query(..., description="Target resource web URL (YouTube, TikTok, Instagram, etc.)")
):
timestamp = int(time.time())
outtmpl = f"{DOWNLOAD_DIR}/audio_{timestamp}.%(ext)s"
cmd = [
"yt-dlp",
url,
"-f", "bestaudio/best",
"-o", outtmpl,
"-x", "--audio-format", "mp3", "--audio-quality", "192K",
"--no-playlist",
"--no-warnings",
"--no-check-certificate"
]
try:
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
raise Exception(result.stderr)
downloaded_files = glob.glob(f"{DOWNLOAD_DIR}/audio_{timestamp}.mp3")
if not downloaded_files:
downloaded_files = glob.glob(f"{DOWNLOAD_DIR}/*_{timestamp}*")
if not downloaded_files:
raise HTTPException(status_code=500, detail="Gagal menyimpan file audio ke server.")
file_path = downloaded_files[0]
file_name = os.path.basename(file_path)
# Daftarkan background task untuk menghapus file dalam waktu 5 menit
background_tasks.add_task(delete_file_after_delay, file_path, 300)
return {
"status": "success",
"message": "File ready. Links are valid for 5 minutes.",
"file_name": file_name,
"format": "mp3",
"auto_download_url": f"https://fareldevelopers-aio.hf.space/api/get-file/{file_name}?action=download",
"play_in_browser_url": f"https://fareldevelopers-aio.hf.space/api/get-file/{file_name}?action=stream"
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Audio Engine Error: {str(e)}")
@app.get('/api/mp4', summary="Get JSON Info for MP4 Video")
def download_mp4(
background_tasks: BackgroundTasks,
url: str = Query(..., description="Target resource web URL (YouTube, TikTok, Instagram, etc.)"),
resolution: str = Query("720", description="Resolution specification (Optional). Default: 720")
):
timestamp = int(time.time())
outtmpl = f"{DOWNLOAD_DIR}/video_{timestamp}_{resolution}p.%(ext)s"
yt_dlp_format = f"bestvideo[height<={resolution}]+bestaudio/best[height<={resolution}]/best"
cmd = [
"yt-dlp",
url,
"-f", yt_dlp_format,
"-o", outtmpl,
"--merge-output-format", "mp4",
"--no-playlist",
"--no-warnings",
"--no-check-certificate"
]
try:
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
raise Exception(result.stderr)
downloaded_files = glob.glob(f"{DOWNLOAD_DIR}/video_{timestamp}_{resolution}p.mp4")
if not downloaded_files:
downloaded_files = glob.glob(f"{DOWNLOAD_DIR}/*_{timestamp}*")
if not downloaded_files:
raise HTTPException(status_code=500, detail="Gagal menyimpan file video ke server.")
file_path = downloaded_files[0]
file_name = os.path.basename(file_path)
# Daftarkan background task untuk menghapus file dalam waktu 5 minutes
background_tasks.add_task(delete_file_after_delay, file_path, 300)
return {
"status": "success",
"message": "File ready. Links are valid for 5 minutes.",
"file_name": file_name,
"format": "mp4",
"resolution": resolution,
"auto_download_url": f"https://fareldevelopers-aio.hf.space/api/get-file/{file_name}?action=download",
"play_in_browser_url": f"https://fareldevelopers-aio.hf.space/api/get-file/{file_name}?action=stream"
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Video Engine Error: {str(e)}")
@app.get('/api/get-file/{file_name}', summary="Serve Saved File (Download or Stream)")
def get_file(file_name: str, action: str = Query("download", description="Options: 'download' or 'stream'")):
"""Endpoint core yang melayani file berdasarkan query parameter action"""
file_path = os.path.join(DOWNLOAD_DIR, file_name)
if not os.path.exists(file_path):
raise HTTPException(status_code=404, detail="File tidak ditemukan atau sudah kedaluwarsa (terhapus otomatis setelah 5 menit).")
# Deteksi tipe media berdasarkan extension
media_type = "audio/mpeg" if file_name.endswith(".mp3") else "video/mp4"
if action == "stream":
# Menggunakan inline content disposition agar browser memutar langsung di web
return FileResponse(file_path, media_type=media_type, content_disposition_type="inline")
else:
# Menggunakan attachment content disposition agar browser otomatis mendownload file
return FileResponse(file_path, media_type="application/octet-stream", filename=file_name, content_disposition_type="attachment")