Skip to content
andrew.dunn.dev

Pinboard

Source

Pinboard is a Ken Burns-style video generator that composites photos as vintage Polaroid snapshots on a panoramic background and drifts a camera across them to music. Drop photos, a wide background image and some music into input/, get a 4K video back. It pairs with Playbill, which assembles a program’s clips and audio; both serve the film in Birthday at the Theater, and Pinboard makes the photo-wall segment.

The whole tool is one file, pipeline.py, on NumPy and Pillow with ffmpeg as a subprocess. Every tunable lives in a CONFIG dict at the top, and the six stages feed forward with no config files or database between them.

rendersCAMERA PATHwide establishing, zoom in, zig-zag meander, zoom outtwo backgrounds make a return trip with crossfaded audioSTAGE 1source scaninput/ photos, musicSTAGE 2backgroundspanoramas resizedSTAGE 3layoutPoisson, SAT, relaxSTAGE 4weatheringsepia, vignette, frameSTAGE 5compositepasted and rotatedSTAGE 6videoframes into ffmpegOUTPUT4K video
Six stages from photos to 4K wall video
  1. Source scan: photos, backgrounds and music under input/, each photo classed portrait or landscape.
  2. Backgrounds: one or two panoramas, resized to match when they differ.
  3. Layout: Poisson disk sampling places frames at a minimum spacing, SAT tests the rotated rectangles for overlap, and force relaxation pushes apart any that still touch.
  4. Weathering: desaturation, warm tint, sepia and vignette, then a Polaroid frame.
  5. Composite: every frame pasted onto the background at its own small rotation.
  6. Video: the canvas cropped at each frame’s camera position, resized to 4K and piped to ffmpeg as raw RGB.

The camera runs four phases, each a duration in CONFIG:

  • a static wide shot of the whole wall;
  • a smooth zoom in toward the left end;
  • a zig-zag meander through alternating waypoints, easing into a dwell at each;
  • a zoom out at the right end, a pan back left and a fade to black.

What a given wall needs is configuration, not code:

  • keepout_zones: boxes photos must not cover, empty by default;
  • badge_overlap_zone: one frame allowed into a keep-out zone so the layout reads as hand-placed, off by default;
  • title_lines: the end title card, a placeholder until set.

With two backgrounds the photos split evenly, the camera crosses the first left to right and the second right to left, and the first two music tracks crossfade at the transition, an optional third under the title card.

Pinboard renders a wall; cutting and muxing a program is Playbill’s job.