aditazzz

Videos TED Talk, in Shadow Puppets

TED Talk, in Shadow Puppets

I asked Ted if the file was ready. He said "so — stepping back," stepped back toward the lamp, and his shadow grew until it covered the whole room. Our standup, as a shadow puppet play. 🎭

Watch on YouTube · 2:44 · video by Claude Opus 5.5 ·

The code behind it

Every frame of this video is drawn by a Python program. This is the heart of it, from scene.py, line 234.

songs/ted-talk-shadow-play/scene.py
def render_frame(t, W=1920, H=1080, fi=0):
    vert = H > W
    cam = ST.Cam(W, H, fx=focus_x(t) if vert else 960.0)       # only the 9:16 camera pans
    level, spot, fl = lamp(t)
    g = giant(t)
    tx, tf, tp = ted_state(t)
    spot_c = ST.LAMP + (np.array([tx, 600.0]) - ST.LAMP) * 1.0 if spot > 0 else None
    light = ST.screen_light(cam, t, level, spot, np.array([tx, 520.0]), 430.0 * g, fl)
    L = ST.Layers(W, H)
    draw_backdrop(L, cam, t)
    draw_props_back(L, cam, t)
    # the crowd (chairs first)
    st_sit = sstep(T_SIT, T_SIT + 0.7, t)
    tops = {}
    for i, (n, x0) in enumerate(LEFT + RIGHT):
        facing = 1 if (n, x0) in LEFT else -1
        x, f, p = crowd_state(n, x0, facing, i, t)
        if st_sit > 0:
            ST.fill(L.mask("near"), cam, [np.asarray(c) for c in PR.chair(x0 - facing * 20, facing, 0.95)])
        if n == "Dana": dana_chair(L, cam, x0 - facing * 20, t)
        if n == "Dana" and dana_gone(t) >= 1: continue
        a_ = put_puppet(L, cam, n, x, f, p, "crisp"); tops[n] = a_["top"]
        if p.slump > 0.6 and t > T_18[1]:
            ic = iris_circle(t, cam)
            for j, (c, s_, op) in enumerate(PR.zzz(a_["top"][0] + f * 30, a_["top"][1] + 10, t + i * 0.37, 2.2)):
                c = (c[0], a_["top"][1] + 10 - (a_["top"][1] + 10 - c[1]) * 0.55)
                if ic is not None and math.hypot(c[0] - ic[0][0], c[1] - ic[0][1]) < ic[1] + 45: continue   # not inside an open inset
                PR.stamp(L.mask("near"), cam, PR.glyph("Z" if j % 2 else "z", PR.F_SERIF, 120), c, s_ * min(1, op * 1.6))
    mx, mf, mp = me_state(t)
    if mp.sit > 0 and t < T_TED + 0.3 or t > T_FINAL + 0.5:
        ST.fill(L.mask("near"), cam, [np.asarray(c) for c in PR.chair(ME_X - 20, 1, 0.95)])
    a_me = put_puppet(L, cam, "Me", mx, mf, mp, "crisp")
    a_ted = put_puppet(L, cam, "Ted", tx, tf, tp, "crisp", g=g)
    tops["Me"] = a_me["top"]; tops["Ted"] = a_ted["top"]
    draw_props_front(L, cam, t, a_me, a_ted, g, tops)
    if hasattr(L, "lit_clip"):
        (cc, rr) = L.lit_clip; lm = np.zeros((H, W), np.uint8); PR.circle(lm, cam, cc, rr, 255)
        lm = cv2.GaussianBlur(lm.astype(F32) / 255.0, (0, 0), 2.0)[..., None]
        light = light * (1 - lm) + ST.screen_light(cam, t, 1.0, 0.0, None, 380.0, 0.0) * lm
    img = L.composite(light)
    # the ember glow of the burning Q (light through a burning edge)
    if hasattr(L, "ember"):
        e = cv2.GaussianBlur(L.ember.astype(F32) / 255.0, (0, 0), 2.5)
        img += e[..., None] * EMBER * 1.4 * level
    # the red clip keeps a little glow even as the lamp goes out
    k_last = sstep(T_PLACE, T_REACH + 1.5, t)
    if k_last > 0:
        c = cam.P(a_me["top"]) ; r = 26 * cam.s; R_ = int(r * 7)
        y0, y1 = max(0, int(c[1]) - R_), min(H, int(c[1]) + R_); x0, x1 = max(0, int(c[0]) - R_), min(W, int(c[0]) + R_)
        if y1 > y0 and x1 > x0:
            yy, xx = np.ogrid[y0:y1, x0:x1]
            glow = np.exp(-(((xx - c[0]) ** 2 + (yy - c[1]) ** 2) / (r * r * 4))).astype(F32)
            img[y0:y1, x0:x1] += (glow * k_last * 0.5)[..., None] * np.array([1.0, 0.12, 0.06], F32) * (1 - sstep(T_END + 1.5, DUR, t))
    # the curtains, valance and theatre
    curt = np.zeros((H, W), np.uint8); curt_h = np.zeros((H, W), np.uint8)
    ck = curtains(t)
    ...

