use std::collections::HashSet;
use std::thread;
use std::time::Duration;
use mpris::{PlaybackStatus, Player, PlayerFinder};
use crate::config::Config;
const INIT_WAIT_TIME: Duration = Duration::from_secs(1);
const BUS_NAME_PREFIX: &str = "org.mpris.MediaPlayer2.";
pub fn is_active(player: &Player) -> bool {
if !player.is_running() {
return false;
}
matches!(player.get_playback_status(), Ok(PlaybackStatus::Playing))
}
fn is_bus_name_whitelisted(player: &Player, whitelist: &HashSet<String>) -> bool {
let bus_name = player.bus_name().trim_start_matches(BUS_NAME_PREFIX);
let without_instance = bus_name
.rsplit_once('.')
.map(|(name, _instance)| name)
.unwrap_or(bus_name);
whitelist.contains(bus_name) || whitelist.contains(without_instance)
}
fn is_whitelisted(config: &Config, player: &Player) -> bool {
if let Some(ref whitelist) = config.player_whitelist {
if !whitelist.is_empty() {
return whitelist.contains(player.identity())
|| is_bus_name_whitelisted(player, whitelist);
}
}
true
}
pub fn wait_for_player(config: &Config, finder: &PlayerFinder) -> Player {
loop {
let players = match finder.iter_players() {
Ok(players) => players,
_ => {
thread::sleep(INIT_WAIT_TIME);
continue;
}
};
#[allow(clippy::manual_flatten)]
for player in players {
if let Ok(player) = player {
if is_active(&player) && is_whitelisted(config, &player) {
return player;
}
}
}
thread::sleep(INIT_WAIT_TIME);
}
}