mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Move ConnectConfig
to connect
This commit is contained in:
parent
1a7c440bd7
commit
cc9a574b2e
12 changed files with 137 additions and 175 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1291,7 +1291,6 @@ dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"librespot-core",
|
"librespot-core",
|
||||||
"librespot-discovery",
|
|
||||||
"librespot-playback",
|
"librespot-playback",
|
||||||
"librespot-protocol",
|
"librespot-protocol",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1370,6 +1369,7 @@ dependencies = [
|
||||||
"hmac",
|
"hmac",
|
||||||
"hyper",
|
"hyper",
|
||||||
"libmdns",
|
"libmdns",
|
||||||
|
"librespot-connect",
|
||||||
"librespot-core",
|
"librespot-core",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
|
|
|
@ -30,10 +30,3 @@ version = "0.3.1"
|
||||||
[dependencies.librespot-protocol]
|
[dependencies.librespot-protocol]
|
||||||
path = "../protocol"
|
path = "../protocol"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
||||||
[dependencies.librespot-discovery]
|
|
||||||
path = "../discovery"
|
|
||||||
version = "0.3.1"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
with-dns-sd = ["librespot-discovery/with-dns-sd"]
|
|
||||||
|
|
115
connect/src/config.rs
Normal file
115
connect/src/config.rs
Normal file
|
@ -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<u16>,
|
||||||
|
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<Self, Self::Err> {
|
||||||
|
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<DeviceType> 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<Option<Self::Item>> {
|
|
||||||
Pin::new(&mut self.0).poll_next(cx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn discovery(
|
|
||||||
config: ConnectConfig,
|
|
||||||
device_id: String,
|
|
||||||
port: u16,
|
|
||||||
) -> io::Result<DiscoveryStream> {
|
|
||||||
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))
|
|
||||||
}
|
|
|
@ -5,10 +5,6 @@ use librespot_core as core;
|
||||||
use librespot_playback as playback;
|
use librespot_playback as playback;
|
||||||
use librespot_protocol as protocol;
|
use librespot_protocol as protocol;
|
||||||
|
|
||||||
|
pub mod config;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
#[deprecated(
|
|
||||||
since = "0.2.1",
|
|
||||||
note = "Please use the crate `librespot_discovery` instead."
|
|
||||||
)]
|
|
||||||
pub mod discovery;
|
|
||||||
pub mod spirc;
|
pub mod spirc;
|
||||||
|
|
|
@ -18,16 +18,13 @@ use tokio::sync::mpsc;
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
config::ConnectConfig,
|
||||||
context::StationContext,
|
context::StationContext,
|
||||||
core::{
|
core::{
|
||||||
config::ConnectConfig, // TODO: move to connect?
|
|
||||||
mercury::{MercuryError, MercurySender},
|
mercury::{MercuryError, MercurySender},
|
||||||
session::UserAttributes,
|
session::UserAttributes,
|
||||||
util::SeqGenerator,
|
util::SeqGenerator,
|
||||||
version,
|
version, Error, Session, SpotifyId,
|
||||||
Error,
|
|
||||||
Session,
|
|
||||||
SpotifyId,
|
|
||||||
},
|
},
|
||||||
playback::{
|
playback::{
|
||||||
mixer::Mixer,
|
mixer::Mixer,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{fmt, path::PathBuf, str::FromStr};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use url::Url;
|
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<Self, Self::Err> {
|
|
||||||
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<DeviceType> 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<u16>,
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -98,7 +98,10 @@ impl SpClient {
|
||||||
let body = protobuf::text_format::print_to_string(message);
|
let body = protobuf::text_format::print_to_string(message);
|
||||||
|
|
||||||
let mut headers = headers.unwrap_or_else(HeaderMap::new);
|
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))
|
self.request(method, endpoint, Some(headers), Some(body))
|
||||||
.await
|
.await
|
||||||
|
@ -112,7 +115,7 @@ impl SpClient {
|
||||||
body: Option<String>,
|
body: Option<String>,
|
||||||
) -> SpClientResult {
|
) -> SpClientResult {
|
||||||
let mut headers = headers.unwrap_or_else(HeaderMap::new);
|
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
|
self.request(method, endpoint, Some(headers), body).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ sha-1 = "0.9"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tokio = { version = "1.0", features = ["parking_lot", "sync", "rt"] }
|
tokio = { version = "1.0", features = ["parking_lot", "sync", "rt"] }
|
||||||
|
|
||||||
|
[dependencies.librespot-connect]
|
||||||
|
path = "../connect"
|
||||||
|
version = "0.3.1"
|
||||||
|
|
||||||
[dependencies.librespot-core]
|
[dependencies.librespot-core]
|
||||||
path = "../core"
|
path = "../core"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
|
@ -16,6 +16,7 @@ use std::task::{Context, Poll};
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use futures_core::Stream;
|
use futures_core::Stream;
|
||||||
|
use librespot_connect as connect;
|
||||||
use librespot_core as core;
|
use librespot_core as core;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ use self::server::DiscoveryServer;
|
||||||
pub use crate::core::authentication::Credentials;
|
pub use crate::core::authentication::Credentials;
|
||||||
|
|
||||||
/// Determining the icon in the list of available devices.
|
/// 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;
|
pub use crate::core::Error;
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,9 @@ use tokio::sync::{mpsc, oneshot};
|
||||||
|
|
||||||
use super::DiscoveryError;
|
use super::DiscoveryError;
|
||||||
|
|
||||||
use crate::core::{
|
use crate::{
|
||||||
authentication::Credentials, config::DeviceType, diffie_hellman::DhLocalKeys, Error,
|
connect::config::DeviceType,
|
||||||
|
core::{authentication::Credentials, diffie_hellman::DhLocalKeys, Error},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Params<'a> = BTreeMap<Cow<'a, str>, Cow<'a, str>>;
|
type Params<'a> = BTreeMap<Cow<'a, str>, Cow<'a, str>>;
|
||||||
|
|
|
@ -18,13 +18,11 @@ use tokio::sync::mpsc::UnboundedReceiver;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use librespot::{
|
use librespot::{
|
||||||
connect::spirc::Spirc,
|
connect::{
|
||||||
core::{
|
|
||||||
authentication::Credentials,
|
|
||||||
cache::Cache,
|
|
||||||
config::{ConnectConfig, DeviceType},
|
config::{ConnectConfig, DeviceType},
|
||||||
version, Session, SessionConfig,
|
spirc::Spirc,
|
||||||
},
|
},
|
||||||
|
core::{authentication::Credentials, cache::Cache, version, Session, SessionConfig},
|
||||||
playback::{
|
playback::{
|
||||||
audio_backend::{self, SinkBuilder, BACKENDS},
|
audio_backend::{self, SinkBuilder, BACKENDS},
|
||||||
config::{
|
config::{
|
||||||
|
|
Loading…
Reference in a new issue