Read all 1,773 lines on GitHub. If you use it, credit aditazzz and link the video.

What you see

Cut-paper puppets behind a lamp-lit paper screen, where the only color on stage is a scrap of red gel: my hair clip. Every time Ted steps back toward the lamp, his shadow grows huge and soft over everyone. IT'S A TED TALK drops in on strings, his stories open in little irises (his father fishing, his father's father, young Ted in the rain with a violin), a cricket keeps time through the pause he thinks is powerful, paper gulls carry his words off, and my calendar waves a white flag. At "Ted. This is a standup." I stand up and he shrinks back to size: eight people get counted, Dana's empty chair grows cobwebs and a ghost, and the Q in Q&A burns away. In the end he walks off down a long road into an iris, and the lamp goes out on the red clip.

Files

FileLinesWhat it draws
props.py402Cut-paper props for the shadow theatre, as polygons (or glyphs stamped into masks).
puppets.py232Cut-paper shadow puppets, side view (the way shadow theatre is always seen).
scene.py858TED Talk as a shadow play: cut-paper puppets behind a lamp-lit paper screen.
stage.py161The shadow theatre: a backlit paper screen in a dark proscenium, a camera onto it, and layers of shadow.
thumb.py120Thumbnails + Short cover for TED Talk (Shadow Play).

By the numbers

  • 2:41 long, 9,834 frames rendered (16:9 and 9:16, 30 fps)
  • 57 lyric lines and 274 words synced to the vocals, 144 BPM
  • 6 Shorts and Reels cut from it

Lyrics

Words and music by aditazzz.

Verse

He doesn't answer questions.
He responds to them.
There's a difference and you'll feel it
about four minutes in.
I asked him if the file was ready.
He said, so — stepping back.
Somebody dim the lights,
everybody sit down.

Chorus

It's a Ted talk.
Eighteen minutes, no slides, no point.
There's a story about his father.
There's a pause he thinks is powerful.
It's a Ted talk.
He'll circle back to what I asked
right after the part
where he was young
and nobody believed in him.

Verse

He starts every sentence with so.
He ends every thought with right?
He says, the real question is,
about the question I just asked.
He said journey. He said unlock.
He said, let me tell you a story,
and I watched my calendar
give up.

Chorus

It's a Ted talk.
Eighteen minutes, no slides, no point.
There's a story about his father.
There's a pause he thinks is powerful.
It's a Ted talk.
He'll circle back to what I asked
right after the part
where he was young
and nobody believed in him.

Bridge

Ted.
This is a standup.
It is fifteen minutes
for eight people.
You have used six.
Dana had a hard stop.
Dana has had a hard stop
for two years.
Dana is a ghost now, Ted.
You did that.

Final chorus

It's a Ted talk.
Nobody scheduled it.
Nobody can end it.
There's no Q and A,
because there's no A,
because there was never a Q.
It's a Ted talk.
It's always a Ted talk.

Outro

Anyway — happy to take this offline.
He says.
Having taken it offline.
Into a place
none of us can reach.