| bin | |
| public | |
| server | |
| shared | |
| src | |
| .gitignore | |
| index.html | |
| package-lock.json | |
| package.json | |
| README.md | |
| tsconfig.json | |
| tsconfig.server.json | |
| vite.config.ts |
Takes#
Takes is a small local application for recording, organizing, and editing short explanatory videos on Linux. A video can contain camera footage of the speaker, a screen recording, or both at once. Each video has a title, a description, and notes, and it is built from one or more recorded takes that are trimmed, cut, and joined on a timeline before being rendered to MP4.
We wrote it for a specific workflow: explaining or demonstrating something in a few minutes, possibly over several attempts, with as little friction as possible between having an idea and having a shareable file. Unlike general-purpose tools such as OBS (recording) combined with Kdenlive (editing), Takes keeps the library, the recorder, and a deliberately limited editor in one place. The trade-off is that it does much less: there are no scenes, transitions, titles, or multi-track audio.
Requirements#
- Node.js 22.18 or later (the server runs TypeScript directly through Node's type stripping)
- ffmpeg and ffprobe on the
PATH - Google Chrome or Chromium (recommended; Firefox also works for recording)
Running#
npm install
npm run build
npm start # or: node server/index.ts
To install a takes command:
npm link
takes # opens a Chrome app window at http://localhost:4455
Options: --dir DIR (library directory, default ~/Videos/takes), --port PORT (default 4455), --no-open, and --browser (use the default browser instead of a Chrome app window). If Takes is already running, takes only opens a new window.
For development, npm run dev runs the server on port 4455 with automatic restarts and the Vite dev server on http://localhost:5173.
Using it#
The library shows every video with its thumbnail, duration, and description. Drag cards to reorder them. Deleting a video (with confirmation) moves its folder to .trash/ inside the library, so a mistaken deletion can be undone by hand.
Recording. Choose any combination of camera, microphone, and screen, then start recording. The screen picker is GNOME's own portal dialog, which lets you choose a monitor or a single window. A countdown precedes the recording, and it can be paused and resumed. The Teleprompter window button opens the notes in a separate window with large text, optional auto-scroll, and start/pause/stop controls, so it can sit on a second monitor or outside the captured window. Recorded data is uploaded to the server once per second while recording, so a browser crash loses at most about a second; an interrupted take appears on the video page with a Recover button.
Editing. Each video has a timeline made of segments of its takes. A new take is appended to the end of the timeline, and a take can be added again from the Takes list. The editor supports splitting at the playhead (S), marking a range (I and O) and cutting it (X), trimming the current segment to the playhead, removing and reordering segments, and undo/redo. The timeline shows the audio waveform, and a zoom slider helps with precise cuts. Editing is non-destructive: the raw takes are never modified.
Transcripts. With a Deepgram API key (set it on the Settings page), each take's audio is transcribed after recording. The Transcript tab shows the words that remain in the timeline. Clicking a word seeks to it, and shift-clicking a second word selects the range between them, which can then be cut. This is often the quickest way to remove a false start or a filler word.
Layout and export. For takes that have both camera and screen, the camera can be placed as picture-in-picture (corner, size, and rectangle, rounded, or circle shape), side by side, or hidden. The preview in the editor uses the same geometry as the export. Export renders the timeline to an H.264/AAC MP4 at 720p or 1080p, optionally with loudness normalization to −16 LUFS, and marks the export as outdated when the timeline or layout changes afterwards.
Background removal. In Layout & export, the background behind you can be kept, blurred, replaced with a solid color, or removed entirely (Cutout, for picture-in-picture, where only you appear over the screen recording, sitting on the bottom edge of the video). Choosing any of these processes the camera track of each take with Robust Video Matting (Lin et al., 2021), a recurrent segmentation model designed for video, which gives soft edges around hair and little flicker between frames. The model runs on the CPU through onnxruntime; takes are processed one at a time in the background, and the result is stored as cutout.webm (VP9 with an alpha channel) so that each take is processed only once. The model (about 15 MB) is downloaded from GitHub to ~/.cache/takes/models/ the first time it is needed. Export waits until every take in the timeline has been processed.
Background removal on another machine. On a laptop CPU, background removal is slow, so it can instead run on a machine with an NVIDIA GPU that you reach over ssh. Set ssh host on the Settings page to an ssh destination such as office or user@host; it must accept key-based login without prompting, since Takes runs ssh without a terminal. That machine needs a working NVIDIA driver, Python 3.10 or later, and ffmpeg (with libvpx) on the PATH. If these come from environment modules or similar, put the commands that load them in Setup command (for example module load python ffmpeg); they run in a bash login shell before each job. For each take, Takes sends camera.webm over a single ssh connection, runs the same model with onnxruntime-gpu in a temporary directory there, receives cutout.webm, and removes the temporary directory. The first job creates a Python environment in ~/.cache/takes/venv on the remote machine (about 2.5 GB, because pip installs the CUDA and cuDNN libraries); delete that directory to rebuild it. For a 60 s, 640×480 take, processing took 27.7 s on a remote RTX 6000 Ada, including the transfer, compared with 536 s on the CPU of a 12-thread laptop; the two cutouts differ by less than 1/255 in alpha on average.
Storage layout#
~/Videos/takes/
library.json order of videos
config.json settings, including the Deepgram key (mode 0600)
<video-id>/
video.json title, description, notes, takes, timeline, layout
thumbnail.jpg
<title>.mp4 latest export
takes/<take-id>/
screen.webm camera.webm raw recordings (mic audio is in camera.webm when there is a camera)
cutout.webm camera with background removed (VP9 + alpha), if requested
peaks.json waveform data
transcript.json Deepgram words with timestamps
Everything is plain files, so videos can be backed up, synced, or inspected without the application.
Limitations#
- Screen and camera are recorded by two independent MediaRecorders started at the same instant. In our tests they stay aligned to within a frame, but we have not measured drift over recordings longer than about 20 minutes.
- Screen capture on Wayland depends on the browser's PipeWire support. Recent Chrome enables it by default; if the picker does not appear or the capture is black, check
chrome://flags/#enable-webrtc-pipewire-capturer. - Only the microphone is recorded; system audio (for example, sound from a demo) is not captured.
- The camera layout and background are set per video, not per segment.
- Background removal on the CPU runs well below real time on a laptop (see above for running it on a remote GPU); the matting quality also degrades with a cluttered background, poor lighting, or objects held close to the body, which the model may partly treat as background.
- Export speed depends on the CPU; with the
veryfastx264 preset, a 1080p picture-in-picture export ran at roughly 3× real time on the development machine. - The server listens only on 127.0.0.1 and rejects requests addressed to other host names, but it has no authentication beyond that; it is meant for a single user on their own machine.