English · 한국어
Making the demo video¶
This folder is the source of truth for the demo video. It holds the tools and the text, not the video: everything that is generated goes to out/, which git ignores.
The video is silent. Terminal scenes are real recordings of the demo, with captions in a band below them. It can be made in English or in Korean. The cards (title, intro, section titles, closing) are HTML pages captured as images.
Three steps, three machines¶
Each step needs different software, so they are separate scripts.
| Step | Script | Run it where | Needs |
|---|---|---|---|
| 1. Record the terminal scenes | record.sh |
Where the demo runs (Docker) | asciinema, agg, ffmpeg, the five repositories side by side |
| 2. Capture the cards | cards.sh |
Anywhere with Chrome | headless Chrome, ffmpeg |
| 3. Assemble | build.py |
Anywhere with ffmpeg built with libass |
ffmpeg with the ass filter |
# 1. on the machine that runs the demo (the real-provider stage must have run once)
./demo/scripts/up.sh && DEMO_REAL_PROVIDER=1 ./demo/scripts/demo.sh
VIDEO_LANG=en VIDEO_VER=v0.10.1 demo/recording/record.sh # → out/clips/en/*.cast, *.mp4, PROVENANCE.txt
# 2. cards (copy demo/.generated/topology.svg over if this is another machine)
VIDEO_LANG=en VIDEO_VER=v0.10.1 SITE_URL=https://randyinthedev-hash.github.io/pqcota demo/recording/cards.sh
# 3. assemble (put out/clips and out/cards in the same out/ first)
demo/recording/build.py --lang en # → out/pqcota-demo.en.mp4 and friends
VIDEO_LANG (or --lang for build.py) picks the language: en or ko. Run the three steps once per language. Do not use LANG: it is the operating system's locale variable.
What comes out¶
pqcota-demo.<lang>.mp4: captions burned in, for direct sharing.pqcota-demo.<lang>.nocaps.mp4andpqcota-demo.<lang>.srt: the same video without captions, plus the captions as a file. Upload this pair to a site that shows captions itself, so they are not shown twice.pqcota-demo.<lang>.provenance.txt: how it was made (below).
How the pieces fit¶
record-take.sh(in../scripts/) runs one scene at a time against the running demo. It prints named markers, such asprovision.approve, that do not show on screen but are kept in the recording. A marker name means "the section that ends here".build.pyfinds the cuts by those names, not by seconds. Its scene table holds what is common to every language: the order of scenes, the speed, and where a still frame is taken. If you re-record and the seconds change, the table does not.lang/<lang>.jsonholds what depends on the language: how long a still stays, the caption text with its position, the caption font and the reading-speed limit. A position is a scene and seconds inside it, or@markerand seconds around that marker in the recording. Reading time differs between languages, so each language sets its own stills, holds and limit. The scene order and the anchors are the same in every language.lang/take.<lang>.shholds the commentary lines thatrecord-take.shprints between commands. English is the reference and the other languages are translations; the commands and the programs' own output stay English in every language.- The cards (
*-card.html,intro-slides.html,section-cards.html,topology-frame.html) hold both languages in one file, as<span class="en">and<span class="ko">.?lang=picks one, and English is the default. - Time rule. Seconds in the assembled video equal seconds in the
.castas long asaggdoes not shorten waiting time.record.shsets the idle limit to 60 seconds, andbuild.pystops if a recording has a silence that long or if the video length and the cast length disagree. - Two rules for editing. A still frame is taken at the end of its scene. If it were taken at the start, lines that were already printed would disappear and come back, which looks edited. Where a number changes (0 → 14), the clip is never sped up.
The record of how it was made¶
record.sh writes out/clips/<lang>/PROVENANCE.txt: the commit of each of the five repositories (and whether it is a release tag and whether the tree was clean), the tool versions, and the recording options. build.py adds the caption file's hash, the marker times and the scene times into pqcota-demo.<lang>.provenance.txt. The closing card shows the release tag the video was recorded from (VIDEO_VER); when the recorded commits are not that tag exactly, the provenance file shows how they differ.
Checking a rebuild¶
A rebuilt video is the same video when the scenes come in the same order, each scene shows the command that was run, the key outputs match (the provider chain with BC, the 0 → 14 → 0 counts, layersMissing), and the captions say the same things. Bytes will differ. A last check is to watch the whole video at normal speed once.
Adding a language¶
Add lang/<lang>.json and lang/take.<lang>.sh, and add the language's spans to each card. Then list the two new files in tools/checkprose/files.txt, so the prose check reads them (it reads .json as it is and .sh without comment lines).
Korean exists (ko). Its video differs from the 2026 August video in one way: the programs now print English, so the terminal output is English and only the commentary, the cards and the captions are Korean.