Radio: an empty ICY StreamTitle blanks the playbar subtitle
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 86/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- rust
- Ambito
- audio-video-rtc, cli
Direzione di ricerca
Inizia da src/infra/radio/stream.rs, dove la callback IcyMetadataReader, intorno alla riga 157, salva meta.stream_title() così com'è nella cella now_playing. Aggiungi l'helper puro clean_stream_title descritto nell'issue e fai passare quella riga attraverso di esso, lasciando invariata la guardia if let Ok(meta). Esegui cargo test --no-default-features --features telemetry,tui,internet-radio stream_title e verifica che i quattro nuovi test compaiano come superati, e non solo filtrati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What
A lot of internet radio stations send an empty now-playing title between songs, during ads or jingles, and some send one all the time. On the wire that's StreamTitle=''; (and sometimes StreamTitle=' - ';). When that happens, the line under the station name in the radio playbar goes blank, or shows a bare -. The "artist" we hand to the OS media integrations (MPRIS, Windows media controls, macOS Now Playing, Discord) goes blank too.
How to reproduce:
- Build with radio support:
cargo run --no-default-features --features telemetry,tui,internet-radio(no Spotify account needed). - Pick the Radio source and tune in to a station. Stations that send empty titles between tracks or during ad breaks show it best.
- Watch the subtitle line in the playbar. When the station sends an empty title, the subtitle goes empty.
What should happen instead: when there's no real title, the subtitle should fall back to the station's genre tags, or to its country/codec/bitrate summary when there are no tags. The code already does this when the title is missing (None). It doesn't do it when the title is present but empty (Some("")).
The cause: the icy-metadata crate (0.6) turns StreamTitle=''; into Some(""), and our metadata callback stores that value as is. Both readers only fall back on None, so the empty string wins.
Where to look
src/infra/radio/stream.rs,open_radio_stream. Line 146 creates the shared celllet now_playing: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));. Lines 150-163 build theIcyMetadataReader, and its callback (lines 153-162) is the only place the cell gets written:
Line 157 is the one to change.move |meta| { // (existing comment about parse errors) if let Ok(meta) = meta { let title = meta.stream_title().map(str::to_owned); if let Ok(mut np) = cell.lock() { *np = title; } } },meta.stream_title()returnsOption<&str>.src/infra/radio/mod.rs, lines 93-95:now_playing_title()just clones whatever is in the cell. You don't need to change it.src/tui/ui/player.rs,draw_radio_playbar(starts at line 997). Lines 1003-1009 only fall back when the title isNone:let artists = radio.now_playing_title().unwrap_or_else(|| { if radio.station.artists.is_empty() { radio.station.album.clone() } else { radio.station.artists.join(", ") } });src/infra/media_metadata.rs, line 304: the same expression for the OS integrations.src/infra/radio/stream.rs,mod tests(lines 178-282): it has two network tests,live_stream_opens_with_icy_metadataandlive_stream_plays_through_sink. Both are#[ignore], so a normalcargo testnever touches the network. Your new tests go in this module.
Possible solution
-
Add a small pure function in
src/infra/radio/stream.rs(above the#[cfg(test)]module is a good spot) that turns the raw title into the value we want to store:/// The title to show, or `None` when the station sent a blank one. fn clean_stream_title(raw: Option<&str>) -> Option<String> { let trimmed = raw?.trim(); if trimmed.chars().all(|c| c == '-' || c.is_whitespace()) { None } else { Some(trimmed.to_string()) } }allon an empty string returnstrue, so""is covered too. Then change line 157 tolet title = clean_stream_title(meta.stream_title());. -
Fix it at this one write site only. Both readers (the playbar and
media_metadata.rs) and anything else that reads the cell then fall back correctly with no other change. Please don't add a second cleanup innow_playing_title()or in the readers. One cleaning point is enough. -
Keep the
if let Ok(meta) = metaguard exactly as it is: a block that fails to parse must still keep the last good title. Only a block that parses fine but carries an empty title should clear the cell toNone. That matches what already happens today for a block with noStreamTitleat all. -
A station whose real title is literally
-loses it. That's fine. -
Leave the existing comments alone. Also don't touch the connect/header/probe timeouts in this file (
src/infra/radio/AGENTS.mdexplains why they're there). -
The whole radio module sits behind the
internet-radiofeature, so the plain slim build doesn't compile your change at all. Build and test withinternet-radioon. -
Tests: add plain
#[test]functions (nottokio::test, there's nothing async here) tomod testsinstream.rs. They need no network, account or audio device. Suggested names:empty_stream_title_clears_to_none:clean_stream_title(Some(""))andclean_stream_title(Some(" "))giveNonedash_only_stream_title_clears_to_none:Some(" - ")andSome("-")giveNonemissing_stream_title_stays_none:NonegivesNonereal_stream_title_is_trimmed_and_kept:Some(" Daft Punk - Get Lucky ")givesSome("Daft Punk - Get Lucky".to_string())
Keep the word
stream_titlein every test name so the filter below picks them all up. -
CI runs clippy on the bin target only, so run cargo test to compile test code.
-
Leave tools/gates.count alone, new tests need no counter change.
Done when
cargo test --no-default-features --features telemetry,tui,internet-radio stream_titleruns your new tests and they pass. A filter that matches nothing still exits 0, so check the count: the summary should list your tests as passed, not just "N filtered out".- Manual check (no Spotify account needed): run
cargo run --no-default-features --features telemetry,tui,internet-radio, tune in to a station that sends empty titles between songs, and check that the playbar subtitle shows the station's tags or summary instead of going blank. - cargo fmt --all -- --check, cargo clippy --no-default-features --features telemetry,tui -- -D warnings and cargo test --no-default-features --features telemetry,tui pass, plus
cargo clippy --no-default-features --features telemetry,tui,internet-radio -- -D warningsand theinternet-radiotest command above.
- Lingua principale
- Rust
- Stelle
- 1.4k
- Fork
- 238
- Merge medio
- 9h 19m
- PR unite (30g)
- 186
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di LargeModGames/spotatui
-
enhancement good first issue javascript
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
LargeModGames/spotatui#841 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement good first issue javascript
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
LargeModGames/spotatui#838 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
documentation good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
LargeModGames/spotatui#832 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
LargeModGames/spotatui#829 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
LargeModGames/spotatui#827 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di LargeModGames/spotatui
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
ActivityWatch/aw-notify-rs#47 · 1 commento ·
-
`inverse()` of a controlled `CUGate` drops the phase parameter γForse già presa @rupasri118 l’ha presa oggi. Apertabug mod: circuit
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
Qiskit/qiskit#17223 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 84/100
I maintainer di solito rispondono entro 2 giorni
-
agent:triaged bug bughunt pm:bundler priority:p1
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
SocketDev/socket-patch#1573 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
rustix::termios::Termios::OutputModes does not expost some const e.g. OLCUC for musl and macOSAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
bytecodealliance/rustix#1706 · 1 commento ·
I maintainer di solito rispondono entro 11 giorni