Spaces:
Paused
Paused
File size: 4,509 Bytes
1ddd8a3 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e f46a634 1ddd8a3 51cdd3e f46a634 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 f46a634 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e f46a634 51cdd3e 1ddd8a3 f46a634 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e f46a634 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e f46a634 51cdd3e 1ddd8a3 f46a634 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 f46a634 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 f46a634 1ddd8a3 51cdd3e f46a634 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e 1ddd8a3 51cdd3e f46a634 51cdd3e f46a634 1ddd8a3 f46a634 1ddd8a3 51cdd3e 1ddd8a3 f46a634 51cdd3e f46a634 | 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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | from fastapi import FastAPI, Query
from fastapi.responses import FileResponse, JSONResponse
from playwright.async_api import async_playwright
import os, uuid, asyncio, shutil, stat
app = FastAPI(
title="Brat-Api Farel",
description="Free BRAT Image & Video Generator API",
version="1.0.0",
)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
def ensure_dir(path: str):
os.makedirs(path, exist_ok=True)
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
return path
OUTPUT_DIR = ensure_dir(os.path.join(BASE_DIR, "output"))
TMP_DIR = ensure_dir(os.path.join(BASE_DIR, "tmp"))
async def delete_later(path: str, delay: int = 300):
await asyncio.sleep(delay)
if os.path.exists(path):
os.remove(path)
# =========================
# ROOT → index.html
# =========================
@app.get("/")
async def root():
html = os.path.join(BASE_DIR, "index.html")
if not os.path.exists(html):
return JSONResponse(status_code=404, content={"error": "index.html not found"})
return FileResponse(html, media_type="text/html")
# =========================
# BRAT IMAGE (INLINE VIEW)
# =========================
@app.get("/api/brat")
async def brat_image(text: str = Query(...)):
text = text.strip()
if not text:
return JSONResponse(status_code=400, content={"error": "text is required"})
filepath = os.path.join(OUTPUT_DIR, f"brat-{uuid.uuid4().hex}.png")
async with async_playwright() as p:
browser = await p.chromium.launch(args=["--no-sandbox"])
page = await (await browser.new_context(
viewport={"width": 1536, "height": 695}
)).new_page()
await page.goto("https://www.bratgenerator.com/", wait_until="domcontentloaded")
try:
await page.click("text=Accept", timeout=3000)
except:
pass
await page.click("#toggleButtonWhite")
await page.click("#textOverlay")
await page.fill("#textInput", text)
await asyncio.sleep(0.4)
el = await page.query_selector("#textOverlay")
box = await el.bounding_box()
img = await page.screenshot(
clip={"x": box["x"], "y": box["y"], "width": 500, "height": 440}
)
with open(filepath, "wb") as f:
f.write(img)
await browser.close()
asyncio.create_task(delete_later(filepath))
# ⬅️ INLINE (preview di browser)
return FileResponse(filepath, media_type="image/png")
# =========================
# BRAT VIDEO (INLINE VIEW)
# =========================
@app.get("/api/bratvid")
async def brat_video(text: str = Query(...)):
text = text.strip()
if not text:
return JSONResponse(status_code=400, content={"error": "text is required"})
words = text.split()
temp_dir = ensure_dir(os.path.join(TMP_DIR, uuid.uuid4().hex))
async with async_playwright() as p:
browser = await p.chromium.launch(args=["--no-sandbox"])
page = await (await browser.new_context(
viewport={"width": 1536, "height": 695}
)).new_page()
await page.goto("https://www.bratgenerator.com/", wait_until="domcontentloaded")
try:
await page.click("text=Accept", timeout=3000)
except:
pass
await page.click("#toggleButtonWhite")
await page.click("#textOverlay")
for i in range(len(words)):
await page.fill("#textInput", " ".join(words[:i+1]))
await asyncio.sleep(0.2)
el = await page.query_selector("#textOverlay")
box = await el.bounding_box()
img = await page.screenshot(
clip={"x": box["x"], "y": box["y"], "width": 500, "height": 440}
)
with open(os.path.join(temp_dir, f"frame{i:03d}.png"), "wb") as f:
f.write(img)
await browser.close()
output = os.path.join(OUTPUT_DIR, f"bratvid-{uuid.uuid4().hex}.mp4")
await asyncio.create_subprocess_exec(
"ffmpeg", "-y",
"-framerate", "1.4",
"-i", os.path.join(temp_dir, "frame%03d.png"),
"-vf", "scale=trunc(iw/2)*2:trunc(ih/2)*2,fps=30",
"-pix_fmt", "yuv420p",
output,
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL
)
shutil.rmtree(temp_dir, ignore_errors=True)
asyncio.create_task(delete_later(output))
# ⬅️ INLINE VIDEO (play langsung)
return FileResponse(output, media_type="video/mp4") |