<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Preservation on Nelson Chen's Blog</title><link>https://mindflakes.com/tags/preservation/</link><description>Recent content in Preservation on Nelson Chen's Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Copyright Nelson Chen</copyright><lastBuildDate>Sun, 13 Sep 2026 10:34:51 -0700</lastBuildDate><atom:link href="https://mindflakes.com/tags/preservation/index.xml" rel="self" type="application/rss+xml"/><item><title>My wobbly VHS pipeline</title><link>https://mindflakes.com/posts/2026/09/13/my-wobbly-vhs-pipeline/</link><pubDate>Sun, 13 Sep 2026 10:34:51 -0700</pubDate><guid>https://mindflakes.com/posts/2026/09/13/my-wobbly-vhs-pipeline/</guid><description>&lt;p&gt;I wanted to recover some VHS tapes. Somehow this turned into tapping a signal inside a Sony VCR, putting capture cards in a computer from the junk pile at work, spreading the processing across three machines, and asking Codex to help redesign an amplifier PCB.&lt;/p&gt;
&lt;p&gt;There is a reason I went this way. The usual way to digitize VHS is to connect a VCR&amp;rsquo;s video and audio outputs to a capture device and record them on a computer. The VCR reads the tape and turns its signal into a picture before the computer ever sees it.&lt;/p&gt;
&lt;p&gt;For better results, you can look for a nicer VCR with a built-in time base corrector, or TBC, which helps correct playback timing errors that make the picture wobble. Unfortunately, the decks I was looking at were $$$. With ancient media having a moment again, it feels like everybody wants the same aging hardware. The expensive stuff is, well, expensive.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/oyvindln/vhs-decode"&gt;VHS-Decode&lt;/a&gt; offers a more hardcore route. You still need a working VCR, but you tap the RF signal inside it, near the tape-head amplifier, before the machine turns it into ordinary video. This is not the antenna connector on the back. Suitable capture hardware records that earlier signal, and the computer reconstructs the picture, including time base correction, in software.&lt;/p&gt;
&lt;p&gt;That sounded pretty appealing: use an ordinary VCR, spend less on a fancy deck, and accept more fiddling. Keeping the RF recording also means I can try different settings or a better decoder later without playing the physical tape again.&lt;/p&gt;
&lt;p&gt;I first heard about VHS-Decode about two years ago. I lacked the hardware, time, and initiative to really start. Codex helped me get past a lot of those hurdles. I drove the whole setup through Codex, right down to configuring Ubuntu on the capture machine. It was involved from the beginning, not something I added after getting everything working.&lt;/p&gt;
&lt;p&gt;To be clear about who wrote what: Codex wrote a lot of the custom code for this setup. I directed and oversaw the work, made the decisions, and handled the physical hardware. When I call these “my scripts” or “my pipeline,” I mean the setup I am building and responsible for, not that I personally typed all the code.&lt;/p&gt;
&lt;p&gt;The pipeline repo has an &lt;code&gt;AGENTS.md&lt;/code&gt; with instructions for Codex and a &lt;code&gt;journal.md&lt;/code&gt; where we take notes as we go. That journal now runs through months of experiments, failures, and procedures that apparently needed another procedure.&lt;/p&gt;
&lt;p&gt;It is still a constant WIP. But looking back through those notes, there is an actual journey from “can I get a signal?” to something that helps me understand and organize the tapes too.&lt;/p&gt;
&lt;h2 id="first-get-a-picture"&gt;First, get a picture&lt;/h2&gt;
&lt;p&gt;I already had the Sony SLV-688HF. The capture computer was a Dell OptiPlex 7010 rescued from the junk pile at work. An old business desktop with room for capture hardware seemed like a reasonable place to start.&lt;/p&gt;
&lt;p&gt;In late June and early July, the work was mostly getting that machine ready: Ubuntu installation and configuration, the CXADC driver, capture cards, cables, and figuring out whether the signal coming out of the VCR was useful. I was directing that work through Codex while handling the physical hardware myself.&lt;/p&gt;
&lt;p&gt;On July 3, the first input we tried was basically flat, even with the tape playing. Switching from the white BNC input to the red one gave us a much healthier signal. A small detail, but fairly important when the whole project depends on recording something other than nothing.&lt;/p&gt;
&lt;p&gt;That day&amp;rsquo;s one-minute test produced about 1.6 GiB of RF data. Decoding it on my MacBook took a little over five minutes in that early test, then produced roughly another 3.2 GiB of intermediate picture data. This was already a hint about where the project was going.&lt;/p&gt;
&lt;p&gt;First there was a viewable black-and-white preview, without sound. Then a short color preview.&lt;/p&gt;
&lt;p&gt;There was an actual picture. The weird route worked well enough to keep going.&lt;/p&gt;
&lt;h2 id="one-minute-was-manageable-two-hours-was-different"&gt;One minute was manageable. Two hours was different.&lt;/h2&gt;
&lt;p&gt;The next problem was doing this at tape length. I added a Samsung 980 1 TB NVMe SSD I already had on hand as scratch storage in the capture machine. By August 8, a two-hour-and-two-minute capture had produced about 196 GiB of RF data, plus separately recorded audio. The machine&amp;rsquo;s 250 GB boot SSD was not going to provide comfortable working room for that.&lt;/p&gt;
&lt;p&gt;Now storage and transfers were part of the job. The source needed to get onto the storage machine, and the copy needed checking before I treated it as safely transferred. Then came decoding, with another set of enormous files to put somewhere.&lt;/p&gt;
&lt;p&gt;I store the captured RF on the NAS in FLAC. Yes, FLAC, the format usually associated with lossless audio. Here it holds the sampled RF signal, not a finished video. The separately captured audio has its own FLAC file. This saves space without throwing away the signal samples I want to decode again later.&lt;/p&gt;
&lt;p&gt;I had Codex write custom scripts and capture tooling, under my direction, to FLAC the streams on the fly. That avoids making every capture a huge raw file followed by another whole compression job. The compressed captures still need to get safely onto the NAS, and the tooling has to keep track of whether samples were lost or an encoder failed. Compression is useful; silently losing part of the tape is not.&lt;/p&gt;
&lt;p&gt;I tried decoding on the storage machine too. One run was heading toward roughly two days of processing. Later the production decoding moved to a Windows machine. The setup grew into three main jobs on three machines: capture, preservation storage, and decoding/export.&lt;/p&gt;
&lt;p&gt;The Windows stage now turns the retained RF recording into intermediate luma and chroma picture files, then makes H.265/AAC copies I can watch. Those convenient video files do not replace the preservation source. Keeping the earlier signal is a large part of why I chose this approach in the first place.&lt;/p&gt;
&lt;p&gt;Audio added its own little complication. I capture it separately, and separate devices have separate clocks. Their crystal oscillators can run at slightly different rates, so audio that lines up at the start can drift away from the picture later.&lt;/p&gt;
&lt;p&gt;Synchronizing the hardware clocks is one approach. I was okay with resampling the audio to fit the video timeline instead. That means adjusting its timing over the recording, not just moving the whole track left or right and hoping. It also means checking synchronization beyond the beginning.&lt;/p&gt;
&lt;p&gt;At this point, “capture a tape” had acquired quite a few more steps than pressing record.&lt;/p&gt;
&lt;h2 id="then-i-had-to-find-out-what-was-on-it"&gt;Then I had to find out what was on it&lt;/h2&gt;
&lt;p&gt;An August entry in that journal has a useful lesson in why the end of a recording is not necessarily the end of a tape.&lt;/p&gt;
&lt;p&gt;A fixed-duration capture can keep recording after a short tape has stopped, wasting a ridiculous amount of space. But looking for static is not enough to decide where useful material ends either. One tape had a static gap followed by another recording. Stopping at the gap would have missed it.&lt;/p&gt;
&lt;p&gt;These tapes were recorded over, sometimes only partially. A cassette can contain television, home video, and then more television. Sampling a few places and finding TV does not establish that there is nothing personal elsewhere.&lt;/p&gt;
&lt;p&gt;So my rule is to capture the whole tape first and analyze it afterward. I do not stop because the interesting-looking recording ended, television started, or the picture went to static. There could be something else further along. The power meter helps detect the physical end of the tape; figuring out which parts to keep in the viewing copies is a separate, later job.&lt;/p&gt;
&lt;p&gt;This became one of the most useful parts of having Codex involved. It has been great at scene analysis, helping with transcription and translation, and writing up what is happening on the tapes. It can help sift the home-video sections out of recorded TV programming and leave a map of the recording alongside the watchable files.&lt;/p&gt;
&lt;p&gt;The review procedures grew around that work: frames throughout the recording, extra scene-change samples, and moving picture with audio around anything ambiguous. I want to know what was actually checked, not just get a confident summary based on three screenshots.&lt;/p&gt;
&lt;p&gt;Codex also helped read the wonky Chinese handwriting on the old labels. Some of it is barely readable scratches at this point. A plausible reading and translation can give me a starting point, and the footage can help make sense of it. Uncertain characters need to stay marked as guesses. The same goes for difficult speech in a transcript.&lt;/p&gt;
&lt;p&gt;I am keeping the tape contents and detailed records private, but this part matters to the story. Getting a video file is useful. Having help figure out what is in it, where the different recordings start, and how to find them again makes the whole project much more useful to me.&lt;/p&gt;
&lt;h2 id="of-course-it-grew-a-labeling-system"&gt;Of course it grew a labeling system&lt;/h2&gt;
&lt;p&gt;By mid-August, I had also connected a Brother PT-D600 label printer over USB. Apparently the tape project needed a labeling regime too.&lt;/p&gt;
&lt;p&gt;I stopped using printed status labels. Keeping those updated was more fuss than it was worth; off-the-shelf smiley-face stickers from Amazon were easier.&lt;/p&gt;
&lt;p&gt;The labels I still print are for identity and content only. Each tape gets a stable ID, and its box gets the same one. Content labels describe the recording, with a date when known. Processing status stays in the digital records, not on a succession of replacement labels.&lt;/p&gt;
&lt;p&gt;Yellow means “could be better.” Green is reserved for what I would call a perfect capture. I am not there yet: I still do not have the shared-clock hardware to synchronize the captures, so I am using the resampling approach described earlier. Green is a goal for now, not a claim about the captures I already have.&lt;/p&gt;
&lt;p&gt;That connects the digital notes back to the object in front of me. Codex can help inspect a tape, write up the findings, and print the labels. If the box and cassette get separated, I can still identify both.&lt;/p&gt;
&lt;p&gt;There is also an M5Stack Atom Lite, a little ESP32 device with a built-in infrared transmitter, for sending the VCR commands like play, stop, and rewind. It cost me $14. I 3D-printed a small stand for cents to hold it up against the VCR, aimed at its infrared receiver. So the automation can press the remote buttons too, although sending an IR command is not proof the VCR obeyed it.&lt;/p&gt;
&lt;p&gt;For that, I also monitor the VCR with a power meter. The deck draws different amounts of power when the tape transport is active and when it is stopped with a tape loaded. The workflow watches those measured states rather than assuming an IR command worked. To rewind, it sends Stop, checks that the deck has settled, sends Rewind, then watches for sustained activity followed by a stable return to the stopped state. Those checks are specific to this VCR and setup.&lt;/p&gt;
&lt;p&gt;At capture time, the software starts recording before sending Play, so it does not miss the beginning while getting ready. It then watches for the deck to become active. When the tape reaches its physical end and the transport stops, the power draw settles back into the stopped range. That sustained change is how the workflow detects end-of-tape, alongside the capture&amp;rsquo;s own integrity checks. It records through the TV programming, static, and silence instead of using the content to guess where the tape ends. An unexpected stop or ambiguous meter evidence still needs checking; a power reading alone cannot explain why the transport stopped.&lt;/p&gt;
&lt;p&gt;Then, later in August, I had it help redesign the RF amplifier PCB for a more ordinary, externally regulated 9V input. I wanted the power setup to be less exotic. This was a later hardware experiment, not something I had to finish before getting that first picture in July.&lt;/p&gt;
&lt;p&gt;The redesign passed KiCad electrical and layout checks, and the prototype fabrication order shipped. That is not a bench-tested result yet. Still, going from a project I had not managed to start to ordering a revised amplifier board is quite a progression.&lt;/p&gt;
&lt;h2 id="the-setup-kept-finding-new-ways-to-be-annoying"&gt;The setup kept finding new ways to be annoying&lt;/h2&gt;
&lt;p&gt;Moving the decoding to Windows did not end the infrastructure work. The intermediate files were still huge. Writing them through a mount to the storage machine saved local scratch space, until the mount became unreliable.&lt;/p&gt;
&lt;p&gt;The decoder itself became part of the work too. In my tape-decode fork, Codex investigated and wrote fixes for a bunch of issues where multithreaded decoding would jam up, with me overseeing the work. So this was not just asking an agent to run somebody else&amp;rsquo;s program. It was also digging into why the program got stuck and changing the code. That does not mean every threading problem is gone, but those fixes are another part of how this setup kept moving forward.&lt;/p&gt;
&lt;p&gt;A decoder can still be running while its output is no longer reaching the destination. A mount process can exist without being useful. Successfully launching a command tells me surprisingly little about whether the job is going to finish.&lt;/p&gt;
&lt;p&gt;So there are checks for actual file growth, child-process logs, transfer lengths, and expected picture-field counts. There is also a chunked path: close a piece locally, transfer it, verify it, reclaim the space, and assemble the pieces in order afterward.&lt;/p&gt;
&lt;p&gt;This is where the long journal earns its keep. Each tape has records of the current files, commands, attempts, and results. The procedures explain which machine does what and what counts as completing a stage. A later Codex conversation can inspect that state and continue instead of needing me to remember every detail.&lt;/p&gt;
&lt;p&gt;I also use the shit out of goals in Codex for this. I give it an outcome to work toward, like getting a tape ingested, preserved, decoded, and reviewed, with the records updated. The goal says what I want finished; the repo&amp;rsquo;s instructions, procedures, and journal give it the details needed to keep working toward that. There are a lot of intermediate steps in this setup, and I do not want “the decoder started” to be mistaken for the job being done.&lt;/p&gt;
&lt;p&gt;The procedures change because the work changes. A failed mount leads to another check. A misleading preview changes the review instructions. Something that worked for a short test turns out to need a different approach for a whole tape.&lt;/p&gt;
&lt;p&gt;I am pretty amazed Codex can deal with all of this. I can ask it to help capture, preserve, decode, review, export, and update the records across this weird setup. I still have to physically put the tape in the VCR. There are limits to the agent thing. 😅&lt;/p&gt;
&lt;p&gt;And a process starting successfully is not successful preservation. Even finishing an encode does not establish that the source is safely retained, the audio is right, or the important sections were found. That is why the notes have become rather fussy about “done.”&lt;/p&gt;
&lt;h2 id="cheaper-does-not-mean-cheap"&gt;Cheaper does not mean cheap&lt;/h2&gt;
&lt;p&gt;People have been asking what this approach costs. I went back through my purchase emails, and even the partial breakdown is a reminder that an ordinary VCR does not make the whole project cheap.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th style="text-align: right"&gt;Cost / replacement allowance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sony SLV-688HF VCR, including shipping and tax&lt;/td&gt;
&lt;td style="text-align: right"&gt;$69.13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Capture computer, salvaged from the junk pile at work&lt;/td&gt;
&lt;td style="text-align: right"&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Samsung 980 1 TB NVMe scratch SSD, already on hand&lt;/td&gt;
&lt;td style="text-align: right"&gt;$0 additional spending; allow about $300 for a new 1 TB replacement today&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Capture-PC boot SSD, PCIe NVMe adapter, BNC cable, tap lead, and SMA/BNC adapters, grouped in one shipment&lt;/td&gt;
&lt;td style="text-align: right"&gt;$100.49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-Video-to-BNC splitter shipment&lt;/td&gt;
&lt;td style="text-align: right"&gt;$8.77&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMA DC-block shipment&lt;/td&gt;
&lt;td style="text-align: right"&gt;$27.38&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Three PCIe capture cards for CXADC, including one dud&lt;/td&gt;
&lt;td style="text-align: right"&gt;$90.02&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JLCPCB amplifier prototype batch: five PCBs, two assembled&lt;/td&gt;
&lt;td style="text-align: right"&gt;About $140&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M5Stack Atom Lite ESP32 controller with built-in IR&lt;/td&gt;
&lt;td style="text-align: right"&gt;$14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3D-printed stand for aiming the IR controller at the VCR&lt;/td&gt;
&lt;td style="text-align: right"&gt;Cents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VCR power meter for transport-state monitoring&lt;/td&gt;
&lt;td style="text-align: right"&gt;About $14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estimated additional spending for my setup&lt;/td&gt;
&lt;td style="text-align: right"&gt;&lt;strong&gt;About $464&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;With a current replacement allowance for the scratch SSD&lt;/td&gt;
&lt;td style="text-align: right"&gt;&lt;strong&gt;About $764&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Apart from the scratch SSD&amp;rsquo;s explicitly marked replacement allowance, these are historical purchase amounts for my setup, including things bought while experimenting, not a recommended shopping list. The three matching AliExpress card orders show $30.87, $31.48, and $27.67. One card was a dud, so I ended up buying three; that is my spending, not a requirement to buy three cards. The emails also carry a shipping-fee exclusion notice, so those amounts may not capture every charge.&lt;/p&gt;
&lt;p&gt;The amplifier batch is about $140 from memory, pending the final invoice. I am counting the whole batch rather than dividing it into a misleadingly cheap single-board price. The Amazon shipment totals also differ from the initial order confirmation. With the $14 IR controller, roughly $14 power meter, and cents for the printed stand, call this roughly $464, with some accounting still to reconcile.&lt;/p&gt;
&lt;p&gt;The scratch SSD was another thing I already had, not another free component somebody else can assume they will find. Current prices are wild. On September 13, 2026, a &lt;a href="https://www.bestbuy.com/product/samsung-990-evo-plus-ssd-1tb-pcie-gen-4x4--5x2-m-2-2280-speeds-up-to-7150-mb-s/J3ZYG2TVFS/sku/12161481"&gt;Best Buy marketplace listing for a Samsung 990 EVO Plus 1 TB&lt;/a&gt; showed $299.74, sold and shipped by Merchant Expo LLC. I am using roughly $300 as a current replacement allowance, before tax. That is a newer model, not the Samsung 980 actually in my machine, and one listing rather than the cheapest-drive claim or a market average.&lt;/p&gt;
&lt;p&gt;The capture computer came out of the junk pile at work. It cost me nothing. Maybe call it a $100 used computer if you had to find something similar, but that is my guess, not a checked price. Including both that computer estimate and the scratch SSD allowance puts this partial budget around $864. The separate boot SSD and PCIe adapter I bought are already counted in the shipment above; the 1 TB scratch drive is not bundled into that amount.&lt;/p&gt;
&lt;p&gt;The other computers already on hand, bulk storage, tools, label printer and its tape, smiley-face stickers, electricity, and AI usage are outside this subtotal too. Starting from nothing would be a different budget.&lt;/p&gt;
&lt;p&gt;For comparison, the TBC-equipped decks I found on eBay while writing this were roughly $700–$1,600, depending on model and claimed condition. A &lt;a href="https://www.ebay.com/itm/236911127606"&gt;JVC HR-S9911U listing marked sold showed $900&lt;/a&gt;, a &lt;a href="https://www.ebay.com/itm/327171572501"&gt;seller-described rebuilt HR-S7600U was listed at about $1,150&lt;/a&gt;, and a &lt;a href="https://www.ebay.com/itm/396906605292"&gt;Panasonic AG-1980 listing describing capacitor replacement showed about $1,600&lt;/a&gt;. Those last two are advertised prices, not verified sale amounts, and this is a small sample rather than a market average.&lt;/p&gt;
&lt;p&gt;My additional spending comes to around $464, helped by a free computer and a scratch SSD I already owned. Allowing for buying those two items brings this partial budget closer to $864, which overlaps the lower end of those TBC-deck examples. There is still a lot of assembly, troubleshooting, and existing equipment behind that number. The eBay prices are for the deck alone too, so neither side is a complete capture setup priced from scratch.&lt;/p&gt;
&lt;h2 id="still-growing"&gt;Still growing&lt;/h2&gt;
&lt;p&gt;This started as a way to avoid paying for a fancy VCR. It has become a small preservation workflow, with considerably more DIY than the price comparison alone suggests.&lt;/p&gt;
&lt;p&gt;I would not present it as a polished setup for somebody else to install. Parts work well, parts need babysitting, and the next tape can still expose another bad assumption.&lt;/p&gt;
&lt;p&gt;I am keeping my own pipeline repo and tape collection private, but you do not need my exact repo to try this. I think this post should give you a starting point for making your own: write down what your machines do, keep a journal, and build up scripts and checks as you go. Steal whichever tricks here are useful, adapt them to your setup, and add the ones you figure out yourself. That is pretty much how mine grew.&lt;/p&gt;
&lt;p&gt;But the payoff is that I can now put a tape in, start a new Codex thread in the repo, and give it an ingest goal.&lt;/p&gt;
&lt;p&gt;It reads the instructions and notes, checks that there is room for the capture, rewinds the tape through the IR controller, and watches the power meter to confirm the rewind has finished. It gets the capture running, sends Play, and records the whole tape, using the meter to detect end-of-tape. Then it can carry on with preserving the files on the NAS, decoding, reviewing, and writing up what it found. Capture everything first; sort out the contents afterward.&lt;/p&gt;
&lt;p&gt;There is a lot behind that little request, and it can still need my help when something goes wrong. But I no longer have to manually coordinate every command on every machine just to get through a tape. The scripts, checks, and long journal are what let a fresh thread pick up the job.&lt;/p&gt;
&lt;p&gt;That is the part I find amazing. This sat on my someday pile for about two years, and now I can toss in a tape and ask Codex to get started. I did not set out to build all of this. I wanted to see what was on the tapes.&lt;/p&gt;</description></item></channel></rss>