에이디어 위클리
EN

↑↓ Enter Esc

MOT-002Strayling 광고

MOT-002

Strayling 광고

  • 스토어 화면 몇 장으로 세로와 가로 광고를 함께
  • 앱 이름과 장면 문구만 바꿔 다시 그려요

// 사용: node scripts/ads/render.mjs. 스토어 공개 화면으로 광고 영상을 만들고(소리 없음) 사이트용으로 줄여요.
import { spawn, execSync } from "node:child_process"; import path from "node:path"; import { chromium } from "playwright";
const FPS = 30, T = path.resolve("scripts/ads/template.html"), M = "docs/videos", P = "public/videos";
const b = await chromium.launch({ channel: "chrome", args: ["--allow-file-access-from-files"] });
for (const app of ["strayling", "nook"]) for (const [fmt, w, h] of [["9x16", 1080, 1920], ["16x9", 1920, 1080]]) {
  const p = await b.newPage({ viewport: { width: w, height: h } }); await p.goto(`file://${T}?app=${app}`); await p.evaluate(() => window.READY); const total = await p.evaluate(() => window.TOTAL), n = Math.round(total * FPS);
  const ff = spawn("ffmpeg", ["-y", "-v", "error", "-f", "image2pipe", "-framerate", String(FPS), "-c:v", "mjpeg", "-i", "-", "-an", "-c:v", "libx264", "-crf", "20", "-preset", "medium", "-pix_fmt", "yuv420p", "-movflags", "+faststart", `${M}/${app}-${fmt}.mp4`], { stdio: ["pipe", "inherit", "inherit"] });
  for (let i = 0; i < n; i++) { await p.evaluate((t) => window.seek(t), i / FPS); ff.stdin.write(await p.screenshot({ type: "jpeg", quality: 95 })); }
  ff.stdin.end(); await new Promise((r) => ff.on("close", r)); await p.close(); console.log(app, fmt, total.toFixed(1) + "s");
}
await b.close();
const run = (c) => execSync(`ffmpeg -y -v error ${c}`);
const enc = (i, o, vf, crf, wcrf, extra = "") => { run(`${extra} -i ${i} -an -vf ${vf} -c:v libx264 -crf ${crf} -preset slow -pix_fmt yuv420p -movflags +faststart ${o}.mp4`); run(`${extra} -i ${i} -an -vf ${vf} -c:v libvpx-vp9 -crf ${wcrf} -b:v 0 -row-mt 1 -cpu-used 2 ${o}.webm`); };
for (const app of ["strayling", "nook"]) {
  const L = `${M}/${app}-16x9.mp4`, V = `${M}/${app}-9x16.mp4`;
  enc(L, `${P}/${app}-16x9-960`, "scale=960:-2", 27, 36); enc(L, `${P}/${app}-16x9-480`, "scale=480:-2", 30, 40); enc(V, `${P}/${app}-9x16-540`, "scale=540:-2", 29, 38);
  run(`-ss 5 -i ${L} -frames:v 1 -vf scale=960:-2 -q:v 5 ${P}/${app}-poster.jpg`);
}

사용법

  1. 저장소에서 node scripts/ads/render.mjs를 돌려요.
  2. 장면과 문구는 scripts/ads/template.html의 APPS에서 바꿔요.

과정

  1. 스토어에 공개한 앱 화면을 모았어요.
  2. HTML 템플릿 하나에 장면과 문구, 손가락 탭을 그렸어요.
  3. Playwright로 30fps 프레임을 찍어 ffmpeg로 9:16과 16:9 영상을 만들었어요.

같은 분류 MOT