Designing a Listen Later Pipeline

cdrnsf1 pts0 comments

Designing a listen later pipeline • Cory DransfeldtSkip to main content Featured July 10, 2026Designing a listen later pipeline<br>/posts/2026/designing-a-listen-later-pipelinedevelopmentwebdevtechrsspreactgolangaudioaudiobookshelf<br>I've had this long, long running relationship with bookmarking and read it later services. I'll commit to one, excited about whatever feature set it offers and then, without fail, my list grows and grows and grows and grows. I archive things to reset, repeat and then move to a different service. The only thing that's ever worked has been listening to articles as audio when I have a spare moment. Sometimes it's background noise but, generally, I absorb things better as audio.Pocket (RIP) was arguably the best at this: it parsed articles beautifully, audio playback was pleasant and it queued things reliably. Instapaper worked fairly well but went through periods of stagnation before its current renaissance. Having Siri read pages to you in Safari also works so long as it's not interrupted and the article isn't too long (it's awful at persisting position and long articles simply fail part way through).Readwise Reader deserves an honorable mention here but, when I last tried it, it didn't support queueing and starting one article at a time is tedious.I've been saving links to linkding long enough to invest in building a client. My initial iteration of this pipeline consisted of saving items manually from FreshRSS to linkding and then having a headless node app poll linkding, fetch unread links and parse them to audio and upload them to audiobookshelf. The pipeline I've arrived at is similar, but with significant refinements and infrastructure changes.A custom RSS reader<br>Everything I've been building for myself lately has been built in Go and Preact. It's fast, robust and has been a good learning experience. I love different parts of a number of different RSS readers and Feedbin is as close to perfect as they get. I wanted something I could easily self-host and build as many or as few features as I wanted.What I built isn't terribly unique: it polls feeds, lets me manage them and organize them into folders. I didn't bother to implement starring (I've never used it in the near two decades I've used RSS). I built support for the following:Proxying imagesFetching full textDetecting feed healthLoading YouTube embeds using youtube-nocookie.comStripping query params used for trackingFirst class linkding integrationRules targeting items saved to linkding (handy for stripping publication titles and such from titles)Rules targeting title/description/content in feed itemsAll the keyboard shortcuts I could possibly wantI'm sure I'm missing some. What this also allows me to do is configure rules targeting everything from a feed and save it to linkding without me having to see or triage it. I love and pay for 404 Media, so everything they publish gets saved automatically.1A UI for my audio engine<br>The initial version of my audio engine that processed saved items was a blunt instrument. It parsed everything, unaltered, to audio. Failures were in Docker logs and all configuration lived in a .env file. A workhorse, but one that wasn't the easiest thing in the world to navigate.I went about building a UI for it (guess which stack I used). It's, more or less, a dashboard with an indicator of whether it's processing, some high level stats, a bunch of tabs and, in each tab, a table. What this allows me to do is see what's been processed recently, links that failed (which I can re-run or archive if it was a permanent failure — typically 403s), all history and so forth. I can view logs in the UI and manage users (of which I'm the only one).The most compelling part of this, to me, are the cookies and rules features. The former lets me dig cookies for paywalled sites (see 404 Media) out of my browser, save them and send them when I fetch a link from the site. The latter lets me apply rules to fetch text before it's processed into audio. This is helpful removing blurbs that are included in every article for a site so I don't have to listen to it every single time.The underlying process to fetch text runs every 5 minutes. Links are accessed using curl and text is parsed using go-readability. If go-readability extracts fewer than 100 characters (usually a page that needs JavaScript to render) it falls back to the Wayback Machine's snapshot, which was crawled by a real browser. Fetches are restricted to http/https so a hostile link can't redirect curl into file:// and read something local, and the output size is capped.Where there's a feed, there's audio to be made.Making things listenable<br>Narration is handled using Piper and the lessac-high voice model. I'm piping Piper's2 stdout straight into FFmpeg's stdin through an io.Pipe, with no WAV written to the disk. Audio output is tagged using id3v2 — this maps to what Audiobookshelf expects for podcasts. The episode title is the article title, the author is a generic...

audio long linkding listen later pipeline

Related Articles