Quill Radio 2.0.0
Quill Radio 2.0 -- Release Notes
Quill Radio 2.0 is about one thing done thoroughly: recordings you can trust. Version 1.1.0 rebuilt the sound -- a new playback engine, every stream format, live rewind, richer Sound Enhancements. 2.0 turns that same care on the recorder, closing a reported round of recording bugs and adding the one piece that was always missing: a recording that survives a restart. If you schedule shows, leave long recordings running unattended, or have ever come back to find a capture cut short or gone entirely, this release is for you.
It also widens the net for finding stations: iHeart and TuneIn now join the search, so two of the biggest directories on the internet are searchable and playable right inside Browse Stations. More on that below.
As always, everything below also lands in QUILL itself. Quill Radio and QUILL share one codebase and one data store, so these fixes arrive in both at once -- nothing here is vendored into the Quill Radio wrapper.
The headline: recordings you can trust
A recording in progress now survives a restart -- and Quill Radio asks before resuming
This is the one that hurt. You set a recording going, the app quits or crashes (or Windows does), and the recording is just gone -- the FFmpeg process it had started keeps writing to a temp file nobody would ever find.
Quill Radio now remembers an in-progress recording. It writes a small marker when a recording starts and clears it on a clean stop, so a crash leaves a breadcrumb. On the next launch it first tidies the temp folder -- any finished orphan file is moved into your recordings folder where you'll actually find it, while a file still being written is left untouched -- and then, if a recording was in progress and is still within a 10-minute grace window, it asks you, once, in a proper accessible dialog:
A recording of WQXR was in progress until 9:00 AM. Resume it for the remaining 12 minute(s)?
Resume (Enter) restarts the recording for the remaining minutes only -- not a fresh full duration. Skip (Escape) leaves it as it is. A Don't ask me again checkbox remembers your choice -- always resume, or never ask -- and you can change it later in Preferences. Nothing happens when nothing was in progress, and a marker file that has gone corrupt is thrown away rather than driving a bogus resume.
Scheduled recordings fire reliably throughout their window, not just at the exact minute
The scheduler used to match the exact start minute. So a recording set for 8:00 that Quill Radio only reached at 8:01 -- a slow launch, a brief stall, the tray icon taking a moment -- silently never fired, and a start that failed still burned the whole occurrence for the day.
The scheduler now treats an entry as due from its start time through the end of its duration, so a late arrival starts with the remaining minutes and catch-up on launch is free. Last-fired is stamped only on a successful start (a failure retries on the next poll while the window is still open), one-time entries auto-disable once they've fired, and when two schedules are due in the same minute while the recorder is busy, the second is held and announced instead of being burned. The scheduler thread itself is now lock-guarded and wrapped so it can no longer die silently.
The Recordings list stops flickering and keeps your place
The Recordings list used to rebuild itself on every refresh, snapping a screen reader back to the top and losing whatever you'd selected. It now updates rows in place, keyed by file path: a no-op when nothing has changed, and when something has, your selection, focus, and scroll position are all preserved instead of the list rebuilding under you mid-read.
The counts are honest now, too. The active recording is counted from the recorder itself, so a recording writing to a temp folder is no longer invisible in the list; a firing schedule is no longer double-counted; and completed one-time entries drop out of the scheduled count. The active row shows a live elapsed time, scheduled entries show their zone-labeled times, and the tray tooltip carries "(recording)" while a capture is running.
Recordings harden against dropped connections, dead streams, and a crashed host
Four pipeline fixes that together make a long unattended recording far more likely to come out whole.
- A reconnect records only the remaining time, not a fresh full duration. A 60-minute show that drops at minute 50 records a roughly 10-minute continuation, not another 60.
- Filenames are never silently overwritten. The old unconditional overwrite is gone; a filename pattern that would produce the same name twice gets
" (2)"," (3)"appended instead of clobbering an earlier recording, and continuation parts keep the original start timestamp in their name so they group together. - A drop is classified before any reconnect attempt is spent. A fatal failure -- your disk is full, or the server took the stream down with an HTTP 4xx such as a 404 or 410 -- stops trying, because the stream is gone and reconnecting would only spam continuation files. A transient drop (a network hiccup or a 5xx) is retried as before.
- A crashed host no longer strands a recording. On Windows the FFmpeg child is tied to Quill Radio's lifetime through a job object, so a crashed or killed Quill Radio takes it down with it instead of leaving a bare FFmpeg writing to your temp folder. And the stop-and-wait fallback moved off the UI thread, so closing the window never hangs on a slow FFmpeg shutdown.
More stations to find: iHeart and TuneIn now in the search
Browse Stations used to search the community RadioBrowser directory and the free SomaFM directory. 2.0 adds two of the largest directories on the internet -- iHeart and TuneIn -- blended into the same results list, so a search for a call sign, a city, or a show now reaches far more of the stations people actually ask for. Every result is labeled with where it came from (iHeart, TuneIn, RadioBrowser, SomaFM), and you play it the same way you always have.
Both are keyless and need no account. iHeart is read straight from its public station sitemap -- a two-request directory index -- and a station's real stream is resolved on demand from its own page the moment you play it, never by bulk-fetching thousands of pages. TuneIn goes through RadioTime's open OPML directory (the same service TuneIn's own web player uses): search returns matching stations and the stream address is looked up only for the ones about to play. To keep a single search from turning into dozens of network round trips, iHeart and TuneIn each resolve a small, capped handful of the most relevant matches per search -- enough to add immediately-playable results without slowing the list down -- while RadioBrowser keeps paging as before. A Refresh button re-fetches the iHeart directory index (it is cached once per Browse Stations session; TuneIn and RadioBrowser are always live).
With four directories in one list, Browse Stations gained the controls to steer it. A Source dropdown lets you narrow the search to just one directory -- All sources, RadioBrowser, iHeart, TuneIn, SomaFM, ACB Media, or Website -- when you already know where a station lives. And the old free-text tag and country boxes are now proper dropdowns: a Tag/genre list and a Country list, filled in from the directory itself, so you pick "jazz" or "United Kingdom" from a list instead of guessing the exact spelling, and choosing one runs the search right away.
TuneIn also feeds Find Streams from a Website: paste a TuneIn station page and Quill Radio resolves its real playable stream, the same on-demand lookup the directory search uses. Find Streams now also recognizes an iHeart or TuneIn page directly rather than handing back a page address that will not play.
Like every other network feature, iHeart and TuneIn are off in Safe Mode, HTTPS-only, and inventoried in QUILL's network-egress audit. This lands in the shared quill package (core/radio/iheart.py, core/radio/tunein.py, core/radio/directory_search.py), so QUILL and QUILL Cast gain the same reach.
Scheduling recordings gained real editing
The Schedule Recording dialog was capture-and-forget: add an entry, and your only other move was to delete it. 2.0 makes the schedule something you can actually manage.
- Edit an existing entry -- change its station, time, or duration without deleting and re-adding it.
- Duplicate an entry -- a fast way to set up the same show on another day, or a second time slot for the same station.
- Enable or disable an entry without losing it -- turn a weekly recording off for a week and back on, instead of deleting and rebuilding it. A disabled entry reads as "(disabled)" in the list and simply does not fire.
- Type the time your way -- "7:30 PM" or "19:30", whichever you think in; both are understood.
- Pin an entry to a time zone -- each schedule entry carries its own zone (defaulting to your local time), so a show quoted in Eastern records at the right moment wherever you are, and the list shows each entry's time with its zone.
What's Playing reaches more stations
When a station will not answer the usual title request -- and after Quill Radio has already tried the playback engine's own title channel -- it now takes one more step: it reads the station's own public "now playing" status page (the Icecast or SHOUTcast status endpoint the stream's own server publishes) and pulls the current title from there. It only ever talks to the same server you are already listening to, and it is off in Safe Mode. The practical result is a real "Now playing" on a batch of stations that used to answer with silence.
For troubleshooting: verbose logging and a log folder you choose
Two additions for when something needs diagnosing. Preferences (Ctrl+,) gained a Verbose logging checkbox that turns on detailed debug logging live, without a restart, and a Log folder setting so you can point the log somewhere easy to find (and hand to a bug report). Recording problems now capture the recorder's own error output into that log as well, so a failed capture leaves a trail instead of a mystery.
Built on the 1.1.0 base
2.0 stands on everything 1.1.0 delivered, and none of it changes:
- The mpv playback engine, used automatically, with the classic Windows Media engine one Preferences setting away.
- Every stream format in real-world use -- MP3, AAC and HE-AAC (AAC+), Ogg Vorbis, Opus, FLAC streams, and HLS (m3u8).
- A second sound card for the radio, live pause and rewind of the stream, and Volume Boost.
- Sound Enhancements as a full listening toolkit -- three-band EQ, compressor, mono downmix, night mode, per-station memories -- applying live on the mpv engine.
- Alt+F4 to the tray, automatic update checks, Preferences, the unified station finder, and file logging.
See release-notes-1.0.md for the 1.0 and 1.1.0 story in full, and CHANGELOG.md for the complete versioned history.
Known notes for this release
- Releases are not yet code-signed: Windows SmartScreen may warn on first run. Choose More info, then Run anyway. Signing is planned.
Not a fork -- a guarantee
Quill Radio runs the exact same radio feature code as QUILL, from the same upstream package. The recordings overhaul in this release lands once, in the shared quill package, and reaches QUILL, Quill Radio, and QUILL Cast together. This repository carries only the wrapper, the installer, the icon, and these docs.