mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
feat(lyrics): YouLyPlus karaoke + fix(macos): suppress mic prompt
Two independent user-facing fixes rolled together. ── Lyrics: YouLyPlus provider (issue #172) ── Adds word-by-word synced (karaoke) lyrics as an alternative lyrics mode. Backed by the public lyricsplus aggregator (Apple Music / Spotify / Musixmatch / QQ Music) — no API keys on our side, subscription costs are borne by the backend operator. Five mirrors are tried on network failure. Settings → Lyrics now exposes a mode radio (Standard vs YouLyPlus) plus a static-only toggle. YouLyPlus misses silently fall back to the existing server + LRCLIB + Netease pipeline so obscure tracks still resolve. The drag-to-reorder source list is hidden in YouLyPlus mode since the external aggregator manages its own source priority. Rendering: per-word spans on each line, active word highlighted with accent-tinted glow. Subscribed imperatively via usePlayerStore.subscribe so 500 ms progress ticks do not re-render the whole lyrics block. The Fullscreen Player reuses the same pattern; the 5-line rail layout is unchanged. white-space: pre on .fs-lyric-word preserves the trailing spaces the API embeds in each syllabus token (flex context would otherwise collapse them). i18n: new keys in all 8 locales (de, en, fr, nl, nb, ru, es, zh). ── macOS mic-prompt suppression ── Ships a vendored cpal 0.15.3 at patches/cpal-0.15.3/ wired via [patch.crates-io]. The only change is in src/host/coreaudio/macos/mod.rs: audio_unit_from_device now unconditionally uses IOType::DefaultOutput for output streams instead of conditionally choosing HalOutput. AUHAL (HalOutput) is classified as input-capable by macOS TCC and triggers the microphone-permission dialog at first launch / after each update even for playback-only apps. Previous attempts (removing NSMicrophoneUsageDescription, setting com.apple.security.device.audio-input false in Entitlements.plist) did not suppress the prompt because TCC fires at AudioUnit instantiation, not at plist level. The upstream fix in cpal PR #1070 / cpal 0.17 only helps when the pinned device equals the system default; always-DefaultOutput covers all cases. Tradeoff: per-device output selection is a no-op on macOS — the stream always follows the system default. Settings.tsx surfaces this via audioOutputDeviceMacNotice (hides the CustomSelect on macOS) and skips audio_list_devices + device-watcher effects there. Matches the behaviour of Apple Music / Spotify on macOS. Also removes the now-obsolete com.apple.security.device.audio-input entitlement (sandbox is disabled anyway, so it was ignored). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2694,6 +2694,33 @@
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* Word-sync (karaoke) mode — per-word highlight inside the active line.
|
||||
The parent `.lyrics-line.active` colour is overridden: only `.active` / `.played`
|
||||
words carry accent tint, the remaining words stay at the line's base colour. */
|
||||
.lyrics-word-synced .lyrics-line {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.lyrics-word-synced .lyrics-line.active {
|
||||
color: var(--text-secondary); /* line colour neutralised; words decide */
|
||||
}
|
||||
.lyrics-word-synced .lyrics-line.completed {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.lyrics-word {
|
||||
display: inline;
|
||||
transition: color 0.18s ease;
|
||||
color: inherit;
|
||||
}
|
||||
.lyrics-word.played {
|
||||
color: var(--accent);
|
||||
opacity: 0.65;
|
||||
}
|
||||
.lyrics-word.active {
|
||||
color: var(--accent);
|
||||
opacity: 1;
|
||||
text-shadow: 0 0 14px color-mix(in srgb, var(--accent) 55%, transparent);
|
||||
}
|
||||
|
||||
.lyrics-plain {
|
||||
padding: 4px 0 16px;
|
||||
}
|
||||
@@ -3555,6 +3582,28 @@
|
||||
transform: scaleX(1.015); /* subtle compositor-only emphasis, no layout cost */
|
||||
}
|
||||
|
||||
/* Fullscreen word-sync (karaoke). Parent .fsl-active base colour stays dim so
|
||||
only the .active/.played words pop. */
|
||||
.fs-lyric-line.fsl-active .fs-lyric-word {
|
||||
color: rgba(255, 255, 255, 0.35);
|
||||
text-shadow: none;
|
||||
}
|
||||
.fs-lyric-word {
|
||||
display: inline;
|
||||
/* Preserve the trailing space the lyricsplus API embeds in each syllabus
|
||||
token (`"Gina "`, `"dreams "`, …). Without this the flex formatting
|
||||
context collapses it and words run together. */
|
||||
white-space: pre;
|
||||
transition: color 0.18s ease, text-shadow 0.18s ease;
|
||||
}
|
||||
.fs-lyric-line.fsl-active .fs-lyric-word.played {
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
.fs-lyric-line.fsl-active .fs-lyric-word.active {
|
||||
color: #ffffff;
|
||||
text-shadow: 0 0 28px var(--accent-glow, var(--accent)), 0 1px 8px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
|
||||
/* ── no-compositing overrides ─────────────────────────────────────────────────
|
||||
Applied only when WEBKIT_DISABLE_COMPOSITING_MODE=1 is set (Arch Linux etc).
|
||||
|
||||
Reference in New Issue
Block a user