From 4e02ef5a6cca76b852cbf212d22ac6d79d68c742 Mon Sep 17 00:00:00 2001 From: Mitch Bigelow Date: Sat, 14 Jan 2017 16:22:33 -0500 Subject: [PATCH 1/6] Stop pulseaudio sink when not in use --- src/audio_backend/pulseaudio.rs | 53 ++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/audio_backend/pulseaudio.rs b/src/audio_backend/pulseaudio.rs index 05876fe..b2afe50 100644 --- a/src/audio_backend/pulseaudio.rs +++ b/src/audio_backend/pulseaudio.rs @@ -5,7 +5,12 @@ use std::ptr::{null, null_mut}; use std::mem::{transmute}; use std::ffi::CString; -pub struct PulseAudioSink(*mut pa_simple); +pub struct PulseAudioSink { + s : *mut pa_simple, + ss : pa_sample_spec, + name : CString, + desc : CString +} impl Open for PulseAudioSink { fn open(device: Option<&str>) -> PulseAudioSink { @@ -24,30 +29,40 @@ impl Open for PulseAudioSink { let name = CString::new("librespot").unwrap(); let description = CString::new("A spoty client library").unwrap(); - let s = unsafe { - pa_simple_new(null(), // Use the default server. - name.as_ptr(), // Our application's name. - PA_STREAM_PLAYBACK, - null(), // Use the default device. - description.as_ptr(), // Description of our stream. - &ss, // Our sample format. - null(), // Use default channel map - null(), // Use default buffering attributes. - null_mut(), // Ignore error code. - ) - }; - assert!(s != null_mut()); - - PulseAudioSink(s) + PulseAudioSink { + s: null_mut(), + ss: ss, + name: name, + desc: description + } } } impl Sink for PulseAudioSink { fn start(&mut self) -> io::Result<()> { + if self.s == null_mut() { + self.s = unsafe { + pa_simple_new(null(), // Use the default server. + self.name.as_ptr(), // Our application's name. + PA_STREAM_PLAYBACK, + null(), // Use the default device. + self.desc.as_ptr(), // desc of our stream. + &self.ss, // Our sample format. + null(), // Use default channel map + null(), // Use default buffering attributes. + null_mut(), // Ignore error code. + ) + }; + assert!(self.s != null_mut()); + } Ok(()) } fn stop(&mut self) -> io::Result<()> { + unsafe { + pa_simple_free(self.s); + } + self.s = null_mut(); Ok(()) } @@ -55,13 +70,9 @@ impl Sink for PulseAudioSink { unsafe { let ptr = transmute(data.as_ptr()); let bytes = data.len() as usize * 2; - pa_simple_write(self.0, ptr, bytes, null_mut()); + pa_simple_write(self.s, ptr, bytes, null_mut()); }; Ok(()) } } - - - - From 55812893517cc8b5a39d8582ce8bf66570022421 Mon Sep 17 00:00:00 2001 From: nsteel Date: Fri, 27 Oct 2017 18:45:02 +0100 Subject: [PATCH 2/6] Added repeat support --- src/spirc.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/spirc.rs b/src/spirc.rs index 3b5fb77..06f2063 100644 --- a/src/spirc.rs +++ b/src/spirc.rs @@ -396,6 +396,11 @@ impl SpircTask { self.notify(None); } + MessageType::kMessageTypeRepeat => { + self.state.set_repeat(frame.get_state().get_repeat()); + self.notify(None); + } + MessageType::kMessageTypeSeek => { let position = frame.get_position(); @@ -467,13 +472,19 @@ impl SpircTask { fn handle_next(&mut self) { let current_index = self.state.get_playing_track_index(); - let new_index = (current_index + 1) % (self.state.get_track().len() as u32); + let num_tracks = self.state.get_track().len() as u32; + let new_index = (current_index + 1) % num_tracks; + + let mut was_last_track = (current_index + 1) >= num_tracks; + if self.state.get_repeat() { + was_last_track = false; + } self.state.set_playing_track_index(new_index); self.state.set_position_ms(0); self.state.set_position_measured_at(now_ms() as u64); - self.load_track(true); + self.load_track(!was_last_track); } fn handle_prev(&mut self) { @@ -520,14 +531,7 @@ impl SpircTask { } fn handle_end_of_track(&mut self) { - let current_index = self.state.get_playing_track_index(); - let new_index = (current_index + 1) % (self.state.get_track().len() as u32); - - self.state.set_playing_track_index(new_index); - self.state.set_position_ms(0); - self.state.set_position_measured_at(now_ms() as u64); - - self.load_track(true); + self.handle_next(); self.notify(None); } From 628df27292e08d44400e4639a8ef25f50ecbb804 Mon Sep 17 00:00:00 2001 From: Nick Steel Date: Fri, 3 Nov 2017 01:15:27 +0000 Subject: [PATCH 3/6] Support for enabling shuffle. --- src/spirc.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/spirc.rs b/src/spirc.rs index 06f2063..750badc 100644 --- a/src/spirc.rs +++ b/src/spirc.rs @@ -17,6 +17,9 @@ use protocol::spirc::{PlayStatus, State, MessageType, Frame, DeviceState}; use mixer::Mixer; use player::Player; +use rand; +use rand::Rng; + pub struct SpircTask { player: Player, mixer: Box, @@ -401,6 +404,26 @@ impl SpircTask { self.notify(None); } + MessageType::kMessageTypeShuffle => { + self.state.set_shuffle(frame.get_state().get_shuffle()); + if self.state.get_shuffle() + { + let current_index = self.state.get_playing_track_index(); + { + let tracks = self.state.mut_track(); + tracks.swap(0, current_index as usize); + if let Some((_, rest)) = tracks.split_first_mut() { + rand::thread_rng().shuffle(rest); + } + } + self.state.set_playing_track_index(0); + } else { + let context = self.state.get_context_uri(); + debug!("{:?}", context); + } + self.notify(None); + } + MessageType::kMessageTypeSeek => { let position = frame.get_position(); From 80493d8bbe5ab11570e3328644293a2eda844831 Mon Sep 17 00:00:00 2001 From: ComlOnline Date: Mon, 20 Nov 2017 00:55:34 +0000 Subject: [PATCH 4/6] README Upadte --- README.md | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index eead876..1d749d6 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,16 @@ applications to use Spotify's service, without using the official but closed-source libspotify. Additionally, it will provide extra features which are not available in the official library. -Note: librespot only works with Spotify Premium. +Note: librespot needs to be logged in and only works with Spotify Premium -# Unmaintained -Unfortunately I am unable to maintain librespot anymore. It should still work, -but issues and Pull requests will be ignored. Feel free to fork it and continue -development there. If a fork gains traction I will happily point to it from the -README. +# THIS FORK +As the origin is no longer maintained I wanted to have a place for a version of librespot with other peoples forks and features merged. + +# THANKS +I've done noting more than make this pretty so big thanks to: +[plietar](https://github.com/plietar/) for making the thing in the first place. +[kingosticks](https://github.com/kingosticks/) For the Suffling and Repeat. +[ipha](https://github.com/ipha/) For the start stop audio sink. ## Building Rust 1.17.0 or later is required to build librespot. @@ -46,9 +49,27 @@ Once you've built *librespot*, run it using : target/release/librespot --username USERNAME --cache CACHEDIR --name DEVICENAME ``` -## Discovery mode -*librespot* can be run in discovery mode, in which case no password is required at startup. -For that, simply omit the `--username` argument. +### All options + +| Type | Short | Long | Description | Hint | +|----------|-------|---------------------|-------------------------------------------------|-------------| +| Option | c | cache | Path to a directory where files will be cached. | CACHE | +| Flag | | disable-audio-cache | Disable caching of the audio data. | | +| Required | n | name | Device name | NAME | +| Option | | device-type | Displayed device type | DEVICE_TYPE | +| Option | b | bitrate | Bitrate (96, 160 or 320). Defaults to 160 | BITRATE | +| Option | | onstart | Run PROGRAM when playback is about to begin. | | +| Option | | onstop | Run PROGRAM when playback has ended. | PROGRAM | +| Flag | v | verbose | Enable verbose output | PROGRAM | +| Option | u | username | Username to sign in with | USERNAME | +| Option | p | password | Password | PASSWORD | +| Flag | | disable-discovery | Disable discovery mode | | +| Option | | backend | Audio backend to use. Use '?' to list options | BACKEND | +| Option | | device | Audio device to use. Use '?' to list options | DEVICE | +| Option | | mixer | Mixer to use | MIXER | + +Taken from here: +https://github.com/ComlOnline/librespot/blob/master/src/main.rs#L88 ## Audio Backends *librespot* supports various audio backends. Multiple backends can be enabled at compile time by enabling the From 2a215278ef7841e4e516193c8c6d31f5c404b7b2 Mon Sep 17 00:00:00 2001 From: ComlOnline Date: Thu, 23 Nov 2017 00:14:29 +0000 Subject: [PATCH 5/6] Edit to puch for travis --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d749d6..95ab3b4 100644 --- a/README.md +++ b/README.md @@ -128,5 +128,4 @@ Come and hang out on gitter if you need help or want to offer some. https://gitter.im/sashahilton00/spotify-connect-resources ## License -Everything in this repository is licensed under the MIT license. - +Everything in this repository is licensed under the MIT license. \ No newline at end of file From 5141f434b576448e9667a5af9e23c5a4111159c0 Mon Sep 17 00:00:00 2001 From: ComlOnline Date: Thu, 23 Nov 2017 11:19:47 +0000 Subject: [PATCH 6/6] Add travis ci tag --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 95ab3b4..d3629ce 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/ComlOnline/librespot.svg?branch=master)](https://travis-ci.org/ComlOnline/librespot) + # librespot *librespot* is an open source client library for Spotify. It enables applications to use Spotify's service, without using the official but @@ -9,6 +11,7 @@ Note: librespot needs to be logged in and only works with Spotify Premium # THIS FORK As the origin is no longer maintained I wanted to have a place for a version of librespot with other peoples forks and features merged. + # THANKS I've done noting more than make this pretty so big thanks to: [plietar](https://github.com/plietar/) for making the thing in the first place.