mirror of
https://github.com/librespot-org/librespot.git
synced 2024-11-08 16:45:43 +00:00
Add simple playback example.
This commit is contained in:
parent
d95c0b3fcd
commit
294a7821d6
8 changed files with 81 additions and 11 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -36,6 +36,7 @@ dependencies = [
|
|||
"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)",
|
||||
]
|
||||
|
@ -851,6 +852,14 @@ name = "utf8-ranges"
|
|||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vergen"
|
||||
version = "0.1.1"
|
||||
|
@ -1033,6 +1042,7 @@ dependencies = [
|
|||
"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
|
||||
"checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cfec50b0842181ba6e713151b72f4ec84a6a7e2c9c8a8a3ffc37bb1cd16b231"
|
||||
"checksum vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3365f36c57e5df714a34be40902b27a992eeddb9996eca52d0584611cf885d"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum vorbis 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "760993e54524128b88d4d7aff09c773c2f16a9f18db3c8ae1ccca5afd1287656"
|
||||
|
|
|
@ -59,6 +59,7 @@ 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]
|
||||
vergen = "0.1.0"
|
||||
|
|
40
examples/play.rs
Normal file
40
examples/play.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
extern crate librespot;
|
||||
extern crate tokio_core;
|
||||
|
||||
use std::env;
|
||||
use tokio_core::reactor::Core;
|
||||
|
||||
use librespot::audio_backend;
|
||||
use librespot::authentication::Credentials;
|
||||
use librespot::player::Player;
|
||||
use librespot::session::{Config, Session};
|
||||
use librespot::util::SpotifyId;
|
||||
|
||||
fn main() {
|
||||
let mut core = Core::new().unwrap();
|
||||
let handle = core.handle();
|
||||
|
||||
let config = Config::default();
|
||||
|
||||
let args : Vec<_> = env::args().collect();
|
||||
if args.len() != 4 {
|
||||
println!("Usage: {} USERNAME PASSWORD TRACK", args[0]);
|
||||
}
|
||||
let username = args[1].to_owned();
|
||||
let password = args[2].to_owned();
|
||||
let credentials = Credentials::with_password(username, password);
|
||||
|
||||
let track = SpotifyId::from_base62(&args[3]);
|
||||
|
||||
let backend = audio_backend::find(None).unwrap();
|
||||
|
||||
println!("Connecting ..");
|
||||
let session = core.run(Session::connect(config, credentials, None, handle)).unwrap();
|
||||
|
||||
let player = Player::new(session.clone(), None, move || (backend)(None));
|
||||
|
||||
println!("Playing...");
|
||||
core.run(player.load(track, true, 0)).unwrap();
|
||||
|
||||
println!("Done");
|
||||
}
|
|
@ -85,8 +85,8 @@ declare_backends! {
|
|||
];
|
||||
}
|
||||
|
||||
pub fn find<T: AsRef<str>>(name: Option<T>) -> Option<fn(Option<String>) -> Box<Sink>> {
|
||||
if let Some(name) = name.as_ref().map(AsRef::as_ref) {
|
||||
pub fn find(name: Option<String>) -> Option<fn(Option<String>) -> Box<Sink>> {
|
||||
if let Some(name) = name {
|
||||
BACKENDS.iter().find(|backend| name == backend.0).map(|backend| backend.1)
|
||||
} else {
|
||||
Some(BACKENDS.first().expect("No backends were enabled at build time").1)
|
||||
|
|
|
@ -29,6 +29,7 @@ extern crate tempfile;
|
|||
extern crate tokio_core;
|
||||
extern crate tokio_proto;
|
||||
extern crate url;
|
||||
extern crate uuid;
|
||||
|
||||
pub extern crate librespot_protocol as protocol;
|
||||
|
||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -73,6 +73,7 @@ struct Setup {
|
|||
|
||||
mixer: fn() -> Box<Mixer>,
|
||||
|
||||
name: String,
|
||||
cache: Option<Cache>,
|
||||
config: Config,
|
||||
credentials: Option<Credentials>,
|
||||
|
@ -116,7 +117,7 @@ fn setup(args: &[String]) -> Setup {
|
|||
exit(0);
|
||||
}
|
||||
|
||||
let backend = audio_backend::find(backend_name.as_ref())
|
||||
let backend = audio_backend::find(backend_name)
|
||||
.expect("Invalid backend");
|
||||
|
||||
let mixer_name = matches.opt_str("mixer");
|
||||
|
@ -144,7 +145,6 @@ fn setup(args: &[String]) -> Setup {
|
|||
|
||||
let config = Config {
|
||||
user_agent: version::version_string(),
|
||||
name: name,
|
||||
device_id: device_id,
|
||||
bitrate: bitrate,
|
||||
onstart: matches.opt_str("onstart"),
|
||||
|
@ -154,6 +154,7 @@ fn setup(args: &[String]) -> Setup {
|
|||
let device = matches.opt_str("device");
|
||||
|
||||
Setup {
|
||||
name: name,
|
||||
backend: backend,
|
||||
cache: cache,
|
||||
config: config,
|
||||
|
@ -165,6 +166,7 @@ fn setup(args: &[String]) -> Setup {
|
|||
}
|
||||
|
||||
struct Main {
|
||||
name: String,
|
||||
cache: Option<Cache>,
|
||||
config: Config,
|
||||
backend: fn(Option<String>) -> Box<Sink>,
|
||||
|
@ -184,6 +186,7 @@ struct Main {
|
|||
|
||||
impl Main {
|
||||
fn new(handle: Handle,
|
||||
name: String,
|
||||
config: Config,
|
||||
cache: Option<Cache>,
|
||||
backend: fn(Option<String>) -> Box<Sink>,
|
||||
|
@ -192,6 +195,7 @@ impl Main {
|
|||
{
|
||||
Main {
|
||||
handle: handle.clone(),
|
||||
name: name,
|
||||
cache: cache,
|
||||
config: config,
|
||||
backend: backend,
|
||||
|
@ -208,8 +212,9 @@ impl Main {
|
|||
}
|
||||
|
||||
fn discovery(&mut self) {
|
||||
let name = self.config.name.clone();
|
||||
let device_id = self.config.device_id.clone();
|
||||
let name = self.name.clone();
|
||||
|
||||
self.discovery = Some(discovery(&self.handle, name, device_id).unwrap());
|
||||
}
|
||||
|
||||
|
@ -256,7 +261,7 @@ impl Future for Main {
|
|||
(backend)(device)
|
||||
});
|
||||
|
||||
let (spirc, spirc_task) = Spirc::new(session, player, mixer);
|
||||
let (spirc, spirc_task) = Spirc::new(self.name.clone(), session, player, mixer);
|
||||
self.spirc = Some(spirc);
|
||||
self.spirc_task = Some(spirc_task);
|
||||
|
||||
|
@ -298,9 +303,9 @@ fn main() {
|
|||
let handle = core.handle();
|
||||
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let Setup { backend, config, device, cache, enable_discovery, credentials, mixer } = setup(&args);
|
||||
let Setup { name, backend, config, device, cache, enable_discovery, credentials, mixer } = setup(&args);
|
||||
|
||||
let mut task = Main::new(handle, config.clone(), cache, backend, device, mixer);
|
||||
let mut task = Main::new(handle, name, config, cache, backend, device, mixer);
|
||||
if enable_discovery {
|
||||
task.discovery();
|
||||
}
|
||||
|
|
|
@ -9,12 +9,14 @@ use std::sync::{RwLock, Arc, Weak};
|
|||
use tokio_core::io::EasyBuf;
|
||||
use tokio_core::reactor::{Handle, Remote};
|
||||
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||
use uuid::Uuid;
|
||||
|
||||
use apresolve::apresolve_or_fallback;
|
||||
use authentication::Credentials;
|
||||
use cache::Cache;
|
||||
use component::Lazy;
|
||||
use connection;
|
||||
use version;
|
||||
|
||||
use audio_key::AudioKeyManager;
|
||||
use channel::ChannelManager;
|
||||
|
@ -43,13 +45,25 @@ impl FromStr for Bitrate {
|
|||
#[derive(Clone)]
|
||||
pub struct Config {
|
||||
pub user_agent: String,
|
||||
pub name: String,
|
||||
pub device_id: String,
|
||||
pub bitrate: Bitrate,
|
||||
pub onstart: Option<String>,
|
||||
pub onstop: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Config {
|
||||
let device_id = Uuid::new_v4().hyphenated().to_string();
|
||||
Config {
|
||||
user_agent: version::version_string(),
|
||||
device_id: device_id,
|
||||
bitrate: Bitrate::Bitrate160,
|
||||
onstart: None,
|
||||
onstop: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SessionData {
|
||||
country: String,
|
||||
canonical_username: String,
|
||||
|
|
|
@ -118,13 +118,12 @@ fn initial_device_state(name: String, volume: u16) -> DeviceState {
|
|||
}
|
||||
|
||||
impl Spirc {
|
||||
pub fn new(session: Session, player: Player, mixer: Box<Mixer>)
|
||||
pub fn new(name: String, session: Session, player: Player, mixer: Box<Mixer>)
|
||||
-> (Spirc, SpircTask)
|
||||
{
|
||||
debug!("new Spirc[{}]", session.session_id());
|
||||
|
||||
let ident = session.device_id().to_owned();
|
||||
let name = session.config().name.clone();
|
||||
|
||||
let uri = format!("hm://remote/user/{}", session.username());
|
||||
|
||||
|
|
Loading…
Reference in a new issue