mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
34b4445c13
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>
86 lines
2.9 KiB
TOML
86 lines
2.9 KiB
TOML
[package]
|
|
name = "psysonic"
|
|
version = "1.34.12"
|
|
description = "Psysonic Desktop Music Player"
|
|
authors = []
|
|
license = ""
|
|
repository = ""
|
|
default-run = "psysonic"
|
|
edition = "2021"
|
|
rust-version = "1.89"
|
|
|
|
[lib]
|
|
name = "psysonic_lib"
|
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
|
|
[[bin]]
|
|
name = "psysonic"
|
|
path = "src/main.rs"
|
|
|
|
[build-dependencies]
|
|
tauri-build = { version = "2", features = [] }
|
|
|
|
[dependencies]
|
|
tauri = { version = "2", features = ["tray-icon", "image-png"] }
|
|
tauri-plugin-single-instance = "2"
|
|
tauri-plugin-shell = "2"
|
|
tauri-plugin-global-shortcut = "2"
|
|
tauri-plugin-store = "2"
|
|
tauri-plugin-dialog = "2"
|
|
tauri-plugin-fs = "2"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
rodio = { version = "0.19", default-features = false, features = ["symphonia-all"] }
|
|
symphonia = { version = "0.5", default-features = false, features = ["flac", "mp3", "pcm", "aac", "alac", "isomp4", "vorbis", "ogg", "wav", "adpcm"] }
|
|
reqwest = { version = "0.12", default-features = false, features = ["stream", "json", "multipart", "rustls-tls", "rustls-tls-native-roots", "blocking"] }
|
|
futures-util = "0.3"
|
|
md5 = "0.7"
|
|
tokio = { version = "1", features = ["rt", "time", "sync"] }
|
|
biquad = "0.4"
|
|
ringbuf = "0.3"
|
|
tauri-plugin-window-state = "2.4.1"
|
|
tauri-plugin-process = "2"
|
|
souvlaki = { version = "0.8", default-features = false, features = ["use_zbus"] }
|
|
discord-rich-presence = "0.2"
|
|
url = "2"
|
|
thread-priority = "1"
|
|
lofty = "0.22"
|
|
sysinfo = { version = "0.33", default-features = false, features = ["disk"] }
|
|
id3 = "1.16.4"
|
|
symphonia-adapter-libopus = "0.2.7"
|
|
|
|
[target.'cfg(unix)'.dependencies]
|
|
libc = "0.2"
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
zbus = { version = "5.9", default-features = false, features = ["blocking-api"] }
|
|
|
|
[target.'cfg(windows)'.dependencies]
|
|
windows = { version = "0.58", features = [
|
|
"Win32_Foundation",
|
|
"Win32_Graphics",
|
|
"Win32_Graphics_Gdi",
|
|
"Win32_System_Com",
|
|
"Win32_UI_Controls",
|
|
"Win32_UI_Shell",
|
|
"Win32_UI_WindowsAndMessaging",
|
|
] }
|
|
|
|
[patch.crates-io]
|
|
# Local patch for Symphonia's isomp4 demuxer:
|
|
# - Fixes descriptor.unwrap() panic on malformed esds atoms (older iTunes M4A)
|
|
# - Tolerates SL predefined=0x01 (null) used by some older iTunes-purchased files
|
|
# - Gracefully skips malformed trak atoms (e.g. MJPEG cover-art streams) instead
|
|
# of failing the entire probe
|
|
symphonia-format-isomp4 = { path = "patches/symphonia-format-isomp4" }
|
|
|
|
# Local patch for cpal's CoreAudio backend on macOS:
|
|
# - Forces IOType::DefaultOutput for all output streams so that macOS never
|
|
# triggers the TCC microphone-permission prompt. Upstream cpal uses
|
|
# IOType::HalOutput when the user pins a non-default device, which routes
|
|
# through AUHAL — that component is flagged as input-capable and triggers
|
|
# the mic consent dialog on first launch / after each update.
|
|
# - Tradeoff: output-device selection is a no-op on macOS (stream follows
|
|
# system default). Surfaced in the Settings UI.
|
|
cpal = { path = "patches/cpal-0.15.3" }
|