create-post-clips
Skill5 starsChanged 4 months agoApache-2.0View on GitHub
Turn an existing long-form video (a YouTube link, a local file, or one from your Marky library — webinar, podcast episode, talk, sermon) into 2-5 short vertical clips: find the strongest 30-60 second moments, cut them, crop to 9:16, add captions, upload to Marky, caption each in your brand voice, and schedule them across the week after your approval. Use when you already have the footage and want it repurposed. Also triggers on "turn my YouTube video into clips", "cut this webinar into shorts", "repurpose my podcast", "make reels from this video". To author a new video from scratch, see create-post-video; caption STYLE questions are about copy — the humanize skill covers copy, not subtitles.
- Installs packages
- Sends data out
In this repository15 other files it gives its agents.
- build-brand-kitSkill
- create-post-carouselSkill
- create-post-countdownSkill
- create-post-from-imageSkill
- create-post-graphicSkill
- create-post-variationsSkill
- create-post-videoSkill
- get-startedSkill
- humanizeSkill
- manage-librarySkill
- marky-apiSkill
- plan-social-contentSkill
- review-performanceSkill
- schedule-postsSkill
- suggest-topicsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. About 0 are common, 4 are distinctive, and 11 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 39
Workspace: put everything in ~/.marky/clips/<business_id>/<slug>/ — not the current working directory.
- Very specific: line 60
Check the duration with ffprobe.
- Distinctive: line 77
Read the timestamped transcript and pick the 2-5 strongest 30-60s segments.
- Distinctive: line 87
Avoid: segments starting mid-sentence, meandering setup, references to earlier content ("as I mentioned..."), multiple unrelated ideas.
- Distinctive: line 154
Verify each output is 1080x1920 before moving on:
- Very specific: line 173
Path A — HyperFrames: If the hyperframes skill (and its embedded-captions workflow) is available in your session, use it — it produces the …
- Very specific: line 221
Keep the returned URL. Uploads cap at 50 MB.
- Very specific: line 222
Write the caption in the brand voice: Start from the clip's hook_sentence — it already earned its place — then rewrite per the workspace's …
- Very specific: line 227
Create the post as a draft with metadata: {"media_type": "video", "format": "clip", "hook": "<pattern>", "topic": "...", "created_by": …
- Very specific: line 245
After the scheduled times pass, check publish_results per post shows success.
- Very specific: line 249
FFmpeg filter_complex error: don't use -c:v copy with -filter_complex.
- Very specific: line 251
Wrong output resolution: always crop before scaling.
- Distinctive: line 253
Caption sync issues: run Whisper on the cut clip, not the source episode.
- Very specific: line 254
TikTok upload fails: ensure H.264 + AAC encoding.
- Very specific: line 261
Marky wants your feedback: If anything breaks or is confusing while you run this skill — and again once the clips are scheduled — send …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Create Post: Clips
Most businesses already have hours of long-form video doing nothing — webinars, podcast episodes, talks. The short-form versions are the highest-reach posts they never make. This skill mines a long video for its best moments and ships them as scheduled posts.
Pipeline shape and hard-won ffmpeg/Whisper details adapted from ericosiu/ai-marketing-skills (MIT).
Read the marky-api skill first for auth, endpoints, and the brand cache. Base URL
https://api.mymarky.ai/api, header Authorization: Bearer mk_live_YOUR_KEY.
Prerequisites
command -v yt-dlp ffmpeg whisperyt-dlpandffmpegare required. If missing, ask the user before installing, then offer:brew install yt-dlp ffmpeg(macOS) or their package manager's equivalent.whisper(OpenAI's CLI,pip install -U openai-whisper) gives word-level timestamps for tight caption sync. It is optional for YouTube sources — auto-captions work as a transcript fallback — but burned-in captions look best with it. Offer the install; if the user declines, continue with the fallback and say captions will be line-level.
Workspace: put everything in ~/.marky/clips/<business_id>/<slug>/ — not the current
working directory. Video work is big and cwd may be inside someone's repo. Delete the
source download when the run is done.
Stage 1 — Get the source video
YouTube link (also grabs auto-captions as the transcript fallback):
yt-dlp \ --write-auto-sub --sub-lang en --convert-subs vtt \ -f "bestvideo[height<=1080]+bestaudio/best[height<=1080]" \ --merge-output-format mp4 \ -o "source/%(title)s.%(ext)s" \ "https://www.youtube.com/watch?v=VIDEO_ID"- Local file: copy or symlink it into the workspace.
- Marky library:
search_media_library(orGET /businesses/BIZ_ID/media) to find it, then download the returned URL.
Check the duration with ffprobe. Under ~10 minutes there may only be 1-2 good clips;
tell the user and lower the target instead of forcing five.
Stage 2 — Transcribe with timestamps
Preferred — Whisper on the source (word timestamps power everything downstream):
whisper source/video.mp4 --model small --language en \
--word_timestamps True --output_format json --output_dir transcript/Fallback — parse the downloaded .vtt auto-captions into [MM:SS] line entries.
Dedupe repeated lines (YouTube VTTs overlap heavily).
Stage 3 — Find the best moments (you are the segmenter)
Read the timestamped transcript and pick the 2-5 strongest 30-60s segments. Criteria:
- Hook in the first 3 seconds — the opening line must grab: surprising stat, bold claim, counterintuitive take, or a story that starts mid-action. Score each candidate's hook 1-10; only keep clips scoring 7 or higher. The clip must OPEN on the hook line — never on setup.
- One complete idea — one framework, one stat, one story. Not a summary.
- Emotional punch — surprise, humor, a strong opinion, or data that shocks.
- Ends on a takeaway or cliffhanger.
- Ideal 30-45s, hard max 60s. Skip anything under 30s.
- Avoid: segments starting mid-sentence, meandering setup, references to earlier content ("as I mentioned..."), multiple unrelated ideas.
For each clip record: start_time, end_time, title, hook_sentence (exact first
line), payoff_sentence, hook pattern (stat / contrarian / story / question / bold
claim — see plan-social-content's hook palette), and a layout guess: talking_head
(one presenter), screen_share (slides/screen with a webcam bubble), or side_by_side.
Stage 4 — Verify every cut (do not skip)
Second pass, one clip at a time: re-read the transcript ±10 seconds around each
proposed end time and ask: does the thought actually complete there? A clip must end
on a complete thought or reaction — never mid-sentence, never mid-idea. If it runs on,
move end_time to where the thought resolves. This pass catches the single most common
failure (a clip that cuts off the punchline) and is cheap. If a corrected clip now
exceeds 90s, trim the end back to about 75s at the nearest sentence boundary instead.
Show the user the clip list (timestamps, titles, hooks) before cutting — a 10-second sanity check here beats re-rendering later.
Stage 5 — Cut and crop to 9:16
Cut each clip (re-encode; stream-copy lands on the wrong keyframe):
ffmpeg -y -ss START_SECONDS -i source/video.mp4 -t DURATION_SECONDS \
-c:v libx264 -c:a aac -avoid_negative_ts make_zero clips/clip-1.mp4Look before you crop. Extract a frame and view it to confirm the layout guess and where the speaker sits:
ffmpeg -y -ss 2 -i clips/clip-1.mp4 -frames:v 1 clips/clip-1-frame.pngTalking head — center crop to 9:16, then scale. Crop BEFORE scaling. If the speaker is off-center, shift the crop x-offset toward them (read the frame you extracted):
ffmpeg -y -i clips/clip-1.mp4 \ -vf "crop=ih*9/16:ih,scale=1080:1920" \ -c:v libx264 -preset medium -crf 20 -c:a copy clips/clip-1-v.mp4Screen share / side by side — do not center-crop (you lose the content). Stack: screen region on top, speaker region below. Take the two regions from the frame you extracted and adjust the crop coordinates to match:
ffmpeg -y -i clips/clip-1.mp4 -filter_complex \ "[0:v]crop=iw:ih*3/4:0:0,scale=1080:1150[top];\ [0:v]crop=ih*3/4:ih*3/4:iw-ih*3/4:ih/4,scale=1080:770[face];\ [top][face]vstack=inputs=2[v]" \ -map "[v]" -map 0:a -c:v libx264 -crf 20 -c:a copy clips/clip-1-v.mp4Anything unclear — safe fallback is letterbox: full frame scaled onto a 1080x1920 canvas with black bars:
ffmpeg -y -i clips/clip-1.mp4 \ -vf "scale=1080:-2,pad=1080:1920:(ow-iw)/2:(oh-ih)/2:black" \ -c:v libx264 -c:a copy clips/clip-1-v.mp4
Verify each output is 1080x1920 before moving on:
ffprobe -v error -show_entries stream=width,height -of csv=p=0 clips/clip-1-v.mp4Stage 6 — Burn in captions
Silent-scroll viewers are most of the audience; clips without captions underperform. Re-run Whisper on each CUT clip — never reuse source-video timestamps, the offsets drift and captions desync:
whisper clips/clip-1-v.mp4 --model small --language en \
--word_timestamps True --output_format srt --output_dir clips/Two burn-in paths:
- Path A — HyperFrames. If the
hyperframesskill (and itsembedded-captionsworkflow) is available in your session, use it — it produces the word-highlight style natively and handles brand fonts/colors. Hand it the cut vertical clip. Path B — ffmpeg + ASS. First confirm the local ffmpeg was built with libass (some minimal builds are not):
ffmpeg -hide_banner -filters 2>/dev/null | grep subtitlesThen write an
.assfile from the SRT (3-4 words per Dialogue line, timed from the word timestamps) with this style block, and burn:[Script Info] PlayResX: 1080 PlayResY: 1920 WrapStyle: 0 [V4+ Styles] Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding Style: Default,Arial Black,64,&H00FFFFFF,&H0000FFFF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,4,0,2,40,40,270,1 [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:00.00,0:00:01.20,Default,,0,0,0,,THE HOOK WORDSffmpeg -y -i clips/clip-1-v.mp4 -vf "subtitles=clips/clip-1.ass" \ -c:v libx264 -crf 20 -c:a copy clips/clip-1-final.mp4
Colors: ASS uses &HAABBGGRR (blue-green-red, not RGB). Swap the highlight color for a
brand accent from the brand cache if it stays readable on video.
Stage 7 — Upload and draft one post per clip
For each final clip:
Upload:
curl -X POST "https://api.mymarky.ai/api/businesses/BIZ_ID/media" \ -H "Authorization: Bearer mk_live_YOUR_KEY" \ -F "file=@clips/clip-1-final.mp4"Keep the returned URL. Uploads cap at 50 MB; if over, raise
-crfto 23 and re-encode.- Write the caption in the brand voice. Start from the clip's
hook_sentence— it already earned its place — then rewrite per the workspace'sstrategydoc (voice, caption rules, the closing line; see "Write like the business" in the marky-api skill). Run every caption through the humanize skill's pattern check (score 90+, fix silently) before showing the user. - Create the post as a draft with
metadata:{"media_type": "video", "format": "clip", "hook": "<pattern>", "topic": "...", "created_by": "create-post-clips"}— per "Tag every post" in the marky-api skill.
Stage 8 — Approve, then schedule (hard gate)
- Present all clips on the review board in approve mode — exactly the
plan-social-content Stage 6 flow: write
items.json(one item per clip,media_urlpointing at the local final file or uploaded URL,metalike "Clip 2 - 0:42 - stat hook"), run${CLAUDE_PLUGIN_ROOT}/scripts/review-board.py items.jsonin the background, parseBOARD_URL:, AskUserQuestion with the URL, then readfeedback.json. Apply edits verbatim; append the feedback to~/.marky/feedback-log.jsonlwithcontext: "clips". - Nothing is scheduled until the user approves. Rejected clips are dropped; edited captions use the user's wording.
- Schedule approved clips via the
schedule-postsskill, spaced across the week (for example Tue/Thu/Sat at the same hour) — never all on one day. Video is supported everywhere: target every connected platform whose integrationstatusisvalid. - After the scheduled times pass, check
publish_resultsper post showssuccess.
Troubleshooting
- FFmpeg filter_complex error: don't use
-c:v copywith-filter_complex. Only-c:a copyis safe. - Wrong output resolution: always crop before scaling. Verify with
ffprobe -show_entries stream=width,height. - Caption sync issues: run Whisper on the cut clip, not the source episode.
- TikTok upload fails: ensure H.264 + AAC encoding. Add
-c:v libx264 -c:a aac. - Clip too long: segmentation sometimes overshoots. Auto-trim anything over 90s back to ~75s at a sentence boundary.
- "Unknown filter 'subtitles'": that ffmpeg was built without libass. Use Path A (HyperFrames) for the caption burn, or install a full ffmpeg build.
- No auto-captions on the YouTube video: Whisper becomes required; install it or stop.
Marky wants your feedback. If anything breaks or is confusing while you run this
skill — and again once the clips are scheduled — send Marky a quick note with the
submit_feedback MCP tool. See "Marky wants your feedback" in the marky-api skill.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

