CtrlK
BlogDocsLog inGet started
Tessl Logo

andrebrov/broll-sourcing

Drop in one talking-head video and get it finished — transcribe it, search the web for supporting b-roll (article screenshots, memes, images, video clips), present the asset list for approval, then hand off to reel-builder to normalize audio, burn subtitles, cut the b-roll in, and export for Instagram and LinkedIn. Use when the user drops a video and wants illustrations/screenshots/memes added, asks to "edit this like CapCut", wants b-roll found for them, or wants a talking-head take prepped for Instagram/LinkedIn. Sourcing and approval only — all rendering belongs to the reel-builder skill.

74

Quality

93%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

cut_boundaries.pyscripts/

#!/usr/bin/env python3
"""Turn rough cut ranges into word-safe ones.

The single most damaging bug in this pipeline: boundaries taken from Whisper
segment edges sit flush against speech, and render_reel.py applies a 30ms audio
fade at every cut to prevent pops — so the fade lands on the word and the take
sounds like it is swallowing syllables. Measured once: 3 of 12 boundaries cut
mid-word, most of the rest within 40ms.

This moves every boundary to the middle of the silence between words, keeping
the same words, and refuses to emit a boundary that clips one.

Usage:
  cut_boundaries.py words.json --ranges "3.1:22.5,25.2:39.7" --out plan/keeps.json
  cut_boundaries.py words.json --ranges-file rough.json --margin 0.15
  cut_boundaries.py --selftest
"""
import argparse, json, sys

MARGIN = 0.12


def load_words(path):
    d = json.load(open(path))
    if "segments" in d:
        return [w for s in d["segments"] for w in s.get("words", [])]
    return d["words"]


def text_of(w):
    return (w.get("word") or w.get("text") or "").strip()


def safe_range(words, a, b, margin=MARGIN):
    """Widen/narrow (a,b) so it lands in silence and keeps the same words."""
    inside = [w for w in words if w["end"] > a and w["start"] < b]
    if not inside:
        return None
    first, last = inside[0], inside[-1]
    prev = max((w for w in words if w["end"] <= first["start"]), key=lambda w: w["end"], default=None)
    nxt  = min((w for w in words if w["start"] >= last["end"]),  key=lambda w: w["start"], default=None)
    lo = first["start"] - margin
    if prev:
        lo = max(lo, (prev["end"] + first["start"]) / 2)
    hi = last["end"] + margin
    if nxt:
        hi = min(hi, (last["end"] + nxt["start"]) / 2)
    return round(max(0.0, lo), 3), round(hi, 3)


def clips_a_word(words, t):
    return [w for w in words if w["start"] < t < w["end"]]


def selftest():
    W = [{"start":1.0,"end":1.4,"text":"one"}, {"start":1.5,"end":1.9,"text":"two"},
         {"start":3.0,"end":3.4,"text":"three"}, {"start":3.5,"end":3.9,"text":"four"}]
    # a range starting mid-word is pulled back into the preceding silence
    lo, hi = safe_range(W, 1.2, 1.95)
    assert not clips_a_word(W, lo) and not clips_a_word(W, hi), (lo, hi)
    assert lo < 1.0 and hi >= 1.9, (lo, hi)
    # the gap between "two" and "three" is 1.1s, so both sides get full margin
    lo, hi = safe_range(W, 0.9, 2.0)
    assert abs(lo - 0.88) < 0.01 and abs(hi - 2.02) < 0.01, (lo, hi)
    # a boundary is never placed inside a word, whatever is asked for
    for a, b in [(1.1,1.6), (1.05,3.2), (0.0,4.0)]:
        lo, hi = safe_range(W, a, b)
        assert not clips_a_word(W, lo) and not clips_a_word(W, hi), (a, b, lo, hi)
    # a range containing no words is refused rather than guessed
    assert safe_range(W, 2.2, 2.6) is None
    print("ok")


def main():
    ap = argparse.ArgumentParser(description=__doc__,
                                 formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("words", nargs="?")
    ap.add_argument("--ranges", help="comma-separated a:b pairs")
    ap.add_argument("--ranges-file", help="JSON list of [a,b] pairs")
    ap.add_argument("--margin", type=float, default=MARGIN)
    ap.add_argument("--out", default="plan/keeps.json")
    ap.add_argument("--selftest", action="store_true")
    a = ap.parse_args()
    if a.selftest:
        return selftest()
    if not a.words or not (a.ranges or a.ranges_file):
        ap.error("need words.json and --ranges or --ranges-file")

    words = load_words(a.words)
    rough = (json.load(open(a.ranges_file)) if a.ranges_file else
             [[float(x) for x in p.split(":")] for p in a.ranges.split(",")])

    out = []
    for lo, hi in rough:
        r = safe_range(words, lo, hi, a.margin)
        if r is None:
            sys.exit(f"range {lo}-{hi} contains no words — check the timings")
        out.append(list(r))
        first = next(w for w in words if w["end"] > r[0] and w["start"] < r[1])
        last  = [w for w in words if w["end"] > r[0] and w["start"] < r[1]][-1]
        print(f"  {lo:7.2f}-{hi:<7.2f} -> {r[0]:7.3f}-{r[1]:<7.3f}  "
              f"{text_of(first)!r} .. {text_of(last)!r}", file=sys.stderr)

    bad = [t for lo, hi in out for t in (lo, hi) if clips_a_word(words, t)]
    if bad:
        sys.exit(f"REFUSING: {len(bad)} boundary/ies still clip a word: {bad}")
    json.dump(out, open(a.out, "w"))
    print(f"{len(out)} ranges, {sum(b-a for a,b in out):.2f}s, 0 clipped words -> {a.out}",
          file=sys.stderr)


if __name__ == "__main__":
    main()

SKILL.md

tile.json