storebound/skills/app-previews/SKILL.md

5.8 KiB

name description
app-previews Make App Store app preview videos and a Google Play promo video for a mobile app or game from real footage (gameplay or app flows) - record clips from a web build, the iOS Simulator, an Android emulator or a folder, cut them to the store formats with captions in every language, check them against the store rules, upload the previews to App Store Connect and put the YouTube URL on Play. Use when the user wants an app preview, preview video, promo video, gameplay trailer for the stores, or asks about app preview sizes and rules.

App previews and promo video

CLI: storebound (bunx storebound in a project that has it). Needs ffmpeg / ffprobe; web recording and caption rendering need playwright in the project (bun add -d playwright; Playwright's Chromium or an installed Google Chrome; no extra Playwright download). Simulator recording needs macOS + Xcode, Android recording needs adb.

What the stores want

target pixels store notes
iphone 886 x 1920 App Store (IPHONE_67) accepted for 6.9", 6.5" and 6.1" iPhones; smaller ones get scaled copies
ipad 1200 x 1600 App Store (IPAD_PRO_3GEN_129) only with apple.ipad: true
youtube 1080 x 1920 Play promo video Play has no video upload: upload to YouTube, put the URL in play.video
youtube-landscape 1920 x 1080 Play promo video landscape alternative

Apple app previews (App Store Connect Help > App preview specifications, https://developer.apple.com/help/app-store-connect/reference/app-information/app-preview-specifications): 15-30 s, at most 30 fps, H.264 (High profile up to level 4.0, 10-12 Mbps) or ProRes 422 HQ, .mov / .m4v / .mp4, at most 500 MB, a stereo audio track (AAC 256 kbps, 44.1 or 48 kHz; a silent one is fine), up to 3 per device size and language, poster frame at 5 s by default. Optional: a missing size or language falls back to scaled / another language. Content: footage captured from the app itself, no hands or devices filmed around it, no prices or other platforms' UI. Play promo video: YouTube URL, public or unlisted, ads off, embeddable, no age restriction (https://support.google.com/googleplay/android-developer/answer/9866151).

Steps

  1. Hands-free footage. Give the game an autoplay / attract mode switch, or the app a scripted demo of its main flow on sample data (URL param, launch argument or intent extra), plus the screenshot switches (language, fixed seed or demo data, no ads). Otherwise record the screen (simulator, emulator or browser recording you start) and use --source folder.
  2. Clips. shots.video.record.clips: per clip seconds (1-60) and path (web, after shots.capture.baseUrl), or url / args / extras (simulator / emulator), waitFor, delayMs. The source and its settings come from shots.capture (or record.source). storebound shots record --dry shows the plan, then storebound shots record writes store/video/clips/<lang>/NN-<name>.mp4 (30 fps H.264, no audio).
    • web: JPEG frames at the frame's device pixels (Page.captureScreenshot, long side capped at 1920, the tallest store video), 3 requests in flight (~45-55 frames/s), joined at their real timings; filming starts when waitFor is true. It warns when frames come out smaller than asked (an upscale) or under 20 frames/s.
    • ios-sim: simctl io recordVideo, stopped after seconds; boots (and later shuts down) the simulator if needed; the first launch after a cold boot gets ios.warmupMs. A still ending is padded with the last frame.
    • android-emu: screenrecord on the running emulator / device (never booted, wiped or rebooted).
    • folder: put clips in <clips>/<lang>/ (or <clips>/ for every language); shots record lists them.
  3. Cut. storebound shots video --dry, then storebound shots video (background + log for many languages): clips joined in name order up to shots.video.seconds (default 25), scaled to fill (fit: 'contain' letterboxes on background), one caption per clip from the screenshot copy titles (captionScenes), music from shots.video.audio (looped, faded) or a silent stereo track. Out: <renders>/<lang>/preview/<target>/01.mp4 + 01-poster.png; every file is probed and checked.
  4. Check + review. storebound shots check (videos included) and storebound shots gallery (previews play in the page with their poster). Watch at least one language end to end.
  5. Upload. App Store: storebound apple previews --dry, then storebound apple previews (editable version, MD5-idempotent, poster frame from --poster / shots.video.poster, files checked before anything is sent). Play: the video must be on YouTube. Publishing on the owner's channel is public, so ask for it in the start batch (or for an existing video URL); upload it with your browser tool once the owner said yes, set play.video, run storebound play listing (the listing PUT replaces the whole listing: without play.video a video set in Play Console is cleared).

From an AI tool (MCP)

shots_record, shots_video (local files) and apple_previews (store write) default to dry_run: true: show the plan, then run for real only after the owner agreed. shots_check is read-only.

Gotchas

  • Under 15 s of clips is an error: record longer clips or more of them.
  • Captions sit at the top: keep the app's top bar or the game's HUD readable or set captions: false.
  • 886 x 1920 cover-crops a 9:19.5 phone recording almost exactly; tablet previews from phone clips are cropped hard, record tablet clips (record.device: 'tablet') or use fit: 'contain'.
  • Apple processes previews for a while after the upload; apple previews reports failed ones (re-run to retry).
  • Product Page Optimization treatments can have their own previews: set them up in App Store Connect (see the store-screenshots skill).