Skip to main content

create-chatgpt-video-ad

Produce a 9:16 social-native ad that recreates a ChatGPT mobile chat — user types in the composer with the iOS keyboard visible, taps send, keyboard slides down, header right-cluster swaps (personPlus/dotted → edit/more), one gray loading dot appears, then the assistant response streams in word-by-word with a soft opacity ramp. Continuous Playwright recording, subtle SFX (key-tap / send-tap / stream-tick / response-done), assembled into a master MP4 plus 9:16 / 1×1 exports. No music bed and no end card by default.

Zur Installation springen

Quellinformationen

Repository
criptogus/agent-evolve-network
Letzte Quellaktivität
4. Juli 2026 um 17:42
Erkannte Sprache von SKILL.md
Englisch
Sterne
289
Forks
2

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
21 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
create-chatgpt-video-ad
description
Produce a 9:16 social-native ad that recreates a ChatGPT mobile chat — user types in the composer with the iOS keyboard visible, taps send, keyboard slides down, header right-cluster swaps (personPlus/dotted → edit/more), one gray loading dot appears, then the assistant response streams in word-by-word with a soft opacity ramp. Continuous Playwright recording, subtle SFX (key-tap / send-tap / stream-tick / response-done), assembled into a master MP4 plus 9:16 / 1×1 exports. No music bed and no end card by default.
# create-chatgpt-video-ad Use this skill when an ad concept calls for an authentic ChatGPT mobile chat: someone asks ChatGPT something, the response streams in, and the *content of the response* is the punchline (the brand answer, a surprising bullet list, a recommendation). It's the "I just asked ChatGPT…" creative format. ## Purpose Animate a ChatGPT mobile conversation into a 9:16 social-native video ad where the *streamed assistant response is the punchline* — the brand surfacing as the natural answer to "I just asked ChatGPT…". The molecule composes the `create-chatgpt-mockup` renderer (driven via Playwright) with the `stitch-videos-ffmpeg` assembly step to choreograph the full beat: the user types in the iOS composer with the keyboard up, taps send (bubble pops + keyboard slides down + header right-cluster swaps in one frame), a single gray loading dot holds ~500ms, then the assistant answer streams in word-by-word with a soft opacity ramp. Everything is captured as ONE continuous Playwright recording (no scene cuts / micro-flicker), assembled into a master MP4 plus 9:16 and 1×1 exports. It is the ChatGPT-host sibling of `create-imessage-video-ad`: reach for this one when ChatGPT is the more credible host for the answer; reach for the `create-chatgpt-mockup` atom directly when you only need a still screenshot rather than the typing + streaming + auto-scroll choreography animated to video. By default the molecule ships **silent** — the recorder emits an empty SFX cue list and stitch passes the video straight through; the four bundled SFX wavs and the cue-derivation logic exist for an optional subliminal pass (see Critical knowledge #4). ## When to use - "Ask ChatGPT" → punchline-as-response ads (brand wins by being the natural answer) - Anything you'd build with the `create-imessage-video-ad` molecule but where ChatGPT is the more credible host - Recreating a real ChatGPT screenshot as a video, with the streaming animation that makes it read as live If the brief just needs a still ChatGPT screenshot, reach for the atom `create-chatgpt-mockup` directly. Use *this* molecule only when you need the **typing + streaming + auto-scroll choreography animated to video**. ## Composed Atoms - `create-chatgpt-mockup` — renders the light-mode ChatGPT iOS HTML (`renderHTML(thread)`); this molecule loads it once with every message `popState: "pending"` and drives the reveal via Playwright. (`create-chatgpt-mockup`) - `render-ios-keyboard` — the iOS QWERTY keyboard fragment (suggestion bar + alpha/shift/backspace/123/space/return rows) that gets mounted at the bottom of the stage and slid up on `keyboard-show` / down on `keyboard-hide`. The chatgpt-mockup atom inlines this same `.kbd` block, so the molecule slides it via `data-state` rather than importing it separately. (`render-ios-keyboard`) - `stitch-videos-ffmpeg` — the assembly/ffmpeg step (`edits/stitch.sh`) that takes the silent `master-chat.mp4`, layers the deterministic `master-chat.sfx.json` cue list (when cues exist) over the four bundled SFX wavs, and muxes/exports `master-final.mp4`. (`stitch-videos-ffmpeg`) ## Inputs 1. **`brief`** (required) — what the ad is selling, the question the user types, the response ChatGPT gives 2. **`output_folder`** — usually `<brand>/ads/video-NN-chatgpt-<slug>/` 3. **`thread`** — JSON matching the create-chatgpt-mockup schema, **with these animation extensions**: - Each `messages[].id` must be set so the timeline can reference it - Each `messages[].popState` defaults to `"pending"` (hidden); the driver flips it to `"now"` at the right t - The assistant message should set `stream: true` so its body words are wrapped in `<span class="word" data-stream="0">` - `header.rightIconsAlt` is the active-chat alt cluster (typically `["edit", "more"]`) - `keyboard: { layout: "qwerty-lower", suggestions: ["I","The","I'm"], state: "shown" }` mounts the keyboard 4. **`timeline`** — array of events; see "Timeline" below ## Critical knowledge — read before producing your first ad ### 0. Continuous recording, not scene-by-scene Same rule as the iMessage molecule. Render the full HTML once with all messages pending, walk a `TIMELINE` on `requestAnimationFrame` inside the page, and record the whole thing as ONE Playwright session. Do not concat scene clips — every page reload causes a micro-flicker at the cut. ### 0.5. 9:19.5, not 9:16 The atom renders at **750×1624** (ratio 0.461) which matches iPhone 14/16 Pro screen recordings. The older 9:16 ratio (750×1334) reads as proportionally squat next to a real iPhone capture — the keyboard dominates and the chat zone feels stubby. When uploading via `upload-ad-sample`, tag as `9:16` (Meta accepts both; no transcode needed). ### 1. Word streaming, not character-by-character Real ChatGPT streams **words** with a 200ms opacity+blur ramp on each. The atom's `wrapWordsForStreaming` pre-wraps every visible word in a span; the driver flips `data-stream="1"` on a schedule. Default cadence: **7 words/sec** (~140ms between word reveals). Slow it down for short responses, speed up for very long ones. ### 2. The header cluster swap is part of the send-tap, not separate The frame that the user bubble lands in is also the frame the header right-icons swap and the keyboard starts sliding down. Three things in one beat. Pulling them apart over multiple frames reads as glitchy. ### 3. The loading dot is ONE dot, not three Real ChatGPT shows a single small dark-gray solid dot below the user bubble for ~500ms before the response starts streaming. Three dots would read as iMessage typing — wrong app. ### 4. SFX are felt, not heard This is the inverse of the iMessage rule. iMessage SFX are the Apple chime — they're a feature. ChatGPT has no native SFX, so anything we play has to be **subliminal**. The pre-bundled levels are: | Cue | Level | Where it sits | |---|---|---| | `key-tap` | -28 dB | Once per word (not per char — too busy) during composer typing | | `send-tap` | -20 dB | On the `send-tap` event only | | `stream-tick` | -32 dB | Every ~12 words during streaming, as a "still working" pulse | | `response-done` | -22 dB | After the final word of the response lands | No music bed by default. If the brief asks for one, lofi at -18dB. ### 5. No SFX on the loading dot The dot is a silent state change. Same rule as the iMessage typing-pop — adding a "thinking" sound makes the chat feel fake. Skip it. ### 6. The keyboard slide and bubble pop are choreographed When the user taps send: the bubble pops in (220ms), the keyboard starts sliding down (280ms), the composer rides up by -518px (the keyboard's height) over the same 280ms. The slide and the bubble overlap — the bubble lands fully visible just before the keyboard finishes hiding. Don't sequence them — let them run concurrently. ## Timeline The driver consumes an array of events. Each event has `{ t: <seconds>, kind, target?, value? }`. | Kind | Meaning | Notes | |---|---|---| | `composer-type` | Type chars over a duration | `{ text, dur_sec }`. Caret remains visible. SFX = one key-tap per word boundary. | | `composer-clear` | Wipe composer text instantly | Used after send-tap | | `keyboard-show` | Set keyboard `data-state="shown"` + stage `data-keyboard-shown="1"` | CSS handles the slide | | `keyboard-hide` | Set keyboard `data-state="hidden"` + clear `data-keyboard-shown` | CSS handles the slide | | `send-tap` | Pulse send button (scale 0.9 → 1.0 over 120ms) | SFX = send-tap | | `pop` | Flip a row from `data-pending="1"` → `pop-now` class | `{ target: <msg-id> }` | | `header-swap` | Set header `right[data-active]` to `"primary"` or `"alt"` | `{ value: "alt" }` | | `loading-dot-show` | Pop the loading-dot row | `{ target: <dot-id> }` | | `loading-dot-hide` | Hide the loading-dot row | `{ target: <dot-id> }` | | `send-state` | Switch composer send button class to `disabled / active / streaming` | `{ value: "streaming" }` | | `stream-words` | Reveal an assistant message word-by-word | `{ target: <msg-id>, dur_sec, wps?: 7 }`. SFX = stream-tick every 12 words, response-done at the end. | | `scroll-to` | Smooth-scroll the conversation so a target row's bottom aligns with the visible-area bottom | `{ target: <msg-id>, dur_ms: 250 }` | Pacing for the canonical example (Q="Hey what's happening in this app?", short list response): ``` t=0.0 keyboard-show t=0.5 composer-type text="Hey what's happening in this app?" dur_sec=2.4 t=3.2 send-tap t=3.20 pop target=msg-user-1 t=3.20 composer-clear t=3.20 header-swap value="alt" t=3.20 keyboard-hide t=3.20 send-state value="streaming" t=3.55 loading-dot-show target=dot-1 t=4.10 loading-dot-hide target=dot-1 t=4.10 pop target=msg-assistant-1 t=4.15 stream-words target=msg-assistant-1 dur_sec=6.0 wps=7 t=4.50 scroll-to target=msg-assistant-1 t=10.5 send-state value="active" ``` Total: ~11s. Pad with a 1s hold at the end so the response can breathe before the cut. ## Workflow ### State 0 — Compose `thread.json` ```json { "statusBar": { "time": "9:41" }, "header": { "style": "plain-title", "title": "ChatGPT", "rightIcons": ["personPlus", "dottedCircle"], "rightIconsAlt": ["edit", "more"] }, "keyboard": { "layout": "qwerty-lower", "suggestions": ["I", "The", "I'm"], "state": "hidden" }, "messages": [ { "type": "user-text", "id": "msg-user-1", "text": "Hey what's happening in this app?", "popState": "pending" }, { "type": "loading-dot", "id": "dot-1", "popState": "pending" }, { "type": "assistant", "id": "msg-assistant-1", "stream": true, "popState": "pending", "feedback": false, "text": "Could you tell me what you mean by \"this app\"?\n\nIf you're referring to the ChatGPT app itself, I can explain:\n\n* How conversations work\n* Memory and personalization\n* Tools (web search, calendars, email, file analysis, image generation, etc.)\n* Why certain UI elements appear\n* What data is saved vs. not saved\n* How tasks/reminders work" } ], "composer": { "placeholder": "Ask ChatGPT" } } ``` ### State 1 — Record ```bash NODE_PATH=<repo>/create-chatgpt-mockup/node_modules \ node clips/record-master.js ``` Writes `master-chat.mp4` (no audio) and `master-chat.sfx.json` (the deterministic SFX cue list). ### State 2 — Stitch SFX onto the video ```bash bash edits/stitch.sh ``` Consumes `master-chat.sfx.json` and the four SFX wavs in `assets/sfx/`. Writes `master-final.mp4`. ### State 3 — Export variants **HARD RULE: never export a width×height whose ratio differs from the master's 750:1624 (≈0.4618).** `scale=1080:1920` (16:9) on this format stretches the UI ~22% horizontally — this shipped once (2026-06-11, Alitu) and reads as "fat" iPhone chrome immediately. The 9:16-tagged deliverable is either the native master or an aspect-true upscale; only the 1×1 crop changes shape (by cropping, never by scaling). ```bash # 9:16-tagged deliverable — aspect-true upscale (1080×2338 keeps 750:1624 exactly). # Shipping the native 750×1624 master unscaled is equally fine. ffmpeg -y -i edits/master-final.mp4 -vf "scale=1080:-2:flags=lanczos" \ -c:v libx264 -pix_fmt yuv420p -c:a copy -movflags +faststart \ meta-upload/master-9x16-1080.mp4 # 1×1 — CROP a square from the master (centered on the chat zone; adjust y to # frame the response), then upscale. Cropping changes shape legitimately; scaling must not. ffmpeg -y -i edits/master-final.mp4 -vf "crop=750:750:0:437,scale=1080:1080:flags=lanczos" \ -c:v libx264 -pix_fmt yuv420p -c:a copy -movflags +faststart \ meta-upload/master-1x1-1080.mp4 ``` ### State 4 — Self-QC with /watch Per project rule (`CLAUDE.md` #3), always `/watch:watch master-final.mp4` and confirm: - Keyboard is visible the whole time the user is typing - Send tap → bubble + keyboard-down + header-swap happen in one beat - One gray dot for ~500ms (not three) - Words fade in left-to-right, top-to-bottom - No OpenAI spiral logo appears before any assistant message title (the spiral only belongs in the empty-state hero — `renderAssistant` should not emit it) - No SFX on the loading dot - No micro-flicker / scene cuts ## Output ``` <output_folder>/ thread.json # the script as data clips/ record-master.js # adapted from this skill's template master-chat.mp4 # ~12s continuous chat recording (silent) master-chat.sfx.json # deterministic SFX cue list edits/ stitch.sh # adapted from this skill's template master-final.mp4 # 750×1624 (native ~9:19.5), h.264 meta-upload/ master-9x16-1080.mp4 # 1080×2338 aspect-true upscale (or ship the native master) master-1x1-1080.mp4 # square CROP of the master, then upscale ``` ## Quality Checks Run these before declaring the ad shippable. Most map directly to the State 4 `/watch:watch` pass above. - [ ] **One continuous take** — no scene-by-scene boundaries or micro-flicker anywhere in the chat; the whole thing is a single Playwright recording (`master-chat.page.html` rendered once, timeline walked on `requestAnimationFrame`). - [ ] **Keyboard is up the entire time the user is typing** and only slides down on the send-tap beat. It must never be visible while the assistant response is streaming (`keyboard-hide` fires at the same `t` as `send-tap`). - [ ] **Send-tap is one beat, not three** — the user bubble pop, the keyboard slide-down, and the header right-cluster swap (`personPlus/dottedCircle` → `edit/more`) all land on the same frame. Pulling them apart reads as glitchy. - [ ] **Exactly one gray loading dot** holds for ~500ms before streaming — not three (three dots reads as an iMessage typing indicator, wrong app), and no SFX on the dot (silent state change). - [ ] **Response streams word-by-word**, left-to-right then top-to-bottom, with the soft opacity ramp — never character-by-character and never all-at-once (the assistant message has `stream: true` so the atom pre-wraps every word in a `.word[data-stream]` span). - [ ] **Conversation auto-scrolls** so the streaming response stays in view — a `scroll-to` after the assistant pop and a mid-stream scroll around the halfway mark. - [ ] **No OpenAI spiral logo** appears above any assistant message title (the spiral belongs only to the empty-state hero). - [ ] **Master dimensions are 750×1624** (modern iPhone Pro ~9:19.5 — the atom's native viewport with `deviceScaleFactor: 2`), h.264, and the 9:16 / 1×1 variants are present under `meta-upload/`. Confirm with `ffprobe -v error -show_entries stream=width,height -of default=nw=1 edits/master-final.mp4`. - [ ] **Every export preserves the master's aspect ratio** (w/h ≈ 0.4618; the 1×1 crop is the only legitimate shape change). `ffprobe` each file under `meta-upload/` and do the division — a 1080×1920 output from this format is ALWAYS a horizontal stretch (live incident 2026-06-11, Alitu). - [ ] **Audio matches the intent.** By default the molecule is **silent**: `master-chat.sfx.json` contains `{"cues": []}` and `master-final.mp4` is a stream-copy of the silent master (no audio track is expected). If you opted into the subliminal SFX pass, every cue must sit at the bundled level (key-tap -28dB, send-tap -20dB, stream-tick -32dB, response-done -22dB), with **no cue on the loading dot**, and audio should peak at 0dB after stitch's `volume=2.5,alimiter` pass. ## Failure Modes | Symptom | Cause | Fix | |---|---|---| | Keyboard visible during streaming | Forgot `keyboard-hide` at send-tap | Add the event at the same t as `send-tap` |
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen