mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
parent
8d8aad8191
commit
dde613e0a0
3 changed files with 106 additions and 68 deletions
48
Cargo.lock
generated
48
Cargo.lock
generated
|
@ -4,14 +4,14 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dns-sd 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"eventual 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"json_macros 0.3.0 (git+https://github.com/plietar/json_macros)",
|
||||
"lazy_static 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)",
|
||||
"librespot-protocol 0.1.0",
|
||||
"lmdb-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -37,7 +37,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -91,7 +91,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.0.63"
|
||||
version = "0.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -103,7 +103,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"openssl 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -127,7 +127,7 @@ version = "0.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.67 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.69 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -142,7 +142,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.27"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -176,7 +176,7 @@ name = "hyper"
|
|||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cookie 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -230,7 +230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -284,7 +284,7 @@ dependencies = [
|
|||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"liblmdb-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.67 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.69 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -397,7 +397,7 @@ name = "ogg-sys"
|
|||
version = "0.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -408,8 +408,8 @@ version = "0.7.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys-extras 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -432,7 +432,7 @@ name = "openssl-sys-extras"
|
|||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -479,7 +479,7 @@ name = "protobuf_build"
|
|||
version = "0.1.1"
|
||||
source = "git+https://github.com/plietar/rust-protobuf-build.git#77ea08e75b66433104a035309751d48170a7aed6"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"protobuf 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -528,10 +528,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.67"
|
||||
version = "0.1.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aho-corasick 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -559,7 +559,7 @@ name = "rust-crypto"
|
|||
version = "0.2.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -607,7 +607,7 @@ name = "shannon-sys"
|
|||
version = "0.1.0"
|
||||
source = "git+https://github.com/plietar/rust-shannon#7000b3e49a53daaa890727ba2b2bd5a43cc4ffef"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -741,7 +741,7 @@ name = "tremor-sys"
|
|||
version = "0.1.0"
|
||||
source = "git+https://github.com/plietar/rust-tremor#5ced876f3cffb041fcf31238da7f3273178029fe"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -786,7 +786,7 @@ dependencies = [
|
|||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -814,7 +814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -845,7 +845,7 @@ name = "vorbis-sys"
|
|||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -856,7 +856,7 @@ name = "vorbisfile-sys"
|
|||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -31,7 +31,7 @@ pub trait MetadataTrait : Send + 'static {
|
|||
fn parse(msg: &Self::Message, session: &Session) -> Self;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Track {
|
||||
pub id: SpotifyId,
|
||||
pub name: String,
|
||||
|
@ -42,7 +42,7 @@ pub struct Track {
|
|||
pub available: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Album {
|
||||
pub id: SpotifyId,
|
||||
pub name: String,
|
||||
|
@ -51,7 +51,7 @@ pub struct Album {
|
|||
pub covers: Vec<FileId>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Artist {
|
||||
pub id: SpotifyId,
|
||||
pub name: String,
|
||||
|
|
102
src/player.rs
102
src/player.rs
|
@ -9,7 +9,7 @@ use audio_decrypt::AudioDecrypt;
|
|||
use audio_backend::Sink;
|
||||
use metadata::{FileFormat, Track, TrackRef};
|
||||
use session::{Bitrate, Session};
|
||||
use util::{self, SpotifyId, Subfile};
|
||||
use util::{self, ReadSeek, SpotifyId, Subfile};
|
||||
pub use spirc::PlayStatus;
|
||||
|
||||
#[cfg(not(feature = "with-tremor"))]
|
||||
|
@ -162,6 +162,56 @@ fn apply_volume(volume: u16, data: &[i16]) -> Cow<[i16]> {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_available_alternative<'a>(session: &Session, track: &'a Track) -> Option<Cow<'a, Track>> {
|
||||
if track.available {
|
||||
Some(Cow::Borrowed(track))
|
||||
} else {
|
||||
let alternatives = track.alternatives
|
||||
.iter()
|
||||
.map(|alt_id| {
|
||||
session.metadata::<Track>(*alt_id)
|
||||
})
|
||||
.collect::<Vec<TrackRef>>();
|
||||
|
||||
eventual::sequence(alternatives.into_iter()).iter().find(|alt| alt.available).map(Cow::Owned)
|
||||
}
|
||||
}
|
||||
|
||||
fn load_track(session: &Session, track_id: SpotifyId) -> Option<vorbis::Decoder<Subfile<AudioDecrypt<Box<ReadSeek>>>>> {
|
||||
let track = session.metadata::<Track>(track_id).await().unwrap();
|
||||
|
||||
let track = match find_available_alternative(session, &track) {
|
||||
Some(track) => track,
|
||||
None => {
|
||||
warn!("Track \"{}\" is not available", track.name);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let format = match session.config().bitrate {
|
||||
Bitrate::Bitrate96 => FileFormat::OGG_VORBIS_96,
|
||||
Bitrate::Bitrate160 => FileFormat::OGG_VORBIS_160,
|
||||
Bitrate::Bitrate320 => FileFormat::OGG_VORBIS_320,
|
||||
};
|
||||
|
||||
|
||||
|
||||
let file_id = match track.files.iter().find(|&&(_, f)| f == format) {
|
||||
Some(&(file_id, _)) => file_id,
|
||||
None => {
|
||||
warn!("Track \"{}\" is not available in format {:?}", track.name, format);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let key = session.audio_key(track.id, file_id).await().unwrap();
|
||||
|
||||
let audio_file = Subfile::new(AudioDecrypt::new(key, session.audio_file(file_id)), 0xa7);
|
||||
let decoder = vorbis::Decoder::new(audio_file).unwrap();
|
||||
|
||||
Some(decoder)
|
||||
}
|
||||
|
||||
impl PlayerInternal {
|
||||
fn run(self, sink: Box<Sink>) {
|
||||
let mut decoder = None;
|
||||
|
@ -189,37 +239,9 @@ impl PlayerInternal {
|
|||
});
|
||||
drop(decoder);
|
||||
|
||||
let mut track = self.session.metadata::<Track>(track_id).await().unwrap();
|
||||
|
||||
if !track.available {
|
||||
let alternatives = track.alternatives
|
||||
.iter()
|
||||
.map(|alt_id| {
|
||||
self.session.metadata::<Track>(*alt_id)
|
||||
})
|
||||
.collect::<Vec<TrackRef>>();
|
||||
|
||||
track = eventual::sequence(alternatives.into_iter())
|
||||
.iter()
|
||||
.find(|alt| alt.available)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let format = match self.session.config().bitrate {
|
||||
Bitrate::Bitrate96 => FileFormat::OGG_VORBIS_96,
|
||||
Bitrate::Bitrate160 => FileFormat::OGG_VORBIS_160,
|
||||
Bitrate::Bitrate320 => FileFormat::OGG_VORBIS_320,
|
||||
};
|
||||
let (file_id, _) = track.files.into_iter().find(|&(_, f)| f == format).unwrap();
|
||||
|
||||
let key = self.session.audio_key(track.id, file_id).await().unwrap();
|
||||
decoder = Some(
|
||||
vorbis::Decoder::new(
|
||||
Subfile::new(
|
||||
AudioDecrypt::new(key,
|
||||
self.session.audio_file(file_id)), 0xa7)).unwrap());
|
||||
|
||||
vorbis_time_seek_ms(decoder.as_mut().unwrap(), position as i64).unwrap();
|
||||
decoder = match load_track(&self.session, track_id) {
|
||||
Some(mut decoder) => {
|
||||
vorbis_time_seek_ms(&mut decoder, position as i64).unwrap();
|
||||
|
||||
self.update(|state| {
|
||||
state.status = if play {
|
||||
|
@ -233,7 +255,23 @@ impl PlayerInternal {
|
|||
|
||||
true
|
||||
});
|
||||
|
||||
info!("Load Done");
|
||||
Some(decoder)
|
||||
}
|
||||
|
||||
None => {
|
||||
self.update(|state| {
|
||||
state.status = PlayStatus::kPlayStatusStop;
|
||||
state.end_of_track = true;
|
||||
true
|
||||
});
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Some(PlayerCommand::Seek(position)) => {
|
||||
vorbis_time_seek_ms(decoder.as_mut().unwrap(), position as i64).unwrap();
|
||||
|
|
Loading…
Reference in a new issue