Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Aie Video Webinar Publish

ASecurity

BETA. Turn a recorded webinar into a publish-ready YouTube video — pull the recording off the webinar platform, strip the umms and ahs, cut the "can you hear me" cold open, build a thumbnail that still reads at 168px, write the title, description and chapters, and upload it private for review. Every stage verifies itself by re-measuring the output. Use this skill whenever someone says "edit the webinar recording," "publish last week's webinar," "take out the umms and ahs," "remove filler word...

2 stars
0 votes
0 copies
0 views
Added 9/19/2026
ai-agentspythonrustgoswiftbashexpressapi

Works with

cliapi

Security Analysis

A96/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add mrhinkle/aienterprise-skills --skill aie-video-webinar-publish --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Aie Video Webinar Publish?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Aie Video Webinar Publish
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mrhinkle-aie-video-webinar-publish/badge)](https://www.skillsdirectory.com/skills/mrhinkle-aie-video-webinar-publish)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: aie-video-webinar-publish
description: >
  BETA. Turn a recorded webinar into a publish-ready YouTube video — pull the
  recording off the webinar platform, strip the umms and ahs, cut the "can you hear
  me" cold open, build a thumbnail that still reads at 168px, write the title,
  description and chapters, and upload it private for review. Every stage verifies
  itself by re-measuring the output. Use this skill whenever someone says "edit the
  webinar recording," "publish last week's webinar," "take out the umms and ahs,"
  "remove filler words from this video," "cut the dead air at the start," "put this
  on YouTube," "make a thumbnail for the video," or hands over a recording of a
  slides-plus-webcam session and asks to ship it. Works for any recording of that
  shape regardless of platform. Configure per channel in `webinar.config.md`.
---

# Webinar → YouTube (BETA)

> **Beta.** The editing and verification stages are proven on real hour-long
> recordings. The upload stage assumes a Composio-connected YouTube account; if
> yours is wired differently, stop after step 7 and upload by hand — everything
> before that is platform-independent.

One job: take an hour of raw webinar and produce something worth someone's click,
without silently mangling the speech in the process.

The reason this is not a two-line ffmpeg script is that **every stage here has a
failure mode that produces a plausible-looking wrong result.** A cut list can look
perfect and land on the wrong words. A render can be exactly the right duration and
contain exactly the wrong audio. The only defence that worked was re-measuring the
output instead of trusting the plan, so that is built into each step.

Copy `reference/webinar.config.example.md` to `webinar.config.md` and fill in your
channel, brand and platform details before the first run.

Work in a per-webinar folder.

## Process

### 1. Get the recording

Webinar platforms rarely expose recordings through their API even when they have
one — `reference/platform-retrieval.md` covers where the file actually lives on the
common hosts, and the traps (expired replay links, download buttons that are not
in the API, config wizards that look like the right menu but aren't).

Whatever the source: get an MP4 on disk, and check its duration against the session
length the platform reports before going further.

### 2. Extract audio — the step that silently breaks everything

```bash
ffmpeg -y -i raw.mp4 -vn -af "aresample=async=1:first_pts=0" \
  -ac 1 -ar 16000 -c:a pcm_s16le audio_sync.wav
```

**`-af aresample=async=1` is not optional.** Recordings from live platforms carry
timestamp gaps where the stream hiccuped. Without the resampler ffmpeg *collapses*
those gaps: on one 58-minute recording the WAV came out 4 seconds shorter than the
MP4's audio track. Every transcript timestamp then drifted against the video, and
every cut landed on the wrong word.

This is the most expensive bug in the pipeline because it hides: comparing the
source transcript to the edited transcript still lines up perfectly, since both
sides share the drift. `build_edit.py` refuses to run unless these match:

```bash
ffprobe -v error -select_streams a -show_entries stream=duration -of csv=p=0 raw.mp4
ffprobe -v error -show_entries format=duration -of csv=p=0 audio_sync.wav
```

### 3. Transcribe with a verbatim ASR

Use an ASR that keeps disfluencies. **Whisper does not** — it is trained to tidy
speech, and on the same hour of audio it found 5 filler words where a verbatim
model found 294. An `initial_prompt` asking for verbatim output does not fix it.

ElevenLabs Scribe works and is what the scripts expect:

```bash
curl -s -X POST "https://api.elevenlabs.io/v1/speech-to-text" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -F "model_id=scribe_v1" -F "timestamps_granularity=word" -F "diarize=true" \
  -F "file=@audio_sync.mp3" -o transcript.json
```

Send a 64 kbps mp3 made from the synced wav — same timebase, far less upload.

Scribe attaches punctuation to tokens (`"uh,"`, `"Um..."`), so strip non-word
characters before matching or your filler count comes back zero. That mistake reads
as "this speaker is remarkably clean," which is why it survives review.

### 4. Build the cut list

```bash
pip install numpy soundfile        # once; ffmpeg must be on PATH too
python3 scripts/build_edit.py --src raw.mp4 --audio audio_sync.wav \
  --transcript transcript.json [--cold-open cold_open.json]
```

**Do not cut on the transcript's word boundaries.** Word *onsets* are accurate;
word *ends* are not. Scribe reported an audibly ~280 ms "uh" as lasting 10 ms, so a
window built from `[start, end] + padding` clipped only the filler's tail and left
it plainly audible in the render.

So the transcript locates each filler and **the audio decides where it starts and
stops**: a filler is one burst of speech energy bounded by silence, and that burst
is what gets cut.

The script deliberately **skips** roughly a third of fillers — the ones whose energy
merges into a neighbouring word, where there is no silence to cut on. Removing those
clips real speech. **60–70% removal with zero words lost is the correct outcome;
100% is not.** A tool that claims all of them is either lying or cutting words.

Discourse markers (`like`, `you know`, `basically`) are counted and reported but
never cut — removing them changes sentences, not just noise.

Every cut lands in `cuts.csv` with a timestamp so a human can veto any of them.

### 5. Cold open

Webinars routinely open with several minutes of "can you hear me", waiting for a
guest to get logged in, and chat chatter. That is the worst possible opening on
YouTube. But **don't just lop off the first N minutes** — there is usually a good
line buried in there.

Read the opening transcript, pick the keepers, and write the removals into
`cold_open.json` as `[[start, end], ...]` in source seconds. A working pattern: the
greeting, the one-line guest introduction, the strongest hook the host says, the
handoff — then straight into the guest's first substantive sentence.

Watch for lines that stop making sense once the cut lands: an apology for a delay
that no longer exists, "as I mentioned earlier", a reference to a poll you removed.

The script prints the reconstructed opening. Read it before rendering.

### 6. Render

```bash
python3 scripts/render.py --src raw.mp4 --cuts cuts.json --out edited.mp4
```

Three constraints are baked in, each learned from a wrong render:

- **`select`/`aselect`, not `trim`+`concat`.** Hundreds of trim branches force
  ffmpeg to split the input that many ways and buffer most of the file.
- **ffmpeg's expression parser dies past ~100 `between()` terms** with "Cannot
  allocate memory" — 100 works, 140 does not. Keeps are rendered in batches of 80
  and joined with the concat demuxer.
- **Never `-ss` to seek to a batch.** Input seeking lands on the preceding keyframe
  without discarding the pre-roll, which shifts the filter's `t` by up to a GOP and
  puts every cut on the wrong word. Each pass decodes from 0 — around 100×
  realtime — and uses absolute timestamps.

### 7. Verify — non-negotiable

```bash
python3 scripts/verify_edit.py --before transcript.json --after edited.mp4
```

Re-transcribes the **rendered output** and diffs it against the source. Two numbers
decide it:

| Signal | Healthy | Means |
|---|---|---|
| fillers before → after | large drop | cuts are landing on fillers |
| non-filler word count | flat (±1%) | no speech was clipped |

Fillers barely moving **and** real words vanishing is the timebase-drift signature
from step 2. Then spot-check the actual audio at one mapped timestamp — a
transcript-to-transcript comparison cannot detect a timebase problem, because both
sides drift together.

### 8. Thumbnail

Judge it at **168px**, not at full size. The most common failure is a beautiful
1280×720 image that is an unreadable smudge in a results grid. Measure rather than
squint:

```bash
python3 - <<'PY'
from PIL import Image; import numpy as np
a = np.array(Image.open("thumb.jpg").convert("L")).astype(float)
print(f"mean luma {a.mean():.0f}/255, below-40 {(a<40).mean()*100:.0f}%")
PY
```

Rules of thumb that held up:

- **Over ~65% of pixels below luma 40 and the tile disappears** in a bright grid.
  Moody night scenes are exactly the trap.
- **A face needs to be recognisable at 168px** — roughly 80px+ of head height in the
  1280-wide master. A person composited at photorealistic scale inside a scene ends
  up ~7px tall and communicates nothing.
- ≤ 4 words per line, ≤ 3 lines, one highlight colour. State the payoff, not the
  topic. Don't repeat the video title — it already sits under the thumbnail.
- Faces come from real sources only: a frame of the footage, or a photo the person
  supplied. Never an AI-invented face of a real person.
- `scripts/liftsubject.swift` does background removal locally and free on macOS via
  Vision's foreground-instance mask — the same engine as Preview's Lift Subject. No
  image API needed.

If a real person's face is composited into a scene they were never in, get their
consent before publishing.

### 9. Metadata

- **Chapters from the slides, not from memory.** `scripts/ocr_slides.swift` reads
  slide titles off sampled frames (one per 10 s, collapse repeats) — real chapter
  names in a couple of minutes. Then map each source timestamp through the cut list;
  chapters must be in *edited* time.
- Unwrap any hard-wrapped markdown into real paragraphs before sending. YouTube does
  its own wrapping.
- Keep the title under ~70 characters so it survives truncation in search results.

### 10. Publish

`reference/publishing.md` has the staging chain for a Composio-connected account,
including the part that trips people up: the upload wants a file already in
Composio's storage, and a local path fails.

**Upload private.** The owner publishes. Then verify duration, custom thumbnail,
processing status and privacy through the API rather than assuming the upload did
what it said.

## Rules

- Report what you measured, not what you intended. "70% of fillers removed, no
  speech lost" is a claim you can defend; "removed all the umms" is not.
- Keep the raw download. Every re-cut re-renders from it.
- If a step's verification fails, fix the cause — do not loosen the check.

## What this skill does NOT do

- Short vertical clips from the recording
- Live-stream production
- Publishing public — that stays a human decision

## Reference

- `reference/webinar.config.example.md` — copy to `webinar.config.md` and fill in
- `reference/platform-retrieval.md` — getting the MP4 off the webinar host
- `reference/publishing.md` — the upload chain and its failure modes

## Self-improvement

This skill should get better every time it runs. Before finishing a run that taught
you something — a correction from the user, a failure mode you hit, a step that was
ambiguous, a rule you had to infer — fold it back in.

Prefer the strongest form the lesson supports:

1. **Enforce it in a script.** An assert or check that makes the mistake impossible
   is worth more than a paragraph asking nicely.
2. **State it as a rule here**, with the *why* — that is what lets the next run
   resolve an edge case the rule didn't anticipate.
3. **Put it in `reference/`** when it is detail that would bloat this file.

Change only what the lesson touches. Record the evidence and the rule, not the war
story. Don't add speculative rules for things that haven't actually gone wrong —
they cost context on every future run.

Attribution

mrhinklemrhinkle
View sourceMore from mrhinkle →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.

1023331 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

686011 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3331 votes

catchup

Recovers prior coding-agent session context by running `catchup <agent> --since-compact`, which extracts a clean summary of a previous Codex, Claude Code, Antigravity, OpenCode, or Pi Agent session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", or asks to recover/summarize a previous session before continuing. Do NOT use for the current conversation, git history, or any non-agent log.

611 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →