use serde::Deserialize;
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct Station {
pub name: String,
pub url: String,
pub genre: String,
pub country: String,
pub bitrate: u32,
}
#[derive(Debug, Deserialize)]
struct ApiBrowseStation {
name: String,
#[serde(rename = "url_resolved")]
url_resolved: String,
tags: String,
country: String,
bitrate: u32,
}
pub fn fallback_stations() -> Vec<Station> {
vec![
Station {
name: "Nightride FM".into(),
url: "https://stream.nightride.fm/nightride.m4a".into(),
genre: "Synthwave".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "NightWave Plaza".into(),
url: "https://radio.plaza.one/mp3".into(),
genre: "Vaporwave".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "SomaFM: Groove Salad".into(),
url: "https://ice2.somafm.com/groovesalad-128-mp3".into(),
genre: "Ambient".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "SomaFM: DEF CON".into(),
url: "https://ice2.somafm.com/defcon-128-mp3".into(),
genre: "Synthwave".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "SomaFM: Space Station".into(),
url: "https://ice2.somafm.com/spacestation-128-mp3".into(),
genre: "Ambient Space".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "SomaFM: Vaporwaves".into(),
url: "https://ice2.somafm.com/vaporwaves-128-mp3".into(),
genre: "Vaporwave".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "Nightride FM: Chillsynth".into(),
url: "https://stream.nightride.fm/chillsynth.m4a".into(),
genre: "Chillsynth".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "Nightride FM: Ebsylon".into(),
url: "https://stream.nightride.fm/ebsylon.m4a".into(),
genre: "Darksynth".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "SomaFM: Underground 80s".into(),
url: "https://ice2.somafm.com/u80s-128-mp3".into(),
genre: "80s".into(),
country: "US".into(),
bitrate: 128,
},
Station {
name: "SomaFM: Drone Zone".into(),
url: "https://ice2.somafm.com/dronezone-128-mp3".into(),
genre: "Drone Ambient".into(),
country: "US".into(),
bitrate: 128,
},
]
}
pub async fn search_stations(query: &str) -> anyhow::Result<Vec<Station>> {
if query.len() < 2 {
return Ok(Vec::new());
}
let client = reqwest::Client::builder()
.user_agent("DriftFM/0.1.0")
.timeout(std::time::Duration::from_secs(5))
.build()?;
let url = format!(
"https://de1.api.radio-browser.info/json/stations/search?name={}&hidebroken=true&order=clickcount&reverse=true&limit=20",
query
);
let resp = client.get(&url).send().await?;
let api_stations = resp.json::<Vec<ApiBrowseStation>>().await?;
let stations = api_stations
.into_iter()
.filter(|s| !s.url_resolved.is_empty())
.map(|s| Station {
name: s.name.trim().to_string(),
url: s.url_resolved,
genre: s.tags
.split(',')
.next()
.unwrap_or("Radio")
.trim()
.to_string(),
country: s.country,
bitrate: s.bitrate,
})
.collect();
Ok(stations)
}