From be6910f72066be7020bb80e7232b69334b77bd22 Mon Sep 17 00:00:00 2001 From: Gianlu Date: Mon, 17 Sep 2018 15:00:30 +0200 Subject: [PATCH 1/9] Added librespot-java to related projects --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ea5b520..dc09ee13 100644 --- a/README.md +++ b/README.md @@ -87,5 +87,7 @@ This is a non exhaustive list of projects that either use or have modified libre - [plugin.audio.spotify](https://github.com/marcelveldt/plugin.audio.spotify) - A Kodi plugin for Spotify. - [raspotify](https://github.com/dtcooper/raspotify) - Spotify Connect client for the Raspberry Pi that Just Works™ - [Spotifyd](https://github.com/Spotifyd/spotifyd) - A stripped down librespot UNIX daemon. -- [Spotcontrol](https://github.com/badfortrains/spotcontrol) - A golang implementation of a Spotify Connect controller. No playback functionality. +- [Spotcontrol](https://github.com/badfortrains/spotcontrol) - A golang implementation of a Spotify Connect controller. No playback +functionality. +- [librespot-java](https://github.com/devgianlu/librespot-java) - A Java port of librespot. From eaac599ce33c8d1b19804ddbef0c7ddebaa2421a Mon Sep 17 00:00:00 2001 From: "William R. Fraser" Date: Tue, 16 Oct 2018 00:24:33 -0700 Subject: [PATCH 2/9] reap the exit statuses from 'onevent' child processes --- src/child_wait_future.rs | 21 +++++++++++++++++++++ src/main.rs | 14 +++++++++++++- src/player_event_handler.rs | 10 +++++----- 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 src/child_wait_future.rs diff --git a/src/child_wait_future.rs b/src/child_wait_future.rs new file mode 100644 index 00000000..8a05c677 --- /dev/null +++ b/src/child_wait_future.rs @@ -0,0 +1,21 @@ +use futures::{Async, Future}; +use std::io; +use std::process::{Child, ExitStatus}; + +/// A future that resolves to a child process's exit status once it exits. +pub struct ChildWaitFuture { + pub child: Child, +} + +impl Future for ChildWaitFuture { + type Item = ExitStatus; + type Error = io::Error; + + fn poll(&mut self) -> Result, Self::Error> { + match self.child.try_wait() { + Ok(Some(status)) => Ok(Async::Ready(status)), + Ok(None) => Ok(Async::NotReady), + Err(e) => Err(e), + } + } +} diff --git a/src/main.rs b/src/main.rs index a18d7b5c..8e5442eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,9 @@ use librespot::playback::config::{Bitrate, PlayerConfig}; use librespot::playback::mixer::{self, Mixer}; use librespot::playback::player::{Player, PlayerEvent}; +mod child_wait_future; +use child_wait_future::ChildWaitFuture; + mod player_event_handler; use player_event_handler::run_program_on_events; @@ -466,7 +469,16 @@ impl Future for Main { if let Some(ref mut player_event_channel) = self.player_event_channel { if let Async::Ready(Some(event)) = player_event_channel.poll().unwrap() { if let Some(ref program) = self.player_event_program { - run_program_on_events(event, program); + let child = run_program_on_events(event, program) + .expect("program failed to start"); + + let wait_future = ChildWaitFuture { child } + .map(|status| if !status.success() { + error!("child exited with status {:?}", status.code()); + }) + .map_err(|e| error!("failed to wait on child process: {}", e)); + + self.handle.spawn(wait_future); } } } diff --git a/src/player_event_handler.rs b/src/player_event_handler.rs index b6a653dd..1d72d182 100644 --- a/src/player_event_handler.rs +++ b/src/player_event_handler.rs @@ -1,18 +1,18 @@ use librespot::playback::player::PlayerEvent; use std::collections::HashMap; -use std::process::Command; +use std::io; +use std::process::{Child, Command}; -fn run_program(program: &str, env_vars: HashMap<&str, String>) { +fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result { let mut v: Vec<&str> = program.split_whitespace().collect(); info!("Running {:?} with environment variables {:?}", v, env_vars); Command::new(&v.remove(0)) .args(&v) .envs(env_vars.iter()) .spawn() - .expect("program failed to start"); } -pub fn run_program_on_events(event: PlayerEvent, onevent: &str) { +pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> io::Result { let mut env_vars = HashMap::new(); match event { PlayerEvent::Changed { @@ -32,5 +32,5 @@ pub fn run_program_on_events(event: PlayerEvent, onevent: &str) { env_vars.insert("TRACK_ID", track_id.to_base16()); } } - run_program(onevent, env_vars); + run_program(onevent, env_vars) } From 9fa138a116a9b06bdd3440195acedba6c14ed0e4 Mon Sep 17 00:00:00 2001 From: "William R. Fraser" Date: Tue, 16 Oct 2018 02:32:17 -0700 Subject: [PATCH 3/9] implement using tokio-process instead --- Cargo.lock | 75 +++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + src/child_wait_future.rs | 21 ----------- src/main.rs | 11 ++---- src/player_event_handler.rs | 5 ++- 5 files changed, 79 insertions(+), 34 deletions(-) delete mode 100644 src/child_wait_future.rs diff --git a/Cargo.lock b/Cargo.lock index c1aa626a..da12b203 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,6 +389,7 @@ dependencies = [ "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-process 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -591,6 +592,17 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio-uds" version = "0.6.4" @@ -611,6 +623,15 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "miow" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "multimap" version = "0.3.0" @@ -782,7 +803,7 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -980,6 +1001,17 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "socket2" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.11.11" @@ -1021,7 +1053,7 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1048,7 +1080,7 @@ version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1104,6 +1136,21 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-process" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-signal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-proto" version = "0.1.1" @@ -1156,6 +1203,21 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-tcp" version = "0.1.0" @@ -1453,8 +1515,10 @@ dependencies = [ "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" "checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" +"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" "checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" "checksum multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9223f4774d08e06185e44e555b9a7561243d387bac49c78a6205c42d6975fbf2" "checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" "checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487" @@ -1477,7 +1541,7 @@ dependencies = [ "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" +"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" "checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" @@ -1503,6 +1567,7 @@ dependencies = [ "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b4896961171cd3317c7e9603d88f379f8c6e45342212235d356496680c68fd" +"checksum socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "06dc9f86ee48652b7c80f3d254e3b9accb67a928c562c64d10d7b016d3d98dab" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90d5efaad92a0f96c629ae16302cc9591915930fd49ff0dcc6b4cde146782397" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" @@ -1515,10 +1580,12 @@ dependencies = [ "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" "checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" +"checksum tokio-process 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0832648d1ff7ca42c06ca45dc76797b92c56500de828e33c77276fa1449947b6" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" +"checksum tokio-signal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b6893092932264944edee8486d54b578c7098bea794aedaf9bd7947b49e6b7bf" "checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" "checksum tokio-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3d05cdd6a78005e535d2b27c21521bdf91fbb321027a62d8e178929d18966d" "checksum tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29a89e4ad0c8f1e4c9860e605c38c69bfdad3cccd4ea446e58ff588c1c07a397" diff --git a/Cargo.toml b/Cargo.toml index 3af02908..88b59667 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ serde_derive = "0.9.6" serde_json = "0.9.5" tokio-core = "0.1.2" tokio-io = "0.1" +tokio-process = "0.2.2" tokio-signal = "0.1.2" url = "1.7.0" diff --git a/src/child_wait_future.rs b/src/child_wait_future.rs deleted file mode 100644 index 8a05c677..00000000 --- a/src/child_wait_future.rs +++ /dev/null @@ -1,21 +0,0 @@ -use futures::{Async, Future}; -use std::io; -use std::process::{Child, ExitStatus}; - -/// A future that resolves to a child process's exit status once it exits. -pub struct ChildWaitFuture { - pub child: Child, -} - -impl Future for ChildWaitFuture { - type Item = ExitStatus; - type Error = io::Error; - - fn poll(&mut self) -> Result, Self::Error> { - match self.child.try_wait() { - Ok(Some(status)) => Ok(Async::Ready(status)), - Ok(None) => Ok(Async::NotReady), - Err(e) => Err(e), - } - } -} diff --git a/src/main.rs b/src/main.rs index 8e5442eb..36cd1b5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ extern crate log; extern crate rpassword; extern crate tokio_core; extern crate tokio_io; +extern crate tokio_process; extern crate tokio_signal; extern crate url; @@ -39,9 +40,6 @@ use librespot::playback::config::{Bitrate, PlayerConfig}; use librespot::playback::mixer::{self, Mixer}; use librespot::playback::player::{Player, PlayerEvent}; -mod child_wait_future; -use child_wait_future::ChildWaitFuture; - mod player_event_handler; use player_event_handler::run_program_on_events; @@ -470,15 +468,14 @@ impl Future for Main { if let Async::Ready(Some(event)) = player_event_channel.poll().unwrap() { if let Some(ref program) = self.player_event_program { let child = run_program_on_events(event, program) - .expect("program failed to start"); - - let wait_future = ChildWaitFuture { child } + .expect("program failed to start") .map(|status| if !status.success() { error!("child exited with status {:?}", status.code()); }) .map_err(|e| error!("failed to wait on child process: {}", e)); - self.handle.spawn(wait_future); + self.handle.spawn(child); + } } } diff --git a/src/player_event_handler.rs b/src/player_event_handler.rs index 1d72d182..23c02313 100644 --- a/src/player_event_handler.rs +++ b/src/player_event_handler.rs @@ -1,7 +1,8 @@ use librespot::playback::player::PlayerEvent; +use tokio_process::{Child, CommandExt}; use std::collections::HashMap; use std::io; -use std::process::{Child, Command}; +use std::process::Command; fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result { let mut v: Vec<&str> = program.split_whitespace().collect(); @@ -9,7 +10,7 @@ fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result io::Result { From 473fc188cde4307dcdb6435d64a7feb4e40e557a Mon Sep 17 00:00:00 2001 From: Sasha Hilton Date: Tue, 30 Oct 2018 17:57:24 +0000 Subject: [PATCH 4/9] Bump minimum version for Travis Builds --- .travis.yml | 2 +- README.md | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b394ad1..bd936967 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: rust rust: - - 1.21.0 + - 1.23.0 - stable - beta - nightly diff --git a/README.md b/README.md index dc09ee13..440a528e 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ Note: librespot only works with Spotify Premium As the origin by [plietar](https://github.com/plietar/) is no longer actively maintained, this organisation and repository have been set up so that the project may be maintained and upgraded in the future. # Documentation -Documentation is currently a work in progress. +Documentation is currently a work in progress. -There is some brief documentation on how the protocol works in the [docs](https://github.com/librespot-org/librespot/tree/master/docs) folder, and more general usage and compilation information is available on the [wiki](https://github.com/librespot-org/librespot/wiki). +There is some brief documentation on how the protocol works in the [docs](https://github.com/librespot-org/librespot/tree/master/docs) folder, and more general usage and compilation information is available on the [wiki](https://github.com/librespot-org/librespot/wiki). -[CONTRIBUTING.md](https://github.com/librespot-org/librespot/blob/master/CONTRIBUTING.md) also contains detailed instructions on setting up a development environment, compilation, and contributing guidelines. +[CONTRIBUTING.md](https://github.com/librespot-org/librespot/blob/master/CONTRIBUTING.md) also contains detailed instructions on setting up a development environment, compilation, and contributing guidelines. If you wish to learn more about how librespot works overall, the best way is to simply read the code, and ask any questions you have in the Gitter chat linked above. @@ -26,7 +26,7 @@ If you wish to learn more about how librespot works overall, the best way is to If you run into a bug when using librespot, please search the existing issues before opening a new one. Chances are, we've encountered it before, and have provided a resolution. If not, please open a new one, and where possible, include the backtrace librespot generates on crashing, along with anything we can use to reproduce the issue, eg. the Spotify URI of the song that caused the crash. # Building -Rust 1.21.0 or later is required to build librespot. +Rust 1.23.0 or later is required to build librespot. **If you are building librespot on macOS, the homebrew provided rust may fail due to the way in which homebrew installs rust. In this case, uninstall the homebrew version of rust and use [rustup](https://www.rustup.rs/), and librespot should then build. This should have been fixed in more recent versions of Homebrew, but we're leaving this notice here as a warning.** @@ -58,7 +58,7 @@ cargo build --release A sample program implementing a headless Spotify Connect receiver is provided. Once you've built *librespot*, run it using : ```shell -target/release/librespot --name DEVICENAME +target/release/librespot --name DEVICENAME ``` The above is a minimal example. Here is a more fully fledged one: @@ -90,4 +90,3 @@ This is a non exhaustive list of projects that either use or have modified libre - [Spotcontrol](https://github.com/badfortrains/spotcontrol) - A golang implementation of a Spotify Connect controller. No playback functionality. - [librespot-java](https://github.com/devgianlu/librespot-java) - A Java port of librespot. - From 7cbf6d173b4e4624e237808c3ff8fe6e0086fda7 Mon Sep 17 00:00:00 2001 From: awiouy Date: Thu, 1 Nov 2018 14:03:51 +0100 Subject: [PATCH 5/9] update lewton to 0.9.3 --- Cargo.lock | 22 ++++++++++++++++------ audio/Cargo.toml | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 910a6f5e..f8a53bfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,11 +333,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lewton" -version = "0.8.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ogg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ogg 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -402,7 +403,7 @@ dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "lewton 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lewton 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "librespot-core 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -706,7 +707,7 @@ dependencies = [ [[package]] name = "ogg" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1030,6 +1031,14 @@ name = "smallvec" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "smallvec" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "socket2" version = "0.2.4" @@ -1552,7 +1561,7 @@ dependencies = [ "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" -"checksum lewton 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d170da25c0b3541e3260f84aa8f9d323468083bd1ed6c4c15aec7ff33e2a1c4" +"checksum lewton 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "81d583f12101d36b9c19f85326f3c4e7d3b88d17f1131113e13da056dc0d4437" "checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" "checksum libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd38073de8f7965d0c17d30546d4bb6da311ab428d1c7a3fc71dff7f9d4979b9" "checksum libpulse-sys 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9bb11b06faf883500c1b625cf4453e6c7737e9df9c7ba01df3f84b22b083e4ac" @@ -1578,7 +1587,7 @@ dependencies = [ "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum ogg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f8de5433300a8a0ba60a3207766a3ce9efdede6aaab23311b5a8cf1664fe2e9" +"checksum ogg 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d79f1db9148be9d0e174bb3ac890f6030fcb1ed947267c5a91ee4c91b5a91e15" "checksum ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a95b8c172e17df1a41bf8d666301d3b2c4efeb90d9d0415e2a4dc0668b35fdb2" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" @@ -1621,6 +1630,7 @@ dependencies = [ "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" +"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" "checksum socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b4896961171cd3317c7e9603d88f379f8c6e45342212235d356496680c68fd" "checksum socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "06dc9f86ee48652b7c80f3d254e3b9accb67a928c562c64d10d7b016d3d98dab" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" diff --git a/audio/Cargo.toml b/audio/Cargo.toml index 2a9e134c..5c61b694 100644 --- a/audio/Cargo.toml +++ b/audio/Cargo.toml @@ -10,7 +10,7 @@ path = "../core" bit-set = "0.4.0" byteorder = "1.0" futures = "0.1.8" -lewton = "0.8.0" +lewton = "0.9.3" log = "0.3.5" num-bigint = "0.1.35" num-traits = "0.1.36" From 0331a7f592a8d7086cc211de1ce8e648356b68d0 Mon Sep 17 00:00:00 2001 From: Sasha Hilton Date: Sat, 3 Nov 2018 16:20:52 +0100 Subject: [PATCH 6/9] Remove contrib from .dockerignore See https://github.com/librespot-org/librespot/issues/243 for reason. Causes docker to fail for RPi builds. --- .dockerignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index 3aeac254..7b0f1998 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,3 @@ target cache protocol/target -contrib From 81e7c9b9d3678b3cb6aaaf47785e662287fd8480 Mon Sep 17 00:00:00 2001 From: ruben Date: Sun, 4 Nov 2018 18:41:33 +0100 Subject: [PATCH 7/9] Changed TRACK_ID from base16 to base62 so that it is equal with the official Spotify app --- src/player_event_handler.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/player_event_handler.rs b/src/player_event_handler.rs index 23c02313..1e682b98 100644 --- a/src/player_event_handler.rs +++ b/src/player_event_handler.rs @@ -21,16 +21,16 @@ pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> io::Result { env_vars.insert("PLAYER_EVENT", "change".to_string()); - env_vars.insert("OLD_TRACK_ID", old_track_id.to_base16()); - env_vars.insert("TRACK_ID", new_track_id.to_base16()); + env_vars.insert("OLD_TRACK_ID", old_track_id.to_base62()); + env_vars.insert("TRACK_ID", new_track_id.to_base62()); } PlayerEvent::Started { track_id } => { env_vars.insert("PLAYER_EVENT", "start".to_string()); - env_vars.insert("TRACK_ID", track_id.to_base16()); + env_vars.insert("TRACK_ID", track_id.to_base62()); } PlayerEvent::Stopped { track_id } => { env_vars.insert("PLAYER_EVENT", "stop".to_string()); - env_vars.insert("TRACK_ID", track_id.to_base16()); + env_vars.insert("TRACK_ID", track_id.to_base62()); } } run_program(onevent, env_vars) From 74e0adac15dd3aefe666955aafb5aa7e7a1c5108 Mon Sep 17 00:00:00 2001 From: Sasha Hilton Date: Sat, 10 Nov 2018 21:31:03 +0100 Subject: [PATCH 8/9] Fix seek past EOF panic for some tracks --- audio/src/fetch.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/audio/src/fetch.rs b/audio/src/fetch.rs index e5e461a4..1aa0c0c0 100644 --- a/audio/src/fetch.rs +++ b/audio/src/fetch.rs @@ -348,11 +348,16 @@ impl Read for AudioFileStreaming { impl Seek for AudioFileStreaming { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.position = try!(self.read_file.seek(pos)); + // Do not seek past EOF + if (self.position as usize % CHUNK_SIZE) != 0 { + // Notify the fetch thread to get the correct block + // This can fail if fetch thread has completed, in which case the + // block is ready. Just ignore the error. + let _ = self.seek.unbounded_send(self.position); + } else { + warn!("Trying to seek past EOF"); + } - // Notify the fetch thread to get the correct block - // This can fail if fetch thread has completed, in which case the - // block is ready. Just ignore the error. - let _ = self.seek.unbounded_send(self.position); Ok(self.position) } } From 9b6b55ee7d692ad626591ec3064b6e6b74a6d360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85ke=20Forslund?= Date: Fri, 22 Feb 2019 14:09:01 +0100 Subject: [PATCH 9/9] Update subscription uri This fixes an issue loading new tracks probably caused by an update on spotify's side. The fix was suggested by @worleydl, all glory to them for figuring it out. --- connect/src/spirc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 87bf4645..3fe3c273 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -214,7 +214,8 @@ impl Spirc { let ident = session.device_id().to_owned(); - let uri = format!("hm://remote/3/user/{}/", session.username()); + // Uri updated in response to issue #288 + let uri = format!("hm://remote/user/{}/", session.username()); let subscription = session.mercury().subscribe(&uri as &str); let subscription = subscription