From ece0d5738867935fc893cd2958786c1fb55bc9df Mon Sep 17 00:00:00 2001 From: luna Date: Mon, 25 May 2026 09:49:01 +0000 Subject: [PATCH] Initial skill: tiktok-video-review with 14-frame extraction workflow --- SKILL.md | 49 +++++++++++++++++++++++++ _meta.json | 5 +++ scripts/extract-frames.sh | 76 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 SKILL.md create mode 100644 _meta.json create mode 100755 scripts/extract-frames.sh diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..575369a --- /dev/null +++ b/SKILL.md @@ -0,0 +1,49 @@ +--- +name: tiktok-video-review +description: Download a TikTok video, extract evenly distributed frames (default 14), and inspect content quickly. +--- + +# tiktok-video-review + +Use this skill when someone wants you to actually look inside a TikTok video instead of only reading metadata. + +## Goal + +Get a fast visual understanding of a TikTok by extracting evenly distributed frames across the full video. + +Default assumption: +- `14` frames across the entire video. + +## Required tools + +- `yt-dlp` +- `ffprobe` +- `ffmpeg` + +If missing, install before proceeding. + +## Workflow + +1. Download the TikTok URL to a local mp4. +2. Read duration with `ffprobe`. +3. Extract `14` evenly spaced frames using the helper script. +4. View the extracted frames and summarize what happens in the video. + +## Commands + +```bash +# 1) Download +yt-dlp -o /tmp/tiktok_review.mp4 "" + +# 2) Extract 14 frames across duration +skills/tiktok-video-review/scripts/extract-frames.sh \ + --input /tmp/tiktok_review.mp4 \ + --outdir /tmp/tiktok_review_frames \ + --count 14 +``` + +## Notes + +- Keep frame extraction uniform across the timeline, not clustered at the start. +- If the video is very short, still aim for the requested count and accept near-duplicate moments. +- Always state clearly that the summary is based on sampled frames, not full per-frame playback. diff --git a/_meta.json b/_meta.json new file mode 100644 index 0000000..dd97fd3 --- /dev/null +++ b/_meta.json @@ -0,0 +1,5 @@ +{ + "ownerId": "local", + "slug": "tiktok-video-review", + "version": "1.0.0" +} diff --git a/scripts/extract-frames.sh b/scripts/extract-frames.sh new file mode 100755 index 0000000..608c8c9 --- /dev/null +++ b/scripts/extract-frames.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +set -euo pipefail + +INPUT="" +OUTDIR="" +COUNT="14" + +while [[ $# -gt 0 ]]; do + case "$1" in + --input) + INPUT="$2" + shift 2 + ;; + --outdir) + OUTDIR="$2" + shift 2 + ;; + --count) + COUNT="$2" + shift 2 + ;; + *) + echo "Unknown arg: $1" >&2 + exit 1 + ;; + esac +done + +if [[ -z "$INPUT" || -z "$OUTDIR" ]]; then + echo "Usage: $0 --input --outdir [--count 14]" >&2 + exit 1 +fi + +if [[ ! -f "$INPUT" ]]; then + echo "Input file not found: $INPUT" >&2 + exit 1 +fi + +mkdir -p "$OUTDIR" +rm -f "$OUTDIR"/frame_*.jpg + +DURATION="$(ffprobe -v error -show_entries format=duration -of default=nokey=1:noprint_wrappers=1 "$INPUT")" + +python3 - "$INPUT" "$OUTDIR" "$COUNT" "$DURATION" <<'PY' +import os +import subprocess +import sys + +inp, outdir, count_s, dur_s = sys.argv[1:] +count = max(1, int(count_s)) +duration = float(dur_s) + +if duration <= 0: + print("Invalid duration", file=sys.stderr) + sys.exit(1) + +# Centered uniform sampling across full duration. +step = duration / count +times = [min(duration - 0.01, (i + 0.5) * step) for i in range(count)] + +for idx, t in enumerate(times, start=1): + out = os.path.join(outdir, f"frame_{idx:02d}.jpg") + cmd = [ + "ffmpeg", "-y", + "-ss", f"{t:.6f}", + "-i", inp, + "-frames:v", "1", + "-q:v", "2", + out, + ] + subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + +print(f"Extracted {count} frames to {outdir}") +PY + +ls -1 "$OUTDIR"/frame_*.jpg