mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Make SpotifyId
understand more URI formats
This commit is contained in:
parent
6786c093ad
commit
b96405af82
3 changed files with 42 additions and 19 deletions
|
@ -13,14 +13,14 @@ use context::StationContext;
|
|||
use librespot_core::config::ConnectConfig;
|
||||
use librespot_core::mercury::MercuryError;
|
||||
use librespot_core::session::Session;
|
||||
use librespot_core::spotify_id::SpotifyId;
|
||||
use librespot_core::spotify_id::{SpotifyId, SpotifyIdError};
|
||||
use librespot_core::util::SeqGenerator;
|
||||
use librespot_core::version;
|
||||
use librespot_core::volume::Volume;
|
||||
use playback::mixer::Mixer;
|
||||
use playback::player::Player;
|
||||
use protocol;
|
||||
use protocol::spirc::{DeviceState, Frame, MessageType, PlayStatus, State};
|
||||
use protocol::spirc::{DeviceState, Frame, MessageType, PlayStatus, State, TrackRef};
|
||||
|
||||
pub struct SpircTask {
|
||||
player: Player,
|
||||
|
@ -797,7 +797,7 @@ impl SpircTask {
|
|||
}
|
||||
|
||||
fn update_tracks(&mut self, frame: &protocol::spirc::Frame) {
|
||||
// debug!("State: {:?}", frame.get_state());
|
||||
debug!("State: {:?}", frame.get_state());
|
||||
let index = frame.get_state().get_playing_track_index();
|
||||
let context_uri = frame.get_state().get_context_uri().to_owned();
|
||||
let tracks = frame.get_state().get_track();
|
||||
|
@ -813,31 +813,43 @@ impl SpircTask {
|
|||
self.state.set_shuffle(frame.get_state().get_shuffle());
|
||||
}
|
||||
|
||||
// should this be a method of SpotifyId directly?
|
||||
fn get_spotify_id_for_track(&self, track_ref: &TrackRef) -> Result<SpotifyId, SpotifyIdError> {
|
||||
SpotifyId::from_raw(track_ref.get_gid()).or_else(|_| {
|
||||
let uri = track_ref.get_uri();
|
||||
debug!("Malformed or no gid, attempting to parse URI <{}>", uri);
|
||||
SpotifyId::from_uri(uri)
|
||||
})
|
||||
}
|
||||
|
||||
fn load_track(&mut self, play: bool) {
|
||||
let context_uri = self.state.get_context_uri().to_owned();
|
||||
let index = self.state.get_playing_track_index();
|
||||
info!("context: {}", context_uri);
|
||||
// Redundant check here
|
||||
let track = if context_uri.contains(":show:") || context_uri.contains(":episode:") {
|
||||
let uri = self.state.get_track()[index as usize].get_uri();
|
||||
SpotifyId::from_uri(uri).expect("Unable to parse uri")
|
||||
} else {
|
||||
let mut index = self.state.get_playing_track_index();
|
||||
// Check for malformed gid
|
||||
let tracks_len = self.state.get_track().len() as u32;
|
||||
debug!(
|
||||
"Loading context: {} index: [{}] of {}",
|
||||
context_uri, index, tracks_len
|
||||
);
|
||||
// Tracks either have a gid or uri.
|
||||
// Context based frames sometimes use spotify:meta:page: that needs to be ignored.
|
||||
let track = {
|
||||
let mut track_ref = &self.state.get_track()[index as usize];
|
||||
while track_ref.get_gid().len() != 16 {
|
||||
let mut track_id = self.get_spotify_id_for_track(track_ref);
|
||||
while track_id.is_err() {
|
||||
warn!(
|
||||
"Skipping track {:?} at position [{}] of {}",
|
||||
track_ref.get_uri(),
|
||||
index,
|
||||
tracks_len
|
||||
);
|
||||
// This will keep looping over, instead we should cylce tracks only once
|
||||
index = if index + 1 < tracks_len { index + 1 } else { 0 };
|
||||
track_ref = &self.state.get_track()[index as usize];
|
||||
track_id = self.get_spotify_id_for_track(track_ref);
|
||||
}
|
||||
SpotifyId::from_raw(track_ref.get_gid()).unwrap()
|
||||
};
|
||||
track_id
|
||||
}
|
||||
.unwrap();
|
||||
|
||||
let position = self.state.get_position_ms();
|
||||
let end_of_track = self.player.load(track, play, position);
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::fmt;
|
|||
pub enum SpotifyAudioType {
|
||||
Track,
|
||||
Podcast,
|
||||
NonPlayable,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
@ -71,12 +72,18 @@ impl SpotifyId {
|
|||
|
||||
pub fn from_uri(uri: &str) -> Result<SpotifyId, SpotifyIdError> {
|
||||
let parts = uri.split(":").collect::<Vec<&str>>();
|
||||
if uri.contains(":show:") || uri.contains(":episode:") {
|
||||
let mut spotify_id = SpotifyId::from_base62(parts[2]).unwrap();
|
||||
let gid = parts.last().unwrap();
|
||||
if uri.contains(":episode:") {
|
||||
let mut spotify_id = SpotifyId::from_base62(gid).unwrap();
|
||||
let _ = std::mem::replace(&mut spotify_id.audio_type, SpotifyAudioType::Podcast);
|
||||
Ok(spotify_id)
|
||||
} else if uri.contains(":track:") {
|
||||
SpotifyId::from_base62(gid)
|
||||
} else {
|
||||
SpotifyId::from_base62(parts[2])
|
||||
// show/playlist/artist/album/??
|
||||
let mut spotify_id = SpotifyId::from_base62(gid).unwrap();
|
||||
let _ = std::mem::replace(&mut spotify_id.audio_type, SpotifyAudioType::NonPlayable);
|
||||
Ok(spotify_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ extern crate librespot_protocol as protocol;
|
|||
|
||||
pub mod cover;
|
||||
|
||||
use futures::future;
|
||||
use futures::Future;
|
||||
use linear_map::LinearMap;
|
||||
|
||||
|
@ -71,6 +72,9 @@ impl AudioItem {
|
|||
match id.audio_type {
|
||||
SpotifyAudioType::Track => Track::get_audio_item(session, id),
|
||||
SpotifyAudioType::Podcast => Episode::get_audio_item(session, id),
|
||||
SpotifyAudioType::NonPlayable => {
|
||||
Box::new(future::err::<AudioItem, MercuryError>(MercuryError))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue