FarelDeveloper commited on
Commit
f46a634
·
verified ·
1 Parent(s): c83139c

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +36 -26
main.py CHANGED
@@ -9,13 +9,15 @@ app = FastAPI(
9
  version="1.0.0",
10
  )
11
 
 
 
12
  def ensure_dir(path: str):
13
  os.makedirs(path, exist_ok=True)
14
  os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
15
  return path
16
 
17
- OUTPUT_DIR = ensure_dir(os.path.join(os.getcwd(), "output"))
18
- TMP_DIR = ensure_dir(os.path.join(os.getcwd(), "tmp"))
19
 
20
  async def delete_later(path: str, delay: int = 300):
21
  await asyncio.sleep(delay)
@@ -23,7 +25,17 @@ async def delete_later(path: str, delay: int = 300):
23
  os.remove(path)
24
 
25
  # =========================
26
- # BRAT IMAGE
 
 
 
 
 
 
 
 
 
 
27
  # =========================
28
  @app.get("/api/brat")
29
  async def brat_image(text: str = Query(...)):
@@ -31,13 +43,13 @@ async def brat_image(text: str = Query(...)):
31
  if not text:
32
  return JSONResponse(status_code=400, content={"error": "text is required"})
33
 
34
- filename = f"brat-{uuid.uuid4().hex}.png"
35
- filepath = os.path.join(OUTPUT_DIR, filename)
36
 
37
  async with async_playwright() as p:
38
  browser = await p.chromium.launch(args=["--no-sandbox"])
39
- context = await browser.new_context(viewport={"width": 1536, "height": 695})
40
- page = await context.new_page()
 
41
 
42
  await page.goto("https://www.bratgenerator.com/", wait_until="domcontentloaded")
43
  try:
@@ -50,8 +62,8 @@ async def brat_image(text: str = Query(...)):
50
  await page.fill("#textInput", text)
51
  await asyncio.sleep(0.4)
52
 
53
- element = await page.query_selector("#textOverlay")
54
- box = await element.bounding_box()
55
 
56
  img = await page.screenshot(
57
  clip={"x": box["x"], "y": box["y"], "width": 500, "height": 440}
@@ -64,10 +76,11 @@ async def brat_image(text: str = Query(...)):
64
 
65
  asyncio.create_task(delete_later(filepath))
66
 
67
- return FileResponse(filepath, media_type="image/png", filename=filename)
 
68
 
69
  # =========================
70
- # BRAT VIDEO
71
  # =========================
72
  @app.get("/api/bratvid")
73
  async def brat_video(text: str = Query(...)):
@@ -80,8 +93,9 @@ async def brat_video(text: str = Query(...)):
80
 
81
  async with async_playwright() as p:
82
  browser = await p.chromium.launch(args=["--no-sandbox"])
83
- context = await browser.new_context(viewport={"width": 1536, "height": 695})
84
- page = await context.new_page()
 
85
 
86
  await page.goto("https://www.bratgenerator.com/", wait_until="domcontentloaded")
87
  try:
@@ -93,11 +107,11 @@ async def brat_video(text: str = Query(...)):
93
  await page.click("#textOverlay")
94
 
95
  for i in range(len(words)):
96
- await page.fill("#textInput", " ".join(words[: i + 1]))
97
  await asyncio.sleep(0.2)
98
 
99
- element = await page.query_selector("#textOverlay")
100
- box = await element.bounding_box()
101
 
102
  img = await page.screenshot(
103
  clip={"x": box["x"], "y": box["y"], "width": 500, "height": 440}
@@ -108,25 +122,21 @@ async def brat_video(text: str = Query(...)):
108
 
109
  await browser.close()
110
 
111
- output_video = os.path.join(OUTPUT_DIR, f"bratvid-{uuid.uuid4().hex}.mp4")
112
 
113
- ffmpeg_cmd = [
114
  "ffmpeg", "-y",
115
  "-framerate", "1.4",
116
  "-i", os.path.join(temp_dir, "frame%03d.png"),
117
  "-vf", "scale=trunc(iw/2)*2:trunc(ih/2)*2,fps=30",
118
  "-pix_fmt", "yuv420p",
119
- output_video
120
- ]
121
-
122
- process = await asyncio.create_subprocess_exec(
123
- *ffmpeg_cmd,
124
  stdout=asyncio.subprocess.DEVNULL,
125
  stderr=asyncio.subprocess.DEVNULL
126
  )
127
- await process.wait()
128
 
129
  shutil.rmtree(temp_dir, ignore_errors=True)
130
- asyncio.create_task(delete_later(output_video))
131
 
132
- return FileResponse(output_video, media_type="video/mp4", filename=os.path.basename(output_video))
 
 
9
  version="1.0.0",
10
  )
11
 
12
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
13
+
14
  def ensure_dir(path: str):
15
  os.makedirs(path, exist_ok=True)
16
  os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
17
  return path
18
 
19
+ OUTPUT_DIR = ensure_dir(os.path.join(BASE_DIR, "output"))
20
+ TMP_DIR = ensure_dir(os.path.join(BASE_DIR, "tmp"))
21
 
22
  async def delete_later(path: str, delay: int = 300):
23
  await asyncio.sleep(delay)
 
25
  os.remove(path)
26
 
27
  # =========================
28
+ # ROOT → index.html
29
+ # =========================
30
+ @app.get("/")
31
+ async def root():
32
+ html = os.path.join(BASE_DIR, "index.html")
33
+ if not os.path.exists(html):
34
+ return JSONResponse(status_code=404, content={"error": "index.html not found"})
35
+ return FileResponse(html, media_type="text/html")
36
+
37
+ # =========================
38
+ # BRAT IMAGE (INLINE VIEW)
39
  # =========================
40
  @app.get("/api/brat")
41
  async def brat_image(text: str = Query(...)):
 
43
  if not text:
44
  return JSONResponse(status_code=400, content={"error": "text is required"})
45
 
46
+ filepath = os.path.join(OUTPUT_DIR, f"brat-{uuid.uuid4().hex}.png")
 
47
 
48
  async with async_playwright() as p:
49
  browser = await p.chromium.launch(args=["--no-sandbox"])
50
+ page = await (await browser.new_context(
51
+ viewport={"width": 1536, "height": 695}
52
+ )).new_page()
53
 
54
  await page.goto("https://www.bratgenerator.com/", wait_until="domcontentloaded")
55
  try:
 
62
  await page.fill("#textInput", text)
63
  await asyncio.sleep(0.4)
64
 
65
+ el = await page.query_selector("#textOverlay")
66
+ box = await el.bounding_box()
67
 
68
  img = await page.screenshot(
69
  clip={"x": box["x"], "y": box["y"], "width": 500, "height": 440}
 
76
 
77
  asyncio.create_task(delete_later(filepath))
78
 
79
+ # ⬅️ INLINE (preview di browser)
80
+ return FileResponse(filepath, media_type="image/png")
81
 
82
  # =========================
83
+ # BRAT VIDEO (INLINE VIEW)
84
  # =========================
85
  @app.get("/api/bratvid")
86
  async def brat_video(text: str = Query(...)):
 
93
 
94
  async with async_playwright() as p:
95
  browser = await p.chromium.launch(args=["--no-sandbox"])
96
+ page = await (await browser.new_context(
97
+ viewport={"width": 1536, "height": 695}
98
+ )).new_page()
99
 
100
  await page.goto("https://www.bratgenerator.com/", wait_until="domcontentloaded")
101
  try:
 
107
  await page.click("#textOverlay")
108
 
109
  for i in range(len(words)):
110
+ await page.fill("#textInput", " ".join(words[:i+1]))
111
  await asyncio.sleep(0.2)
112
 
113
+ el = await page.query_selector("#textOverlay")
114
+ box = await el.bounding_box()
115
 
116
  img = await page.screenshot(
117
  clip={"x": box["x"], "y": box["y"], "width": 500, "height": 440}
 
122
 
123
  await browser.close()
124
 
125
+ output = os.path.join(OUTPUT_DIR, f"bratvid-{uuid.uuid4().hex}.mp4")
126
 
127
+ await asyncio.create_subprocess_exec(
128
  "ffmpeg", "-y",
129
  "-framerate", "1.4",
130
  "-i", os.path.join(temp_dir, "frame%03d.png"),
131
  "-vf", "scale=trunc(iw/2)*2:trunc(ih/2)*2,fps=30",
132
  "-pix_fmt", "yuv420p",
133
+ output,
 
 
 
 
134
  stdout=asyncio.subprocess.DEVNULL,
135
  stderr=asyncio.subprocess.DEVNULL
136
  )
 
137
 
138
  shutil.rmtree(temp_dir, ignore_errors=True)
139
+ asyncio.create_task(delete_later(output))
140
 
141
+ # ⬅️ INLINE VIDEO (play langsung)
142
+ return FileResponse(output, media_type="video/mp4")