Releases: serrebidev/requestcast
Release list
RequestCast 1.8.5
RequestCast now recognises live events that it did not start — a scheduled show
like A State of Trance, a remote DJ, or another tool feeding the live harbor —
and yields to them.
Outside events are detected and shown. The home page now reports the live
event currently on air (from the station's nowplaying API) alongside RequestCast's
own relay. RequestCast's own relay is told apart by matching its broadcast start
time, so it never shows up twice.
Live events take priority. When a live event is already on air, "Add &
request" on a YouTube livestream now reports that the event has priority instead
of connecting a second source over it. While a relayed stream is playing, the
title/metadata loop stops the moment an outside event takes over, so RequestCast
never overwrites the event's own title; and when a relay ends, the watchdog only
marks the live over if no outside event has taken over the harbor — so an
incoming show is not wrongly reported as ended.
RequestCast 1.8.4
Livestreams now hand the air back to AutoDJ by themselves when they end, and
ffprobe is tracked as a required tool.
Auto-return to AutoDJ. When a relayed livestream ends, yt-dlp exits but the
ffmpeg encoder can linger on the harbor feeding silence, which keeps the station
stuck on a dead live source. A watchdog now waits on the source process and, the
moment it ends, stops the encoder, clears the on-air record, and pushes
is_live="false" to Liquidsoap — so AutoDJ resumes automatically and the
now-playing display stops claiming a live stream. The watcher is keyed on the
actual process handles, so re-requesting the same stream can never let a stale
watcher tear down the new relay.
ffprobe is a required tool. The missing-tools check (setup page, diagnostics,
and automatic install) now includes ffprobe alongside ffmpeg, so a station with
ffmpeg but no ffprobe is reported clearly and, on Windows, both are installed
together.
RequestCast 1.8.3
Livestream requests now play immediately instead of hanging in the queue, and the
livestream title is pushed to Liquidsoap.
Livestreams fail fast and never retry. A livestream that is queued behind an
older job (or that can't be relayed) used to sit in the queue as "waiting for the
downloader" forever — the downloader kept trying to grab a stream that never ends.
Livestream downloads now raise a distinct LiveStreamError that fails the job
immediately with a clear message and is excluded from automatic retries and
requeues, so nothing blocks the queue.
Livestream metadata is pushed to air. When a livestream is relayed, the
stream's title and artist are pushed to Liquidsoap via custom_metadata.insert
right after the harbor switch, and refreshed periodically while it plays — so the
on-air display shows the actual stream title instead of a stale AutoDJ track.
Configured with azuracast_live_metadata_url (the telnet/API endpoint) and
azuracast_live_metadata_key, or on a server
REQUESTCAST_AZURACAST_LIVE_METADATA_URL / REQUESTCAST_AZURACAST_LIVE_METADATA_KEY.
RequestCast 1.8.2
YouTube livestreams now play live instead of trying to download.
"Add & request" on a livestream puts it on the air. A YouTube livestream never
ends, so there was nothing sensible to download — the old behaviour was a download
that hung or failed. Now, when live playback is enabled in Preferences, choosing
"Add & request" on a live URL relays the stream straight into the station's live
input, and AzuraCast's live-fallback switch takes it on air a few seconds later.
The home page shows the live stream while it is playing, with a Stop button that
hands the air back to AutoDJ.
Live playback is opt-in and configurable. Two new settings control it:
azuracast_live_enabled (off by default) and azuracast_live_url, the icecast://
URL of the station's live/DJ harbor. On a server they can also be set with
REQUESTCAST_AZURACAST_LIVE_ENABLED=1 and REQUESTCAST_AZURACAST_LIVE_URL. A
livestream that is added but not requested, or one that appears inside a playlist,
is reported clearly as a livestream rather than being silently attempted.
RequestCast 1.8.1
A deployment fix and a Soulseek default change.
musicdl stops failing to update itself on hardened servers. On a server
deployment the Python environment is typically root-owned and made read-only by
systemd hardening, so the automatic musicdl update tried to write into it every
cycle and failed with "Read-only file system". RequestCast now recognises a venv
it cannot write to — and a read-only error from pip itself — and leaves the
package alone with a clear note, because such an install is updated from
requirements.txt at deploy time. A genuinely writable install still updates
itself exactly as before.
Soulseek shares the AzuraCast media library by default. When Soulseek is
enabled, the folder peers can download from is now the station's AzuraCast media
folder when one is configured, falling back to the download folder in local mode.
The radio's music library is shared back to the network out of the box, while
files RequestCast is still working on stay private.
RequestCast 1.8.0
RequestCast gains an optional Soulseek source, finer control over Deezer and
YouTube audio quality, and richer Deezer metadata and lyrics.
A Soulseek source for the tracks nothing else has. Enable it in Preferences
with a username and password, and a separate "Soulseek only" search appears alongside
YouTube, Deezer, and musicdl. Results list peers, formats, and availability, and a
download fetches the file straight from the chosen peer. Soulseek results have no
catalog fallback — a peer that goes offline fails that one track rather than silently
substituting another source. The download folder can be shared back to keep the network
alive, and is off by default. Requests from peers who share nothing are refused, and
folders split across drives no longer crash the share scanner.
Deezer quality is now your choice. The ARL setting previously always asked for
FLAC and then dropped to 320 kbps MP3. Preferences now has a quality option: FLAC with
a 320 kbps fallback (the default), or 320 kbps MP3 only. There is no silent drop to
128 kbps — if the account cannot serve what you asked for, the track falls through to
the next source.
Deezer's own metadata, plus synced lyrics. Deezer downloads now read the track's
authoritative metadata from Deezer's gateway — title, artist, album, ISRC, release year,
track and disc numbers, and cover art — instead of guessing from the search result.
Deezer tracks also fetch synced lyrics from LRCLIB when available and tag them into the
file next to the cover art.
YouTube audio format control. A new setting decides what YouTube audio is delivered
as. The default is "original", which keeps the source codec untouched — the
quality-preserving behaviour RequestCast has always had. Converting to FLAC, MP3, or
Opus is now an option for stations that prefer one container; converting to FLAC never
adds quality, it only re-containers the audio.
RequestCast 1.7.2
A request that AzuraCast declines under its own rules is no longer reported as a
failed download.
"Add & request" reports the truth when AzuraCast says no. When a track is added
successfully but AzuraCast declines to auto-queue the request — because the song or
artist was played too recently, the song is already requested, or the track is not
requestable — the job now finishes as completed with "Added successfully; AzuraCast did
not accept the request" and the reason, instead of showing a red "failed" that read as
though the download never happened. The file is still safely in the library and request
playlist either way.
A settings file that cannot be written no longer costs you the tool update it was trying
to record.
Tool updates survive a read-only settings file. When RequestCast installs or updates
yt-dlp or Deno, it writes down where the new copy landed. If the settings file cannot be
written — a service confined to a few writable paths, a portable copy on read-only media —
that write failed loudly enough to take the update with it: the background updater thread
died the first time it succeeded at anything, so yt-dlp was never checked again for as long
as the program stayed running, and the "check for updates now" button returned an error
after having updated the tools. Installing a missing tool mid-download failed the same way,
reporting that the tool could not be installed when it just had been.
The tool is installed either way, and RequestCast looks in its own tools folder before
PATH, so an unwritable settings file now costs nothing but the note of where the tool went.
RequestCast 1.7.1
A settings file that cannot be written no longer costs you the tool update it was trying
to record.
Tool updates survive a read-only settings file. When RequestCast installs or updates
yt-dlp or Deno, it writes down where the new copy landed. If the settings file cannot be
written — a service confined to a few writable paths, a portable copy on read-only media —
that write failed loudly enough to take the update with it: the background updater thread
died the first time it succeeded at anything, so yt-dlp was never checked again for as long
as the program stayed running, and the "check for updates now" button returned an error
after having updated the tools. Installing a missing tool mid-download failed the same way,
reporting that the tool could not be installed when it just had been.
The tool is installed either way, and RequestCast looks in its own tools folder before
PATH, so an unwritable settings file now costs nothing but the note of where the tool went.
RequestCast 1.7.0
Searches bring back much more, refused downloads recover on their own, and the download
tools install and update themselves.
Deno is installed automatically, and YouTube works again. YouTube now answers with
JavaScript challenges yt-dlp cannot solve by itself; it hands them to an external
JavaScript runtime, and enables Deno by default. Without one, YouTube downloads lose the
better formats and fail with 403 errors no amount of retrying clears. RequestCast now
treats Deno as a required tool: it is fetched into the tools folder alongside yt-dlp and
ffmpeg, kept current, and passed to yt-dlp explicitly, since our copy is not on PATH. A
403 with no Deno present now says so instead of blaming rate limiting.
The download tools set themselves up. yt-dlp, ffmpeg, and Deno are installed in the
background as soon as RequestCast is configured — nobody has to find a button first — and
a download that arrives before they are ready waits for the install rather than failing.
yt-dlp and musicdl keep themselves up to date. Both stop working as the sites they
read change, and an out-of-date yt-dlp is the most common cause of downloads that fail
while the same track plays fine in a browser. RequestCast checks daily by default and
installs what is newer. The interval is configurable, automatic updating can be turned
off, and Preferences has a "check for updates now" button that reports what each tool did.
Searches pull in much more. Result counts were fixed at 25 from YouTube and 12 per
type from Deezer. The number is now a setting, defaulting to 50 per source and per result
type, and every search page has a "results per source" control, so one search can ask for
200 without changing anything permanently. Deezer results are paged rather than truncated
at the API's 100-row ceiling. musicdl can also join searches now — its platforms carry
plenty that YouTube and Deezer do not — either always, or per search from the source list.
Failed downloads have real retry settings. Bulk runs — a channel, a discography, a
playlist import — get refused in batches with 403 or "video unavailable" even though the
same tracks download fine later. That is rate limiting, and there was no way to tune it.
Now there is:
- Extra attempts per track, each asking YouTube as a different client, which is what
usually clears a 403 outright. - A gap between tracks, which is the most effective way to avoid being rate limited to
begin with. - A cooldown after several refusals in a row, and again before a final pass over
everything that failed, so a batch that was refused is retried once the site has settled
instead of being written off. - A requeue limit for a whole download that fails outright.
- A "try this download again" button on every finished download. Tracks already in the
library are recognised and skipped, so a retry only fetches what is missing.
Failures are also explained now: a bare HTTP Error 403: Forbidden in the history says
what it means and what to change.
RequestCast 1.6.1
Two fixes for the musicdl integration from 1.6.0.
Single-track pages now work on every musicdl platform. Pasting a bare track URL —
soundcloud.com/artist/song, not just a playlist or set — used to fail with "That URL
did not produce any tracks musicdl recognizes", because musicdl's URL parser only
understands collections. RequestCast now reads the page for an artist and title and
resolves the track by searching that platform's own musicdl client. Tracks whose
streams cannot be stored up front (HLS streams, short-lived URLs) are re-resolved the
same way when the download runs instead of being dropped.
musicdl no longer fails on hardened Linux services. A service running with a
read-only home directory (systemd ProtectSystem=strict) got
[Errno 30] Read-only file system on any musicdl lookup, because musicdl creates its
log directory under the account's home. RequestCast now points the XDG directories
musicdl uses at its own state directory; XDG values you set yourself still win.