Create new librespot-core crate

This commit is contained in:
Paul Lietar 2017-08-03 19:58:44 +01:00
parent d59f3eff81
commit bf60f6e7ab
38 changed files with 293 additions and 141 deletions

120
Cargo.lock generated
View file

@ -1,44 +1,8 @@
[root]
name = "librespot"
name = "librespot-protocol"
version = "0.1.0"
dependencies = [
"alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)",
"base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.0-a.0 (git+https://github.com/hyperium/hyper)",
"lazy_static 0.2.8 (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",
"linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mdns 0.2.0 (git+https://github.com/plietar/rust-mdns)",
"num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"rpassword 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (git+https://github.com/awmath/rust-crypto.git?branch=avx2)",
"serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-signal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vorbis 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -275,10 +239,90 @@ dependencies = [
]
[[package]]
name = "librespot-protocol"
name = "librespot"
version = "0.1.0"
dependencies = [
"alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)",
"base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.0-a.0 (git+https://github.com/hyperium/hyper)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)",
"librespot-core 0.1.0",
"librespot-protocol 0.1.0",
"linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mdns 0.2.0 (git+https://github.com/plietar/rust-mdns)",
"num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"rpassword 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (git+https://github.com/awmath/rust-crypto.git?branch=avx2)",
"serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-signal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vorbis 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "librespot-core"
version = "0.1.0"
dependencies = [
"alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)",
"base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.0-a.0 (git+https://github.com/hyperium/hyper)",
"lazy_static 0.2.8 (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",
"linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mdns 0.2.0 (git+https://github.com/plietar/rust-mdns)",
"num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"rpassword 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (git+https://github.com/awmath/rust-crypto.git?branch=avx2)",
"serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-signal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vorbis 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View file

@ -9,6 +9,8 @@ keywords = ["spotify"]
repository = "https://github.com/plietar/librespot"
readme = "README.md"
[workspace]
[lib]
name = "librespot"
path = "src/lib.rs"
@ -21,6 +23,9 @@ doc = false
[dependencies.librespot-protocol]
path = "protocol"
[dependencies.librespot-core]
path = "core"
[dependencies]
base64 = "0.5.0"
bit-set = "0.4.0"

View file

@ -1,46 +1,14 @@
extern crate vergen;
extern crate protobuf_macros;
extern crate rand;
use rand::Rng;
use std::env;
use std::path::PathBuf;
use std::fs::OpenOptions;
use std::io::Write;
fn main() {
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
vergen::vergen(vergen::OutputFns::all()).unwrap();
let build_id: String = rand::thread_rng()
.gen_ascii_chars()
.take(8)
.collect();
let mut version_file =
OpenOptions::new()
.write(true)
.append(true)
.open(&out.join("version.rs"))
.unwrap();
let build_id_fn = format!("
/// Generate a random build id.
pub fn build_id() -> &'static str {{
\"{}\"
}}
", build_id);
if let Err(e) = version_file.write_all(build_id_fn.as_bytes()) {
println!("{}", e);
}
protobuf_macros::expand("src/lib.in.rs", &out.join("lib.rs")).unwrap();
println!("cargo:rerun-if-changed=src/lib.in.rs");
println!("cargo:rerun-if-changed=src/spirc.rs");
println!("cargo:rerun-if-changed=src/connection");
}

53
core/Cargo.toml Normal file
View file

@ -0,0 +1,53 @@
[package]
name = "librespot-core"
version = "0.1.0"
authors = ["Paul Lietar <paul@lietar.net>"]
build = "build.rs"
[dependencies.librespot-protocol]
path = "../protocol"
[dependencies]
base64 = "0.5.0"
bit-set = "0.4.0"
byteorder = "1.0"
env_logger = "0.4.0"
getopts = "0.2.14"
hyper = { git = "https://github.com/hyperium/hyper" }
lazy_static = "0.2.0"
linear-map = "1.0"
log = "0.3.5"
num-bigint = "0.1.35"
num-integer = "0.1.32"
num-traits = "0.1.36"
protobuf = "1.1"
rand = "0.3.13"
rpassword = "0.3.0"
rust-crypto = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" }
serde = "0.9.6"
serde_json = "0.9.5"
serde_derive = "0.9.6"
shannon = "0.2.0"
tempfile = "2.1"
url = "1.3"
vorbis = "0.1.0"
tremor = { git = "https://github.com/plietar/rust-tremor", optional = true }
alsa = { git = "https://github.com/plietar/rust-alsa", optional = true }
portaudio-rs = { version = "0.3.0", optional = true }
libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true }
mdns = { git = "https://github.com/plietar/rust-mdns" }
error-chain = { version = "0.9.0", default_features = false }
futures = "0.1.8"
tokio-core = "0.1.2"
tokio-proto = "0.1.0"
tokio-signal = "0.1"
uuid = { version = "0.4", features = ["v4"] }
[build-dependencies]
rand = "0.3.13"
vergen = "0.1.0"
protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros", features = ["with-syntex"] }

43
core/build.rs Normal file
View file

@ -0,0 +1,43 @@
extern crate vergen;
extern crate protobuf_macros;
extern crate rand;
use rand::Rng;
use std::env;
use std::path::PathBuf;
use std::fs::OpenOptions;
use std::io::Write;
fn main() {
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
vergen::vergen(vergen::OutputFns::all()).unwrap();
let build_id: String = rand::thread_rng()
.gen_ascii_chars()
.take(8)
.collect();
let mut version_file =
OpenOptions::new()
.write(true)
.append(true)
.open(&out.join("version.rs"))
.unwrap();
let build_id_fn = format!("
/// Generate a random build id.
pub fn build_id() -> &'static str {{
\"{}\"
}}
", build_id);
if let Err(e) = version_file.write_all(build_id_fn.as_bytes()) {
println!("{}", e);
}
protobuf_macros::expand("src/lib.in.rs", &out.join("lib.rs")).unwrap();
println!("cargo:rerun-if-changed=src/lib.in.rs");
println!("cargo:rerun-if-changed=src/connection");
}

View file

@ -16,8 +16,6 @@ use std::path::Path;
use protocol::authentication::AuthenticationType;
pub mod discovery;
#[derive(Debug, Clone)]
#[derive(Serialize, Deserialize)]
pub struct Credentials {

View file

@ -4,6 +4,23 @@ use std::fmt;
use version;
#[derive(Clone,Debug)]
pub struct SessionConfig {
pub user_agent: String,
pub device_id: String,
}
impl Default for SessionConfig {
fn default() -> SessionConfig {
let device_id = Uuid::new_v4().hyphenated().to_string();
SessionConfig {
user_agent: version::version_string(),
device_id: device_id,
}
}
}
#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub enum Bitrate {
Bitrate96,
@ -83,22 +100,6 @@ impl Default for DeviceType {
}
}
#[derive(Clone,Debug)]
pub struct SessionConfig {
pub user_agent: String,
pub device_id: String,
}
impl Default for SessionConfig {
fn default() -> SessionConfig {
let device_id = Uuid::new_v4().hyphenated().to_string();
SessionConfig {
user_agent: version::version_string(),
device_id: device_id,
}
}
}
#[derive(Clone,Debug)]
pub struct PlayerConfig {
pub bitrate: Bitrate,

1
core/src/lib.in.rs Normal file
View file

@ -0,0 +1 @@
pub mod connection;

50
core/src/lib.rs Normal file
View file

@ -0,0 +1,50 @@
#![cfg_attr(feature = "cargo-clippy", allow(unused_io_amount))]
// TODO: many items from tokio-core::io have been deprecated in favour of tokio-io
#![allow(deprecated)]
#[macro_use] extern crate error_chain;
#[macro_use] extern crate futures;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
#[macro_use] extern crate serde_derive;
extern crate base64;
extern crate bit_set;
extern crate byteorder;
extern crate crypto;
extern crate getopts;
extern crate hyper;
extern crate linear_map;
extern crate mdns;
extern crate num_bigint;
extern crate num_integer;
extern crate num_traits;
extern crate protobuf;
extern crate rand;
extern crate rpassword;
extern crate serde;
extern crate serde_json;
extern crate shannon;
extern crate tempfile;
extern crate tokio_core;
extern crate tokio_proto;
extern crate url;
extern crate uuid;
pub extern crate librespot_protocol as protocol;
#[macro_use] mod component;
pub mod apresolve;
pub mod audio_key;
pub mod authentication;
pub mod cache;
pub mod channel;
pub mod config;
pub mod diffie_hellman;
pub mod mercury;
pub mod session;
pub mod util;
pub mod version;
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

View file

@ -1,9 +1,9 @@
use byteorder::{BigEndian, WriteBytesExt};
use std::io::Write;
use channel::ChannelData;
use session::Session;
use util::FileId;
use core::channel::ChannelData;
use core::session::Session;
use core::util::FileId;
pub fn get(session: &Session, file: FileId) -> ChannelData {
let (channel_id, channel) = session.channel().allocate();

View file

@ -5,7 +5,7 @@ use num_traits::FromPrimitive;
use std::io;
use std::ops::Add;
use audio_key::AudioKey;
use core::audio_key::AudioKey;
const AUDIO_AESIV: &'static [u8] = &[0x72, 0xe0, 0x67, 0xfb, 0xdd, 0xcb, 0xcf, 0x77, 0xeb, 0xe8,
0xbc, 0x64, 0x3f, 0x63, 0x0d, 0x93];

View file

@ -10,9 +10,9 @@ use std::io::{self, Read, Write, Seek, SeekFrom};
use std::sync::{Arc, Condvar, Mutex};
use tempfile::NamedTempFile;
use channel::{Channel, ChannelData, ChannelError, ChannelHeaders};
use session::Session;
use util::FileId;
use core::channel::{Channel, ChannelData, ChannelError, ChannelHeaders};
use core::session::Session;
use core::util::FileId;
const CHUNK_SIZE: usize = 0x20000;

View file

@ -2,7 +2,6 @@ use base64;
use crypto::digest::Digest;
use crypto::mac::Mac;
use crypto;
use diffie_hellman::{DH_GENERATOR, DH_PRIME};
use futures::sync::mpsc;
use futures::{Future, Stream, BoxFuture, Poll, Async};
use hyper::server::{Service, NewService, Request, Response, Http};
@ -17,9 +16,10 @@ use tokio_core::net::TcpListener;
use tokio_core::reactor::Handle;
use url;
use authentication::Credentials;
use util;
use config::ConnectConfig;
use core::diffie_hellman::{DH_GENERATOR, DH_PRIME};
use core::authentication::Credentials;
use core::util;
use core::config::ConnectConfig;
#[derive(Clone)]
struct Discovery(Arc<DiscoveryInner>);

View file

@ -1,7 +1,8 @@
use futures::{Future, BoxFuture};
use serde_json;
use session::Session;
use mercury::MercuryError;
use core::mercury::MercuryError;
use core::session::Session;
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]

View file

@ -1,2 +1 @@
pub mod connection;
pub mod spirc;

View file

@ -5,9 +5,7 @@
// TODO: many items from tokio-core::io have been deprecated in favour of tokio-io
#![allow(deprecated)]
#[macro_use] extern crate error_chain;
#[macro_use] extern crate futures;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
#[macro_use] extern crate serde_json;
#[macro_use] extern crate serde_derive;
@ -34,6 +32,7 @@ extern crate tokio_proto;
extern crate url;
extern crate uuid;
pub extern crate librespot_core as core;
pub extern crate librespot_protocol as protocol;
#[cfg(not(feature = "with-tremor"))]
@ -50,26 +49,14 @@ extern crate portaudio_rs;
#[cfg(feature = "libpulse-sys")]
extern crate libpulse_sys;
#[macro_use] mod component;
pub mod album_cover;
pub mod apresolve;
pub mod audio_backend;
pub mod audio_decrypt;
pub mod audio_file;
pub mod audio_key;
pub mod authentication;
pub mod cache;
pub mod channel;
pub mod config;
pub mod diffie_hellman;
pub mod discovery;
pub mod keymaster;
pub mod mercury;
pub mod metadata;
pub mod mixer;
pub mod player;
pub mod session;
pub mod util;
pub mod version;
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

View file

@ -20,17 +20,17 @@ use tokio_core::reactor::{Handle, Core};
use tokio_core::io::IoStream;
use std::mem;
use librespot::spirc::{Spirc, SpircTask};
use librespot::authentication::{get_credentials, Credentials};
use librespot::authentication::discovery::{discovery, DiscoveryStream};
use librespot::audio_backend::{self, Sink, BACKENDS};
use librespot::cache::Cache;
use librespot::player::Player;
use librespot::session::Session;
use librespot::config::{Bitrate, DeviceType, PlayerConfig, SessionConfig, ConnectConfig};
use librespot::mixer::{self, Mixer};
use librespot::core::authentication::{get_credentials, Credentials};
use librespot::core::cache::Cache;
use librespot::core::config::{Bitrate, DeviceType, PlayerConfig, SessionConfig, ConnectConfig};
use librespot::core::session::Session;
use librespot::core::version;
use librespot::version;
use librespot::audio_backend::{self, Sink, BACKENDS};
use librespot::discovery::{discovery, DiscoveryStream};
use librespot::mixer::{self, Mixer};
use librespot::player::Player;
use librespot::spirc::{Spirc, SpircTask};
fn usage(program: &str, opts: &getopts::Options) -> String {
let brief = format!("Usage: {} [options]", program);
@ -152,7 +152,7 @@ fn setup(args: &[String]) -> Setup {
};
let session_config = {
let device_id = librespot::session::device_id(&name);
let device_id = librespot::core::session::device_id(&name);
SessionConfig {
user_agent: version::version_string(),

View file

@ -2,10 +2,10 @@ use futures::{Future, BoxFuture};
use linear_map::LinearMap;
use protobuf;
use mercury::MercuryError;
use core::mercury::MercuryError;
use protocol;
use session::Session;
use util::{SpotifyId, FileId, StrChunksExt};
use core::session::Session;
use core::util::{SpotifyId, FileId, StrChunksExt};
pub use protocol::metadata::AudioFile_Format as FileFormat;

View file

@ -8,14 +8,15 @@ use std::thread;
use std;
use vorbis::{self, VorbisError};
use core::config::{Bitrate, PlayerConfig};
use core::session::Session;
use core::util::{self, SpotifyId, Subfile};
use audio_backend::Sink;
use audio_decrypt::AudioDecrypt;
use audio_file::AudioFile;
use metadata::{FileFormat, Track, Metadata};
use session::Session;
use mixer::AudioFilter;
use util::{self, SpotifyId, Subfile};
use config::{Bitrate, PlayerConfig};
#[derive(Clone)]
pub struct Player {

View file

@ -5,17 +5,18 @@ use futures::sync::{oneshot, mpsc};
use futures::{Future, Stream, Sink, Async, Poll, BoxFuture};
use protobuf::{self, Message};
use config::ConnectConfig;
use mercury::MercuryError;
use mixer::Mixer;
use player::Player;
use session::Session;
use util::{now_ms, SpotifyId, SeqGenerator};
use version;
use core::config::ConnectConfig;
use core::mercury::MercuryError;
use core::session::Session;
use core::util::{now_ms, SpotifyId, SeqGenerator};
use core::version;
use protocol;
use protocol::spirc::{PlayStatus, State, MessageType, Frame, DeviceState};
use mixer::Mixer;
use player::Player;
pub struct SpircTask {
player: Player,
mixer: Box<Mixer>,