diff --git a/Cargo.lock b/Cargo.lock index a7f5093d..1b65127d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1291,7 +1291,6 @@ dependencies = [ "form_urlencoded", "futures-util", "librespot-core", - "librespot-discovery", "librespot-playback", "librespot-protocol", "log", @@ -1370,6 +1369,7 @@ dependencies = [ "hmac", "hyper", "libmdns", + "librespot-connect", "librespot-core", "log", "rand", diff --git a/connect/Cargo.toml b/connect/Cargo.toml index ab425a66..37521df9 100644 --- a/connect/Cargo.toml +++ b/connect/Cargo.toml @@ -30,10 +30,3 @@ version = "0.3.1" [dependencies.librespot-protocol] path = "../protocol" version = "0.3.1" - -[dependencies.librespot-discovery] -path = "../discovery" -version = "0.3.1" - -[features] -with-dns-sd = ["librespot-discovery/with-dns-sd"] diff --git a/connect/src/config.rs b/connect/src/config.rs new file mode 100644 index 00000000..4d751fcf --- /dev/null +++ b/connect/src/config.rs @@ -0,0 +1,115 @@ +use std::{fmt, str::FromStr}; + +#[derive(Clone, Debug)] +pub struct ConnectConfig { + pub name: String, + pub device_type: DeviceType, + pub initial_volume: Option, + pub has_volume_ctrl: bool, +} + +impl Default for ConnectConfig { + fn default() -> ConnectConfig { + ConnectConfig { + name: "Librespot".to_string(), + device_type: DeviceType::default(), + initial_volume: Some(50), + has_volume_ctrl: true, + } + } +} + +#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum DeviceType { + Unknown = 0, + Computer = 1, + Tablet = 2, + Smartphone = 3, + Speaker = 4, + Tv = 5, + Avr = 6, + Stb = 7, + AudioDongle = 8, + GameConsole = 9, + CastAudio = 10, + CastVideo = 11, + Automobile = 12, + Smartwatch = 13, + Chromebook = 14, + UnknownSpotify = 100, + CarThing = 101, + Observer = 102, + HomeThing = 103, +} + +impl FromStr for DeviceType { + type Err = (); + fn from_str(s: &str) -> Result { + use self::DeviceType::*; + match s.to_lowercase().as_ref() { + "computer" => Ok(Computer), + "tablet" => Ok(Tablet), + "smartphone" => Ok(Smartphone), + "speaker" => Ok(Speaker), + "tv" => Ok(Tv), + "avr" => Ok(Avr), + "stb" => Ok(Stb), + "audiodongle" => Ok(AudioDongle), + "gameconsole" => Ok(GameConsole), + "castaudio" => Ok(CastAudio), + "castvideo" => Ok(CastVideo), + "automobile" => Ok(Automobile), + "smartwatch" => Ok(Smartwatch), + "chromebook" => Ok(Chromebook), + "carthing" => Ok(CarThing), + "homething" => Ok(HomeThing), + _ => Err(()), + } + } +} + +impl From<&DeviceType> for &str { + fn from(d: &DeviceType) -> &'static str { + use self::DeviceType::*; + match d { + Unknown => "Unknown", + Computer => "Computer", + Tablet => "Tablet", + Smartphone => "Smartphone", + Speaker => "Speaker", + Tv => "TV", + Avr => "AVR", + Stb => "STB", + AudioDongle => "AudioDongle", + GameConsole => "GameConsole", + CastAudio => "CastAudio", + CastVideo => "CastVideo", + Automobile => "Automobile", + Smartwatch => "Smartwatch", + Chromebook => "Chromebook", + UnknownSpotify => "UnknownSpotify", + CarThing => "CarThing", + Observer => "Observer", + HomeThing => "HomeThing", + } + } +} + +impl From for &str { + fn from(d: DeviceType) -> &'static str { + (&d).into() + } +} + +impl fmt::Display for DeviceType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let str: &str = self.into(); + f.write_str(str) + } +} + +impl Default for DeviceType { + fn default() -> DeviceType { + DeviceType::Speaker + } +} diff --git a/connect/src/discovery.rs b/connect/src/discovery.rs deleted file mode 100644 index 8f4f9b34..00000000 --- a/connect/src/discovery.rs +++ /dev/null @@ -1,32 +0,0 @@ -use std::{ - io, - pin::Pin, - task::{Context, Poll}, -}; - -use futures_util::Stream; -use librespot_core::{authentication::Credentials, config::ConnectConfig}; - -pub struct DiscoveryStream(librespot_discovery::Discovery); - -impl Stream for DiscoveryStream { - type Item = Credentials; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Pin::new(&mut self.0).poll_next(cx) - } -} - -pub fn discovery( - config: ConnectConfig, - device_id: String, - port: u16, -) -> io::Result { - librespot_discovery::Discovery::builder(device_id) - .device_type(config.device_type) - .port(port) - .name(config.name) - .launch() - .map(DiscoveryStream) - .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) -} diff --git a/connect/src/lib.rs b/connect/src/lib.rs index 267bf1b8..193e5db5 100644 --- a/connect/src/lib.rs +++ b/connect/src/lib.rs @@ -5,10 +5,6 @@ use librespot_core as core; use librespot_playback as playback; use librespot_protocol as protocol; +pub mod config; pub mod context; -#[deprecated( - since = "0.2.1", - note = "Please use the crate `librespot_discovery` instead." -)] -pub mod discovery; pub mod spirc; diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 427555ff..ef9da811 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -18,16 +18,13 @@ use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; use crate::{ + config::ConnectConfig, context::StationContext, core::{ - config::ConnectConfig, // TODO: move to connect? mercury::{MercuryError, MercurySender}, session::UserAttributes, util::SeqGenerator, - version, - Error, - Session, - SpotifyId, + version, Error, Session, SpotifyId, }, playback::{ mixer::Mixer, diff --git a/core/src/config.rs b/core/src/config.rs index b667a330..87c1637f 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -1,4 +1,4 @@ -use std::{fmt, path::PathBuf, str::FromStr}; +use std::path::PathBuf; use url::Url; @@ -21,117 +21,3 @@ impl Default for SessionConfig { } } } - -#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub enum DeviceType { - Unknown = 0, - Computer = 1, - Tablet = 2, - Smartphone = 3, - Speaker = 4, - Tv = 5, - Avr = 6, - Stb = 7, - AudioDongle = 8, - GameConsole = 9, - CastAudio = 10, - CastVideo = 11, - Automobile = 12, - Smartwatch = 13, - Chromebook = 14, - UnknownSpotify = 100, - CarThing = 101, - Observer = 102, - HomeThing = 103, -} - -impl FromStr for DeviceType { - type Err = (); - fn from_str(s: &str) -> Result { - use self::DeviceType::*; - match s.to_lowercase().as_ref() { - "computer" => Ok(Computer), - "tablet" => Ok(Tablet), - "smartphone" => Ok(Smartphone), - "speaker" => Ok(Speaker), - "tv" => Ok(Tv), - "avr" => Ok(Avr), - "stb" => Ok(Stb), - "audiodongle" => Ok(AudioDongle), - "gameconsole" => Ok(GameConsole), - "castaudio" => Ok(CastAudio), - "castvideo" => Ok(CastVideo), - "automobile" => Ok(Automobile), - "smartwatch" => Ok(Smartwatch), - "chromebook" => Ok(Chromebook), - "carthing" => Ok(CarThing), - "homething" => Ok(HomeThing), - _ => Err(()), - } - } -} - -impl From<&DeviceType> for &str { - fn from(d: &DeviceType) -> &'static str { - use self::DeviceType::*; - match d { - Unknown => "Unknown", - Computer => "Computer", - Tablet => "Tablet", - Smartphone => "Smartphone", - Speaker => "Speaker", - Tv => "TV", - Avr => "AVR", - Stb => "STB", - AudioDongle => "AudioDongle", - GameConsole => "GameConsole", - CastAudio => "CastAudio", - CastVideo => "CastVideo", - Automobile => "Automobile", - Smartwatch => "Smartwatch", - Chromebook => "Chromebook", - UnknownSpotify => "UnknownSpotify", - CarThing => "CarThing", - Observer => "Observer", - HomeThing => "HomeThing", - } - } -} - -impl From for &str { - fn from(d: DeviceType) -> &'static str { - (&d).into() - } -} - -impl fmt::Display for DeviceType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let str: &str = self.into(); - f.write_str(str) - } -} - -impl Default for DeviceType { - fn default() -> DeviceType { - DeviceType::Speaker - } -} - -#[derive(Clone, Debug)] -pub struct ConnectConfig { - pub name: String, - pub device_type: DeviceType, - pub initial_volume: Option, - pub has_volume_ctrl: bool, -} - -impl Default for ConnectConfig { - fn default() -> ConnectConfig { - ConnectConfig { - name: "Librespot".to_string(), - device_type: DeviceType::default(), - initial_volume: Some(50), - has_volume_ctrl: true, - } - } -} diff --git a/core/src/spclient.rs b/core/src/spclient.rs index de57e97b..9985041a 100644 --- a/core/src/spclient.rs +++ b/core/src/spclient.rs @@ -98,7 +98,10 @@ impl SpClient { let body = protobuf::text_format::print_to_string(message); let mut headers = headers.unwrap_or_else(HeaderMap::new); - headers.insert(CONTENT_TYPE, "application/protobuf".parse()?); + headers.insert( + CONTENT_TYPE, + HeaderValue::from_static("application/protobuf"), + ); self.request(method, endpoint, Some(headers), Some(body)) .await @@ -112,7 +115,7 @@ impl SpClient { body: Option, ) -> SpClientResult { let mut headers = headers.unwrap_or_else(HeaderMap::new); - headers.insert(ACCEPT, "application/json".parse()?); + headers.insert(ACCEPT, HeaderValue::from_static("application/json")); self.request(method, endpoint, Some(headers), body).await } diff --git a/discovery/Cargo.toml b/discovery/Cargo.toml index 0225ab68..cafa6870 100644 --- a/discovery/Cargo.toml +++ b/discovery/Cargo.toml @@ -25,6 +25,10 @@ sha-1 = "0.9" thiserror = "1.0" tokio = { version = "1.0", features = ["parking_lot", "sync", "rt"] } +[dependencies.librespot-connect] +path = "../connect" +version = "0.3.1" + [dependencies.librespot-core] path = "../core" version = "0.3.1" diff --git a/discovery/src/lib.rs b/discovery/src/lib.rs index a29b3b8c..a4e124c5 100644 --- a/discovery/src/lib.rs +++ b/discovery/src/lib.rs @@ -16,6 +16,7 @@ use std::task::{Context, Poll}; use cfg_if::cfg_if; use futures_core::Stream; +use librespot_connect as connect; use librespot_core as core; use thiserror::Error; @@ -25,7 +26,7 @@ use self::server::DiscoveryServer; pub use crate::core::authentication::Credentials; /// Determining the icon in the list of available devices. -pub use crate::core::config::DeviceType; +pub use crate::connect::config::DeviceType; pub use crate::core::Error; diff --git a/discovery/src/server.rs b/discovery/src/server.rs index 4a251ea5..b02c0e64 100644 --- a/discovery/src/server.rs +++ b/discovery/src/server.rs @@ -27,8 +27,9 @@ use tokio::sync::{mpsc, oneshot}; use super::DiscoveryError; -use crate::core::{ - authentication::Credentials, config::DeviceType, diffie_hellman::DhLocalKeys, Error, +use crate::{ + connect::config::DeviceType, + core::{authentication::Credentials, diffie_hellman::DhLocalKeys, Error}, }; type Params<'a> = BTreeMap, Cow<'a, str>>; diff --git a/src/main.rs b/src/main.rs index 8f2e532c..ff7c79da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,13 +18,11 @@ use tokio::sync::mpsc::UnboundedReceiver; use url::Url; use librespot::{ - connect::spirc::Spirc, - core::{ - authentication::Credentials, - cache::Cache, + connect::{ config::{ConnectConfig, DeviceType}, - version, Session, SessionConfig, + spirc::Spirc, }, + core::{authentication::Credentials, cache::Cache, version, Session, SessionConfig}, playback::{ audio_backend::{self, SinkBuilder, BACKENDS}, config::{