Transfer music (Settings > Transfer music, or Library > Transfer music), with no login and nothing to set up: Spotify liked songs and playlists come over by copying them in the Spotify app (Ctrl+A, Ctrl+C) and pressing Paste; YouTube Music by playlist link or a Google Takeout file; Deezer and SoundCloud from a public profile; Last.fm from the user name. Runs in the background, continues after a restart, and lists that come over twice only get their new songs. Pasting many links into search opens it too.
Links without keys: Spotify playlists, albums, artists and songs are read from Spotify's public embed page when neither the server nor the app has a Spotify key (up to 100 songs per list), YouTube playlists from YouTube's web endpoint without an API key.
New playlist: paste a link instead of typing songs. Spotify playlists, albums, artists and songs, Deezer playlists, albums, artists and profiles, SoundCloud sets, likes and tracks, YouTube playlists, public Apple Music playlists and albums, Bandcamp albums, Last.fm profiles and short links (on.soundcloud.com, deezer.page.link, spotify.link) work; pasting such a link into search does the same. Playlist files (CSV, Spotify export, M3U, XSPF) import from the same dialog.
Settings > Support > Docs opens the new documentation at docs.glyph.my.
Add Discord Rich Presence (Settings > Integrations, off by default): the current song, artist, album and cover appear in your Discord profile. A Discord application ID from the Developer Portal is needed unless this build ships one.
Queue: songs added with Play next / Add to queue form an "Up next" section that always plays first; the rest is labelled "Next from: <list>". Click any queued song to continue from there.
Shuffle styles (Settings > Playback, or right-click Shuffle): smart shuffle spreads artists and moves recently heard songs back; fully random is uniform.
Right-click menus on player controls: mini player card/bar, repeat mode, shuffle style, seek 10/30 s and restart on previous/next, output device, channel mode and MPD on volume.
Spatial audio: choose Mono, Stereo or Spatial; Spatial keeps surround (5.1/7.1) speaker positions and renders them for headphones with an HRTF head model.
Play on a Music Player Daemon (MPD) on another computer, with Glyph as remote.
Opt-in listening statistics (time, plays, skips, top artists and songs, hours and weekdays), synced across signed-in devices; turning them off deletes them.
Lyrics: the current line stays centred and moves smoothly with an eased colour sweep; pick another lyrics version (remembered per song) and adjust timing in a new options panel; redesigned view switch.
Search lyrics: results found only through their lyrics appear in an "In lyrics" section. Search waits until you stop typing.
AI assistants (MCP): a local MCP server (127.0.0.1, token) or access through the signed-in server with OAuth sign-in and in-app approval; 27 tools for playback, queue, search, playlists, likes and lyrics.
YouTube: choose r-dlp (built in, default) or yt-dlp; native InnerTube search and a YouTube ID hint to the server make finding sources much faster.
Server downloads retry transient failures and fall back to another quality instead of failing.
Artist pages list the full discography from Deezer; verified badges appear next to artist names; an animated equalizer marks the playing song.
Sidebar shows followed artists; right-click an entry to hide it. Playing an artist adds only the artist to Recently played.
Add-to-playlist flyouts stay on screen with a 5 px gap and say "No playlists yet" when empty; playlist names are limited to 100 characters and long titles wrap.
List pages scroll under the top bar; the info column of a playlist scrolls in small windows; the queue panel has bottom padding on the lyrics page.
The background animation drops to 10 fps while Glyph is not focused (switchable); the window title follows the playing song while the app is in the background.
New languages: Español, Français, Italiano, Polski, Português, Türkçe, Українська.
/v1/import/spotify also reads SoundCloud links (sets, a profile's likes or tracks, single songs) with the server's SoundCloud key, so the app's "Transfer music" needs no key of its own.
Serve the documentation at docs.glyph.my (and /docs on other hosts), rendered from the Markdown in github.com/glyphmusic/docs at request time: a push to main is live within about a minute without a deploy. glyph.my/docs redirects there. Pages have a search (Ctrl+K or /, index at search.json); for LLMs there are llms.txt, llms-full.txt and every page as Markdown at its .md address.
Relay AI assistants (MCP) to signed-in desktop apps: Streamable HTTP endpoint /mcp, OAuth 2.1 with PKCE and dynamic client registration, a sign-in page confirmed in the app, and glyph remote mcp on|off for owners (migration 0014).
Search YouTube through InnerTube directly before falling back to yt-dlp, and accept the app's YouTube ID hint to skip the search.
Add /changelog: every release of the desktop app, server, companion and r-dlp, newest first, filterable by part (scripts/snapshot-changelogs.mjs).
Add a questions section to the landing page, with FAQ structured data.
Add glyph config list|get|set|unset|path to read and change server.toml with validation, sources and defaults; API keys are never printed.
Add glyph cloudflare list|set|unset|secret|domain to change a Cloudflare deployment's values, secrets and custom domain.
Serve lyrics from the companion first (POST /internal/lyrics) and fall back to the Worker's own lookup, so LRCLIB's rate limit on data-centre addresses no longer breaks lyrics.
Answer /v1/lyrics with "no lyrics" (404) when the upstream is rate-limited or down, instead of a 502/503; a failed lookup is retried after five minutes, a confirmed miss after an hour.
Answer /v1/similar with an empty list (200) when Last.fm is not configured or fails, instead of a 503/502.
Download YouTube audio through the configured server/companion path, using the same source resolution as playback.
Add a shared download queue: maximum five simultaneous downloads by default, configured only through audio.download_parallelism and audio.download_adaptive in TOML.
Adapt download admission to observed network throughput and stalled transfers, including local YouTube downloads.
Add Only YouTube in source settings, honoring Local/Server and returning unavailable instead of falling back to another provider or preview.
Prevent simultaneous downloads from sharing temporary output filenames.
Changes are recorded here for every release, newest first.
Resolve Worker cache misses on the companion (POST /internal/resolve), so the Worker parses one small answer instead of several provider searches. Without a companion, or when it is busy or offline, the Worker resolves itself as before.
Never share the admission queue between Worker requests. A permit handed across requests woke the waiter in the other request's context, which Cloudflare reported as hung requests and exceeded CPU limits.
Accept Audius' presigned R2 audio redirects (*.r2.cloudflarestorage.com) as redirect targets only; Audius playback and downloads returned HTTP 502.
Speculatively warm the first audio bytes of hovered songs, opened lists and upcoming queue tracks, with bounded background work and data-saver support.
Play saved downloads locally before any network request; check remote revisions in the background and replace changed audio only after a complete SHA-256-checked download.
Decode arriving HTTP ranges immediately, including after seeking. Keep received audio ranges in a bounded local disk cache for replays and loops.
Keep the seek cursor at its requested position while buffering, preload the next queue item early, and resume a prepared crossfade player when a seek skips the fade window.
Signed-in sharing copies short Glyph links for songs, artists and playlists, with rich previews and desktop deep links. Shared playlists open as a preview with an explicit Add to library action.
Prefetch HTTP audio blocks before the current buffer runs out, with larger startup and decoded reserves to prevent chunk-boundary pauses.
Enable Windows multimedia scheduling for the WASAPI callback to improve playback under load and when minimized.
Local yt-dlp playback starts from HTTP chunks while parallel background ranges fill the cache. Subsequent reads switch to the completed local file; downloaded songs remain immediate local playback.
Start streamable HTTP MP4 audio from its leading metadata instead of scanning every segment before playback; preserve byte-range seeking after initialization.
Give the playlist editor Save button the same 8 px corner radius as Follow. Keep it inactive gray until the name, cover or playlist switches differ from the opening state. Changed values enable a white Save button; reverting them disables it again.
Add 10 px of space above the Queue panel to separate it from the topbar.
New releases use one SHA256SUMS.txt for all assets. The updater selects the checksum by exact filename and also supports older per-asset checksum files. Older app versions need one manual upgrade to adopt this format.
Clicking outside Settings closes the modal and blocks interaction with controls underneath it.
Continue playback when a proxy changes from partial ranges to full audio responses. Validate returned byte ranges and keep small full responses seekable for MP3/ID3 probing.
Server: use the companion to search specifically for matching song audio before falling back to previews; serve consistent byte ranges from both cache hits and fresh media.
Recover audio outputs that accept a stream but never consume samples by retrying the same device with its negotiated buffer settings. Report a nonresponsive output instead of loading forever.
Add diagnostics around opening the output and queueing decoded audio.
Server fixes prepared alongside this build: retry full playback sources before reusing a Deezer preview; avoid redundant YouTube metadata requests and long cooldowns after transient YouTube failures.
Antivirus heuristic reports for the unsigned 0.2.1 installer remain under investigation; no clean VirusTotal result is claimed for this release.
Reuse three prestarted yt-dlp extractors in parallel, coalesce duplicate video lookups, and separate audio transfer capacity from metadata requests. Keep a bounded CLI fallback.
Preserve upstream ETags and modification dates so clients can check downloaded audio revisions without blocking playback.
Reuse resolved YouTube URLs in bounded companion memory, avoiding repeated yt-dlp extraction on seeks and audio refills without storing audio on disk.
Signed-in sharing copies short Glyph links for songs, artists and playlists, with rich previews and desktop deep links. Shared playlists open as a preview with an explicit Add to library action.
Avoid a Worker crash when a long cache key contains Unicode characters at the truncation boundary.
Start background quality preparation for partial audio responses and let companion encodes finish after a request disconnects.
Match YouTube by ISRC when available, then retry artist/title without the audio suffix if necessary (fixes Blender's LUVME falling back to a preview).
Prepare two quality variants concurrently in the background, keeping an encoder available for foreground work.
Forward requested byte ranges through the Worker and companion to YouTube, avoiding repeated downloads of the entire prefix when seeking or refilling the decoder.
Stream uncached high-quality YouTube audio immediately instead of waiting for a whole download and remux.
Publish one SHA256SUMS.txt for the complete release; self-update matches exact filenames and retains support for old sidecars.
Search for song audio through the configured companion when resolving a YouTube match; avoid unrelated video results and duration mismatches.
Explicitly slice full edge-cache hits for range requests; re-fetch entries missing the byte length instead of returning inconsistent audio responses.
Retry full playback sources before a cached Deezer preview and shorten preview caching to five minutes. Invalidate earlier resolver mappings.
Skip per-video metadata extraction when YouTube flat results already include duration.
Do not disable all YouTube requests for ten minutes after one network failure or timeout.
Send account authorization only once per request. Duplicate headers caused HTTP 400 responses in search, playback resolution, profiles and device management.
Show failures and retry actions for device and profile loading instead of leaving loading placeholders visible indefinitely.
Bound account-refresh waits and local yt-dlp status checks.
Normalize Windows shortcut paths so the app is registered as **Glyph**.
**Playback > Sources > YouTube playback**: choose **Local** yt-dlp or the **Server** companion. The choice is specific to each device. Local mode resolves YouTube before contacting the server; downloaded files always play locally.
A Windows setup executable with a stable installation folder, Start menu shortcut and uninstaller. New installations update the existing app rather than creating another versioned installation.
Playback startup diagnostics and a test for starting a downloaded track through the real audio output.
Improved library activity, account synchronization and private-server access handling.
Server request admission and abuse limits, persistent audio cache inventory, storage reservations and audio quality variants.
Stable releases for Windows x64, macOS Intel and Apple Silicon, and Linux x64 and ARM64, with SHA-256 checksums.
Route /download, screenshots, icons, the web manifest and crawler files through the Cloudflare Worker. This fixes missing landing-page images, the unavailable favicon and the download page's HTTP 522 response.
Initial published desktop release: music search, playback, lyrics, library and playlists, optional account synchronization, and portable application archives.
Initial server implementation, provider search and resolution, streaming audio, optional accounts and synchronization, Cloudflare Worker and native companion.