podcast support (#203)
* implement search for shows/podcasts * create Playable supertype for queue to contain tracks and episodes * wip: implement playback of episodes * load spotify id from uri instead of raw id to fix podcast playback * show duration for podcast episodes * implement generic status bar for playables (tracks and episodes) omit saved indicator for now as the library does not yet support podcasts * instead of only the last 50 fetch all episodes of a show * refactor: extract Playable code to separate file * implement playback/queuing of shows + sharing url * implement podcast library * migrate mpris code to Playable supertype
This commit is contained in:
committed by
GitHub
parent
8bf06147e2
commit
1b1d392ab8
74
src/mpris.rs
74
src/mpris.rs
@@ -9,13 +9,15 @@ use dbus::tree::{Access, Factory};
|
||||
use dbus::{Path, SignalArgs};
|
||||
|
||||
use crate::album::Album;
|
||||
use crate::playable::Playable;
|
||||
use crate::playlist::Playlist;
|
||||
use crate::queue::{Queue, RepeatSetting};
|
||||
use crate::spotify::{PlayerEvent, Spotify, URIType};
|
||||
use crate::track::Track;
|
||||
use crate::traits::ListItem;
|
||||
|
||||
type Metadata = HashMap<String, Variant<Box<dyn RefArg>>>;
|
||||
struct MprisState(String, Option<Track>);
|
||||
struct MprisState(String, Option<Playable>);
|
||||
|
||||
fn get_playbackstatus(spotify: Arc<Spotify>) -> String {
|
||||
match spotify.get_current_status() {
|
||||
@@ -26,18 +28,18 @@ fn get_playbackstatus(spotify: Arc<Spotify>) -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn get_metadata(track: Option<Track>) -> Metadata {
|
||||
fn get_metadata(playable: Option<Playable>) -> Metadata {
|
||||
let mut hm: Metadata = HashMap::new();
|
||||
let track = track.as_ref();
|
||||
let playable = playable.as_ref();
|
||||
|
||||
hm.insert(
|
||||
"mpris:trackid".to_string(),
|
||||
Variant(Box::new(
|
||||
track
|
||||
playable
|
||||
.map(|t| {
|
||||
format!(
|
||||
"spotify:track:{}",
|
||||
t.id.clone().unwrap_or_else(|| "0".to_string())
|
||||
t.id().unwrap_or_else(|| "0".to_string())
|
||||
)
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
@@ -46,47 +48,77 @@ fn get_metadata(track: Option<Track>) -> Metadata {
|
||||
hm.insert(
|
||||
"mpris:length".to_string(),
|
||||
Variant(Box::new(i64::from(
|
||||
track.map(|t| t.duration * 1_000).unwrap_or(0),
|
||||
playable.map(|t| t.duration() * 1_000).unwrap_or(0),
|
||||
))),
|
||||
);
|
||||
hm.insert(
|
||||
"mpris:artUrl".to_string(),
|
||||
Variant(Box::new(
|
||||
track.map(|t| t.cover_url.clone()).unwrap_or_default(),
|
||||
playable
|
||||
.map(|t| t.cover_url().unwrap_or_default())
|
||||
.unwrap_or_default(),
|
||||
)),
|
||||
);
|
||||
|
||||
hm.insert(
|
||||
"xesam:album".to_string(),
|
||||
Variant(Box::new(track.map(|t| t.album.clone()).unwrap_or_default())),
|
||||
Variant(Box::new(
|
||||
playable
|
||||
.and_then(|p| p.track())
|
||||
.map(|t| t.album.clone())
|
||||
.unwrap_or_default(),
|
||||
)),
|
||||
);
|
||||
hm.insert(
|
||||
"xesam:albumArtist".to_string(),
|
||||
Variant(Box::new(
|
||||
track.map(|t| t.album_artists.clone()).unwrap_or_default(),
|
||||
playable
|
||||
.and_then(|p| p.track())
|
||||
.map(|t| t.album_artists.clone())
|
||||
.unwrap_or_default(),
|
||||
)),
|
||||
);
|
||||
hm.insert(
|
||||
"xesam:artist".to_string(),
|
||||
Variant(Box::new(
|
||||
track.map(|t| t.artists.clone()).unwrap_or_default(),
|
||||
playable
|
||||
.and_then(|p| p.track())
|
||||
.map(|t| t.artists.clone())
|
||||
.unwrap_or_default(),
|
||||
)),
|
||||
);
|
||||
hm.insert(
|
||||
"xesam:discNumber".to_string(),
|
||||
Variant(Box::new(track.map(|t| t.disc_number).unwrap_or(0))),
|
||||
Variant(Box::new(
|
||||
playable
|
||||
.and_then(|p| p.track())
|
||||
.map(|t| t.disc_number)
|
||||
.unwrap_or(0),
|
||||
)),
|
||||
);
|
||||
hm.insert(
|
||||
"xesam:title".to_string(),
|
||||
Variant(Box::new(track.map(|t| t.title.clone()).unwrap_or_default())),
|
||||
Variant(Box::new(
|
||||
playable
|
||||
.map(|t| match t {
|
||||
Playable::Track(t) => t.title.clone(),
|
||||
Playable::Episode(ep) => ep.name.clone(),
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
)),
|
||||
);
|
||||
hm.insert(
|
||||
"xesam:trackNumber".to_string(),
|
||||
Variant(Box::new(track.map(|t| t.track_number).unwrap_or(0) as i32)),
|
||||
Variant(Box::new(
|
||||
playable
|
||||
.and_then(|p| p.track())
|
||||
.map(|t| t.track_number)
|
||||
.unwrap_or(0) as i32,
|
||||
)),
|
||||
);
|
||||
hm.insert(
|
||||
"xesam:url".to_string(),
|
||||
Variant(Box::new(track.map(|t| t.url.clone()).unwrap_or_default())),
|
||||
Variant(Box::new(playable.map(|t| t.uri()).unwrap_or_default())),
|
||||
);
|
||||
|
||||
hm
|
||||
@@ -411,7 +443,11 @@ fn run_dbus_server(spotify: Arc<Spotify>, queue: Arc<Queue>, rx: mpsc::Receiver<
|
||||
if let Some(a) = spotify.album(&id) {
|
||||
if let Some(t) = &Album::from(&a).tracks {
|
||||
queue.clear();
|
||||
let index = queue.append_next(t.iter().collect());
|
||||
let index = queue.append_next(
|
||||
t.iter()
|
||||
.map(|track| Playable::Track(track.clone()))
|
||||
.collect(),
|
||||
);
|
||||
queue.play(index, false, false)
|
||||
}
|
||||
}
|
||||
@@ -419,7 +455,7 @@ fn run_dbus_server(spotify: Arc<Spotify>, queue: Arc<Queue>, rx: mpsc::Receiver<
|
||||
Some(URIType::Track) => {
|
||||
if let Some(t) = spotify.track(&id) {
|
||||
queue.clear();
|
||||
queue.append(&Track::from(&t));
|
||||
queue.append(Playable::Track(Track::from(&t)));
|
||||
queue.play(0, false, false)
|
||||
}
|
||||
}
|
||||
@@ -430,7 +466,11 @@ fn run_dbus_server(spotify: Arc<Spotify>, queue: Arc<Queue>, rx: mpsc::Receiver<
|
||||
playlist.load_tracks(spotify);
|
||||
if let Some(t) = &playlist.tracks {
|
||||
queue.clear();
|
||||
let index = queue.append_next(t.iter().collect());
|
||||
let index = queue.append_next(
|
||||
t.iter()
|
||||
.map(|track| Playable::Track(track.clone()))
|
||||
.collect(),
|
||||
);
|
||||
queue.play(index, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user