From 191caca51831c1707f709033bb1d19f5b441c1f3 Mon Sep 17 00:00:00 2001 From: awiouy Date: Sun, 11 Feb 2018 16:13:42 +0100 Subject: [PATCH 1/3] core API: move Bitrate and PlayerConfig from core to playback --- core/src/config.rs | 42 ----------------------------------------- examples/play.rs | 2 +- playback/src/config.rs | 43 ++++++++++++++++++++++++++++++++++++++++++ playback/src/lib.rs | 1 + playback/src/player.rs | 2 +- src/main.rs | 3 ++- 6 files changed, 48 insertions(+), 45 deletions(-) create mode 100644 playback/src/config.rs diff --git a/core/src/config.rs b/core/src/config.rs index 297c04f4..7d3a5aea 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -20,31 +20,6 @@ impl Default for SessionConfig { } } -#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub enum Bitrate { - Bitrate96, - Bitrate160, - Bitrate320, -} - -impl FromStr for Bitrate { - type Err = (); - fn from_str(s: &str) -> Result { - match s { - "96" => Ok(Bitrate::Bitrate96), - "160" => Ok(Bitrate::Bitrate160), - "320" => Ok(Bitrate::Bitrate320), - _ => Err(()), - } - } -} - -impl Default for Bitrate { - fn default() -> Bitrate { - Bitrate::Bitrate160 - } -} - #[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)] pub enum DeviceType { Unknown = 0, @@ -99,23 +74,6 @@ impl Default for DeviceType { } } -#[derive(Clone, Debug)] -pub struct PlayerConfig { - pub bitrate: Bitrate, - pub onstart: Option, - pub onstop: Option, -} - -impl Default for PlayerConfig { - fn default() -> PlayerConfig { - PlayerConfig { - bitrate: Bitrate::default(), - onstart: None, - onstop: None, - } - } -} - #[derive(Clone, Debug)] pub struct ConnectConfig { pub name: String, diff --git a/examples/play.rs b/examples/play.rs index d6092732..8c88ddbe 100644 --- a/examples/play.rs +++ b/examples/play.rs @@ -5,7 +5,7 @@ use std::env; use tokio_core::reactor::Core; use librespot::core::authentication::Credentials; -use librespot::core::config::{PlayerConfig, SessionConfig}; +use librespot::playback::config::{PlayerConfig, SessionConfig}; use librespot::core::session::Session; use librespot::core::util::SpotifyId; diff --git a/playback/src/config.rs b/playback/src/config.rs new file mode 100644 index 00000000..d44e937a --- /dev/null +++ b/playback/src/config.rs @@ -0,0 +1,43 @@ +use std::str::FromStr; + +#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum Bitrate { + Bitrate96, + Bitrate160, + Bitrate320, +} + +impl FromStr for Bitrate { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "96" => Ok(Bitrate::Bitrate96), + "160" => Ok(Bitrate::Bitrate160), + "320" => Ok(Bitrate::Bitrate320), + _ => Err(()), + } + } +} + +impl Default for Bitrate { + fn default() -> Bitrate { + Bitrate::Bitrate160 + } +} + +#[derive(Clone, Debug)] +pub struct PlayerConfig { + pub bitrate: Bitrate, + pub onstart: Option, + pub onstop: Option, +} + +impl Default for PlayerConfig { + fn default() -> PlayerConfig { + PlayerConfig { + bitrate: Bitrate::default(), + onstart: None, + onstop: None, + } + } +} diff --git a/playback/src/lib.rs b/playback/src/lib.rs index 2633343b..014c7814 100644 --- a/playback/src/lib.rs +++ b/playback/src/lib.rs @@ -22,5 +22,6 @@ extern crate librespot_core as core; extern crate librespot_metadata as metadata; pub mod audio_backend; +pub mod config; pub mod mixer; pub mod player; diff --git a/playback/src/player.rs b/playback/src/player.rs index f0ee5d22..48f7f307 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -9,7 +9,7 @@ use std::sync::mpsc::{RecvError, TryRecvError, RecvTimeoutError}; use std::thread; use std::time::Duration; -use core::config::{Bitrate, PlayerConfig}; +use config::{Bitrate, PlayerConfig}; use core::session::Session; use core::util::SpotifyId; diff --git a/src/main.rs b/src/main.rs index 2ecfb57c..18f47a41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,11 +20,12 @@ use std::mem; use librespot::core::authentication::{get_credentials, Credentials}; use librespot::core::cache::Cache; -use librespot::core::config::{Bitrate, DeviceType, PlayerConfig, SessionConfig, ConnectConfig}; +use librespot::core::config::{DeviceType, SessionConfig, ConnectConfig}; use librespot::core::session::Session; use librespot::core::version; use librespot::playback::audio_backend::{self, Sink, BACKENDS}; +use librespot::playback::config::{Bitrate, PlayerConfig}; use librespot::discovery::discovery::{discovery, DiscoveryStream}; use librespot::playback::mixer::{self, Mixer}; use librespot::playback::player::Player; From d900134114d9ab9f71645fecf07f806496770b91 Mon Sep 17 00:00:00 2001 From: awiouy Date: Sun, 11 Feb 2018 16:57:55 +0100 Subject: [PATCH 2/3] connect: discovery and spirc --- Cargo.lock | 4 ++-- Cargo.toml | 7 +++---- {discovery => connect}/Cargo.toml | 10 +++++++++- build.rs => connect/build.rs | 0 {discovery => connect}/src/discovery.rs | 0 {src => connect/src}/lib.in.rs | 0 {discovery => connect}/src/lib.rs | 4 ++++ {src => connect/src}/spirc.rs | 0 src/lib.rs | 7 +------ src/main.rs | 4 ++-- 10 files changed, 21 insertions(+), 15 deletions(-) rename {discovery => connect}/Cargo.toml (68%) rename build.rs => connect/build.rs (100%) rename {discovery => connect}/src/discovery.rs (100%) rename {src => connect/src}/lib.in.rs (100%) rename {discovery => connect}/src/lib.rs (75%) rename {src => connect/src}/spirc.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 0f21634d..e31c72fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -316,8 +316,8 @@ dependencies = [ "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.14 (registry+https://github.com/rust-lang/crates.io-index)", "librespot-audio 0.1.0", + "librespot-connect 0.1.0", "librespot-core 0.1.0", - "librespot-discovery 0.1.0", "librespot-metadata 0.1.0", "librespot-playback 0.1.0", "librespot-protocol 0.1.0", @@ -388,7 +388,7 @@ dependencies = [ ] [[package]] -name = "librespot-discovery" +name = "librespot-connect" version = "0.1.0" dependencies = [ "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 15e1dda1..f3b88c3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,6 @@ name = "librespot" version = "0.1.0" authors = ["Paul LiĆ©tar "] -build = "build.rs" license = "MIT" description = "Open Source Spotify client library" keywords = ["spotify"] @@ -22,10 +21,10 @@ doc = false [dependencies.librespot-audio] path = "audio" +[dependencies.librespot-connect] +path = "connect" [dependencies.librespot-core] path = "core" -[dependencies.librespot-discovery] -path = "discovery" [dependencies.librespot-metadata] path = "metadata" [dependencies.librespot-playback] @@ -67,7 +66,7 @@ jackaudio-backend = ["librespot-playback/jackaudio-backend"] with-tremor = ["librespot-audio/with-tremor"] with-vorbis = ["librespot-audio/with-vorbis"] -with-dns-sd = ["librespot-discovery/with-dns-sd"] +with-dns-sd = ["librespot-connect/with-dns-sd"] default = ["librespot-playback/portaudio-backend"] diff --git a/discovery/Cargo.toml b/connect/Cargo.toml similarity index 68% rename from discovery/Cargo.toml rename to connect/Cargo.toml index f69185a0..a345401d 100644 --- a/discovery/Cargo.toml +++ b/connect/Cargo.toml @@ -1,10 +1,15 @@ [package] -name = "librespot-discovery" +name = "librespot-connect" version = "0.1.0" authors = ["Paul Lietar "] +build = "build.rs" [dependencies.librespot-core] path = "../core" +[dependencies.librespot-playback] +path = "../playback" +[dependencies.librespot-protocol] +path = "../protocol" [dependencies] base64 = "0.5.0" @@ -24,6 +29,9 @@ url = "1.3" dns-sd = { version = "0.1.3", optional = true } mdns = { git = "https://github.com/plietar/rust-mdns", optional = true } +[build-dependencies] +protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros", features = ["with-syntex"] } + [features] default = ["mdns"] with-dns-sd = ["dns-sd"] diff --git a/build.rs b/connect/build.rs similarity index 100% rename from build.rs rename to connect/build.rs diff --git a/discovery/src/discovery.rs b/connect/src/discovery.rs similarity index 100% rename from discovery/src/discovery.rs rename to connect/src/discovery.rs diff --git a/src/lib.in.rs b/connect/src/lib.in.rs similarity index 100% rename from src/lib.in.rs rename to connect/src/lib.in.rs diff --git a/discovery/src/lib.rs b/connect/src/lib.rs similarity index 75% rename from discovery/src/lib.rs rename to connect/src/lib.rs index d8775b8a..22c6885f 100644 --- a/discovery/src/lib.rs +++ b/connect/src/lib.rs @@ -18,5 +18,9 @@ extern crate dns_sd; extern crate mdns; extern crate librespot_core as core; +extern crate librespot_playback as playback; +extern crate librespot_protocol as protocol; pub mod discovery; + +include!(concat!(env!("OUT_DIR"), "/lib.rs")); diff --git a/src/spirc.rs b/connect/src/spirc.rs similarity index 100% rename from src/spirc.rs rename to connect/src/spirc.rs diff --git a/src/lib.rs b/src/lib.rs index 1d0ee72d..2ba4dac0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,6 @@ #![cfg_attr(feature = "cargo-clippy", allow(unused_io_amount))] -#[macro_use] extern crate log; - extern crate base64; extern crate crypto; extern crate futures; @@ -15,11 +13,8 @@ extern crate tokio_core; extern crate url; pub extern crate librespot_audio as audio; +pub extern crate librespot_connect as connect; pub extern crate librespot_core as core; -pub extern crate librespot_discovery as discovery; pub extern crate librespot_playback as playback; pub extern crate librespot_protocol as protocol; pub extern crate librespot_metadata as metadata; - - -include!(concat!(env!("OUT_DIR"), "/lib.rs")); diff --git a/src/main.rs b/src/main.rs index 18f47a41..8168e844 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,10 +26,10 @@ use librespot::core::version; use librespot::playback::audio_backend::{self, Sink, BACKENDS}; use librespot::playback::config::{Bitrate, PlayerConfig}; -use librespot::discovery::discovery::{discovery, DiscoveryStream}; +use librespot::connect::discovery::{discovery, DiscoveryStream}; use librespot::playback::mixer::{self, Mixer}; use librespot::playback::player::Player; -use librespot::spirc::{Spirc, SpircTask}; +use librespot::connect::spirc::{Spirc, SpircTask}; fn usage(program: &str, opts: &getopts::Options) -> String { let brief = format!("Usage: {} [options]", program); From b7c32e9d6de7e20b8249b9f5aa98ac83cdbb9c94 Mon Sep 17 00:00:00 2001 From: awiouy Date: Sun, 11 Feb 2018 18:52:53 +0100 Subject: [PATCH 3/3] rustfmt: connect --- connect/build.rs | 1 - connect/src/discovery.rs | 105 ++++++++++++++++++++++----------------- connect/src/lib.rs | 6 ++- connect/src/spirc.rs | 77 ++++++++++++++-------------- 4 files changed, 105 insertions(+), 84 deletions(-) diff --git a/connect/build.rs b/connect/build.rs index 033187ec..e8df45d5 100644 --- a/connect/build.rs +++ b/connect/build.rs @@ -10,5 +10,4 @@ fn main() { println!("cargo:rerun-if-changed=src/lib.in.rs"); println!("cargo:rerun-if-changed=src/spirc.rs"); - } diff --git a/connect/src/discovery.rs b/connect/src/discovery.rs index e29a798a..fce47bca 100644 --- a/connect/src/discovery.rs +++ b/connect/src/discovery.rs @@ -1,11 +1,11 @@ use base64; +use crypto; use crypto::digest::Digest; use crypto::mac::Mac; -use crypto; +use futures::{Future, Poll, Stream}; use futures::sync::mpsc; -use futures::{Future, Stream, Poll}; -use hyper::server::{Service, Request, Response, Http}; use hyper::{self, Get, Post, StatusCode}; +use hyper::server::{Http, Request, Response, Service}; #[cfg(feature = "with-dns-sd")] use dns_sd::DNSService; @@ -21,10 +21,10 @@ use std::sync::Arc; use tokio_core::reactor::Handle; use url; -use core::diffie_hellman::{DH_GENERATOR, DH_PRIME}; use core::authentication::Credentials; -use core::util; use core::config::ConnectConfig; +use core::diffie_hellman::{DH_GENERATOR, DH_PRIME}; +use core::util; #[derive(Clone)] struct Discovery(Arc); @@ -37,9 +37,10 @@ struct DiscoveryInner { } impl Discovery { - fn new(config: ConnectConfig, device_id: String) - -> (Discovery, mpsc::UnboundedReceiver) - { + fn new( + config: ConnectConfig, + device_id: String, + ) -> (Discovery, mpsc::UnboundedReceiver) { let (tx, rx) = mpsc::unbounded(); let key_data = util::rand_vec(&mut rand::thread_rng(), 95); @@ -59,9 +60,10 @@ impl Discovery { } impl Discovery { - fn handle_get_info(&self, _params: &BTreeMap) - -> ::futures::Finished - { + fn handle_get_info( + &self, + _params: &BTreeMap, + ) -> ::futures::Finished { let public_key = self.0.public_key.to_bytes_be(); let public_key = base64::encode(&public_key); @@ -85,9 +87,10 @@ impl Discovery { ::futures::finished(Response::new().with_body(body)) } - fn handle_add_user(&self, params: &BTreeMap) - -> ::futures::Finished - { + fn handle_add_user( + &self, + params: &BTreeMap, + ) -> ::futures::Finished { let username = params.get("userName").unwrap(); let encrypted_blob = params.get("blob").unwrap(); let client_key = params.get("clientKey").unwrap(); @@ -133,8 +136,8 @@ impl Discovery { let decrypted = { let mut data = vec![0u8; encrypted.len()]; - let mut cipher = crypto::aes::ctr(crypto::aes::KeySize::KeySize128, - &encryption_key[0..16], iv); + let mut cipher = + crypto::aes::ctr(crypto::aes::KeySize::KeySize128, &encryption_key[0..16], iv); cipher.process(encrypted, &mut data); String::from_utf8(data).unwrap() }; @@ -153,9 +156,7 @@ impl Discovery { ::futures::finished(Response::new().with_body(body)) } - fn not_found(&self) - -> ::futures::Finished - { + fn not_found(&self) -> ::futures::Finished { ::futures::finished(Response::new().with_status(StatusCode::NotFound)) } } @@ -179,19 +180,22 @@ impl Service for Discovery { } let this = self.clone(); - Box::new(body.fold(Vec::new(), |mut acc, chunk| { - acc.extend_from_slice(chunk.as_ref()); - Ok::<_, hyper::Error>(acc) - }).map(move |body| { - params.extend(url::form_urlencoded::parse(&body).into_owned()); - params - }).and_then(move |params| { - match (method, params.get("action").map(AsRef::as_ref)) { - (Get, Some("getInfo")) => this.handle_get_info(¶ms), - (Post, Some("addUser")) => this.handle_add_user(¶ms), - _ => this.not_found(), - } - })) + Box::new( + body.fold(Vec::new(), |mut acc, chunk| { + acc.extend_from_slice(chunk.as_ref()); + Ok::<_, hyper::Error>(acc) + }).map(move |body| { + params.extend(url::form_urlencoded::parse(&body).into_owned()); + params + }) + .and_then( + move |params| match (method, params.get("action").map(AsRef::as_ref)) { + (Get, Some("getInfo")) => this.handle_get_info(¶ms), + (Post, Some("addUser")) => this.handle_add_user(¶ms), + _ => this.not_found(), + }, + ), + ) } } @@ -207,22 +211,30 @@ pub struct DiscoveryStream { _svc: mdns::Service, } -pub fn discovery(handle: &Handle, config: ConnectConfig, device_id: String, port: u16) - -> io::Result -{ +pub fn discovery( + handle: &Handle, + config: ConnectConfig, + device_id: String, + port: u16, +) -> io::Result { let (discovery, creds_rx) = Discovery::new(config.clone(), device_id); let serve = { let http = Http::new(); debug!("Zeroconf server listening on 0.0.0.0:{}", port); - http.serve_addr_handle(&format!("0.0.0.0:{}", port).parse().unwrap(), &handle, move || Ok(discovery.clone())).unwrap() + http.serve_addr_handle( + &format!("0.0.0.0:{}", port).parse().unwrap(), + &handle, + move || Ok(discovery.clone()), + ).unwrap() }; let s_port = serve.incoming_ref().local_addr().port(); let server_future = { let handle = handle.clone(); - serve.for_each(move |connection| { + serve + .for_each(move |connection| { handle.spawn(connection.then(|_| Ok(()))); Ok(()) }) @@ -231,22 +243,25 @@ pub fn discovery(handle: &Handle, config: ConnectConfig, device_id: String, port handle.spawn(server_future); #[cfg(feature = "with-dns-sd")] - let svc = DNSService::register(Some(&*config.name), - "_spotify-connect._tcp", - None, - None, - s_port, - &["VERSION=1.0", "CPath=/"]).unwrap(); + let svc = DNSService::register( + Some(&*config.name), + "_spotify-connect._tcp", + None, + None, + s_port, + &["VERSION=1.0", "CPath=/"], + ).unwrap(); #[cfg(not(feature = "with-dns-sd"))] let responder = mdns::Responder::spawn(&handle)?; - + #[cfg(not(feature = "with-dns-sd"))] let svc = responder.register( "_spotify-connect._tcp".to_owned(), config.name, s_port, - &["VERSION=1.0", "CPath=/"]); + &["VERSION=1.0", "CPath=/"], + ); Ok(DiscoveryStream { credentials: creds_rx, diff --git a/connect/src/lib.rs b/connect/src/lib.rs index 22c6885f..97fff8d8 100644 --- a/connect/src/lib.rs +++ b/connect/src/lib.rs @@ -1,5 +1,7 @@ -#[macro_use] extern crate log; -#[macro_use] extern crate serde_json; +#[macro_use] +extern crate log; +#[macro_use] +extern crate serde_json; extern crate base64; extern crate crypto; diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index a34be279..704472d7 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -1,24 +1,24 @@ +use futures::{Async, Future, Poll, Sink, Stream}; use futures::future; -use futures::sync::{oneshot, mpsc}; -use futures::{Future, Stream, Sink, Async, Poll}; +use futures::sync::{mpsc, oneshot}; use protobuf::{self, Message}; use core::config::ConnectConfig; use core::mercury::MercuryError; use core::session::Session; -use core::util::{SpotifyId, SeqGenerator}; +use core::util::{SeqGenerator, SpotifyId}; use core::version; use protocol; -use protocol::spirc::{PlayStatus, State, MessageType, Frame, DeviceState}; +use protocol::spirc::{DeviceState, Frame, MessageType, PlayStatus, State}; use playback::mixer::Mixer; use playback::player::Player; -use std; use rand; use rand::Rng; -use std::time::{UNIX_EPOCH, SystemTime}; +use std; +use std::time::{SystemTime, UNIX_EPOCH}; pub struct SpircTask { player: Player, @@ -47,7 +47,7 @@ pub enum SpircCommand { Next, VolumeUp, VolumeDown, - Shutdown + Shutdown, } pub struct Spirc { @@ -152,11 +152,13 @@ fn volume_to_mixer(volume: u16) -> u16 { val } - impl Spirc { - pub fn new(config: ConnectConfig, session: Session, player: Player, mixer: Box) - -> (Spirc, SpircTask) - { + pub fn new( + config: ConnectConfig, + session: Session, + player: Player, + mixer: Box, + ) -> (Spirc, SpircTask) { debug!("new Spirc[{}]", session.session_id()); let ident = session.device_id().to_owned(); @@ -164,15 +166,20 @@ impl Spirc { let uri = format!("hm://remote/3/user/{}/", session.username()); let subscription = session.mercury().subscribe(&uri as &str); - let subscription = subscription.map(|stream| stream.map_err(|_| MercuryError)).flatten_stream(); + let subscription = subscription + .map(|stream| stream.map_err(|_| MercuryError)) + .flatten_stream(); let subscription = Box::new(subscription.map(|response| -> Frame { let data = response.payload.first().unwrap(); protobuf::parse_from_bytes(data).unwrap() })); - let sender = Box::new(session.mercury().sender(uri).with(|frame: Frame| { - Ok(frame.write_to_bytes().unwrap()) - })); + let sender = Box::new( + session + .mercury() + .sender(uri) + .with(|frame: Frame| Ok(frame.write_to_bytes().unwrap())), + ); let (cmd_tx, cmd_rx) = mpsc::unbounded(); @@ -200,9 +207,7 @@ impl Spirc { session: session.clone(), }; - let spirc = Spirc { - commands: cmd_tx, - }; + let spirc = Spirc { commands: cmd_tx }; task.hello(); @@ -268,9 +273,7 @@ impl Future for SpircTask { self.handle_end_of_track(); } Ok(Async::NotReady) => (), - Err(oneshot::Canceled) => { - self.end_of_track = Box::new(future::empty()) - } + Err(oneshot::Canceled) => self.end_of_track = Box::new(future::empty()), } } @@ -357,15 +360,18 @@ impl SpircTask { } fn handle_frame(&mut self, frame: Frame) { - debug!("{:?} {:?} {} {} {}", - frame.get_typ(), - frame.get_device_state().get_name(), - frame.get_ident(), - frame.get_seq_nr(), - frame.get_state_update_id()); + debug!( + "{:?} {:?} {} {} {}", + frame.get_typ(), + frame.get_device_state().get_name(), + frame.get_ident(), + frame.get_seq_nr(), + frame.get_state_update_id() + ); - if frame.get_ident() == self.ident || - (frame.get_recipient().len() > 0 && !frame.get_recipient().contains(&self.ident)) { + if frame.get_ident() == self.ident + || (frame.get_recipient().len() > 0 && !frame.get_recipient().contains(&self.ident)) + { return; } @@ -383,7 +389,8 @@ impl SpircTask { self.update_tracks(&frame); if self.state.get_track().len() > 0 { - self.state.set_position_ms(frame.get_state().get_position_ms()); + self.state + .set_position_ms(frame.get_state().get_position_ms()); self.state.set_position_measured_at(now_ms() as u64); let play = frame.get_state().get_status() == PlayStatus::kPlayStatusPlay; @@ -437,8 +444,7 @@ impl SpircTask { MessageType::kMessageTypeShuffle => { self.state.set_shuffle(frame.get_state().get_shuffle()); - if self.state.get_shuffle() - { + if self.state.get_shuffle() { let current_index = self.state.get_playing_track_index(); { let tracks = self.state.mut_track(); @@ -471,14 +477,13 @@ impl SpircTask { MessageType::kMessageTypeVolume => { self.device.set_volume(frame.get_volume()); - self.mixer.set_volume(volume_to_mixer(frame.get_volume() as u16)); + self.mixer + .set_volume(volume_to_mixer(frame.get_volume() as u16)); self.notify(None); } MessageType::kMessageTypeNotify => { - if self.device.get_is_active() && - frame.get_device_state().get_is_active() - { + if self.device.get_is_active() && frame.get_device_state().get_is_active() { self.device.set_is_active(false); self.state.set_status(PlayStatus::kPlayStatusStop); self.player.stop();