mpris_async/
lib.rs

1//! # mpris-async
2//!
3//! Async version of the [`mpris`] crate. 
4//!
5//! Provides async versions of [`PlayerEvents`](mpris::PlayerEvents), [`PlayerFinder`](mpris::PlayerFinder),
6//! and [`ProgressTracker`](mpris::ProgressTracker).
7//!
8//! # Get started 
9//! Easiest way to get started with mpris is using [`get_active_player`] and then using
10//! [`events::PlayerEventsStream`] to track changes.
11
12pub mod player;
13pub mod events;
14pub mod progress;
15pub mod fake_progress;
16pub use mpris::{Player, Progress, Metadata, TrackList, TrackID};
17
18use std::time::Duration;
19use crate::player::PlayerStream;
20
21use async_std::task;
22
23use mpris::{DBusError, FindingError, PlayerFinder};
24
25/// Gets the most active player. If no player exists, this function will wait until one does.
26/// Based of off [`PlayerFinder::find_active`](PlayerFinder::find_active)
27pub async fn get_active_player(retry_delay: u64) -> Result<Player, DBusError> {
28    let finder = match PlayerFinder::new() {
29        Ok(x) => x,
30        Err(_) => return  Err(DBusError::Miscellaneous("Could not create player finder. Is DBus running?".to_string())),
31    };
32    loop {
33        let player = match finder.find_active() {
34            Ok(player) => player,
35            Err(FindingError::NoPlayerFound) => {
36                task::sleep(Duration::from_millis(retry_delay)).await;
37                continue
38            },
39            Err(FindingError::DBusError(x)) => return Err(x),
40        };
41        return Ok(player);
42    }
43}
44
45/// Gets the first player. If no player exists, this function will wait until one does.
46/// Based of off [`PlayerFinder::find_first`](PlayerFinder::find_first)
47pub async fn get_first_player(retry_delay: u64) -> Result<Player, DBusError> {
48    let finder = match PlayerFinder::new() {
49        Ok(x) => x,
50        Err(_) => return  Err(DBusError::Miscellaneous("Could not create player finder. Is DBus running?".to_string())),
51    };
52    loop {
53        let player = match finder.find_first() {
54            Ok(player) => player,
55            Err(FindingError::NoPlayerFound) => {
56                task::sleep(Duration::from_millis(retry_delay)).await;
57                continue
58            },
59            Err(FindingError::DBusError(x)) => return Err(x),
60        };
61        return Ok(player);
62    }
63}
64
65/// Gets all of the avaliable players. If no player exists, this function will wait until one does.
66/// Every `retry_delay` milliseconds it will try for a new connection.
67/// Based of off [`PlayerFinder::find_all`](PlayerFinder::find_all)
68pub async fn get_players(retry_delay: u64) -> Result<Vec<Player>, DBusError> {
69    let finder = match PlayerFinder::new() {
70        Ok(x) => x,
71        Err(_) => return  Err(DBusError::Miscellaneous("Could not create player finder. Is DBus running?".to_string())),
72    };
73    loop {
74        let player = match finder.find_all() {
75            Ok(player) => player,
76            Err(FindingError::NoPlayerFound) => {
77                task::sleep(Duration::from_millis(retry_delay)).await;
78                continue
79            },
80            Err(FindingError::DBusError(x)) => return Err(x),
81        };
82        return Ok(player);
83    }
84}
85
86/// Creates a stream of Players. Unlike mpris::PlayerFinder::iter_players, this function will keep
87/// checking for more players forever.
88pub fn stream_players(retry_delay: u64) -> PlayerStream {
89    return PlayerStream::new(retry_delay);
90}