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:
Henrik Friedrichsen
2020-07-14 10:38:22 +02:00
committed by GitHub
parent 8bf06147e2
commit 1b1d392ab8
19 changed files with 723 additions and 115 deletions

View File

@@ -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)
}
}