Skip to content

Commit 31e6368

Browse files
committed
Merge branch by clxxiii into hotfix_librespot_0.7
2 parents 1f7e8fc + 0cfbfc5 commit 31e6368

8 files changed

Lines changed: 221 additions & 115 deletions

File tree

Cargo.lock

Lines changed: 141 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ libc = "0.2.82"
2323
log = "0.4.6"
2424
serde = { version = "1.0.115", features = ["derive"] }
2525
sha-1 = "0.10"
26-
tokio = {version = "1.26.0", features = ["signal", "rt-multi-thread", "process", "io-std"] }
26+
tokio = {version = "1.44.2", features = ["signal", "rt-multi-thread", "process", "io-std"] }
2727
tokio-stream = "0.1.7"
2828
url = "2.2.2"
2929
librespot-audio = { version = "0.7.1", default-features = false }
@@ -68,7 +68,7 @@ rodio_backend = ["librespot-playback/rodio-backend"]
6868
rodiojack_backend = ["librespot-playback/rodiojack-backend"]
6969

7070
[package.metadata.deb]
71-
depends = "$auto, systemd, pulseaudio"
71+
depends = "$auto"
7272
features = ["pulseaudio_backend", "dbus_mpris"]
7373
assets = [
7474
["target/release/spotifyd", "usr/bin/", "755"],

src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
673673
.volume_controller
674674
.unwrap_or(VolumeController::SoftVolume);
675675

676+
let default_initial_volume = 90;
676677
let initial_volume: u16 = config
677678
.shared_config
678679
.initial_volume
@@ -685,8 +686,7 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
685686
}
686687
})
687688
.map(|volume| (volume as i32 * (u16::MAX as i32) / 100) as u16)
688-
.unwrap_or((90_i32 * (u16::MAX as i32) / 100) as u16); // default to 90%
689-
warn!("initial_volume: {initial_volume}");
689+
.unwrap_or((default_initial_volume * (u16::MAX as i32) / 100) as u16);
690690

691691
let device_name = config
692692
.shared_config

src/dbus_mpris.rs

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use futures::{
1313
Future,
1414
task::{Context, Poll},
1515
};
16-
use librespot_connect::{LoadRequest, LoadRequestOptions, Spirc};
16+
use librespot_connect::{LoadContextOptions, LoadRequest, LoadRequestOptions, Spirc};
1717
use librespot_core::{Session, SpotifyId, spotify_id::SpotifyItemType};
1818
use librespot_metadata::audio::AudioItem;
1919
use librespot_playback::player::PlayerEvent;
@@ -139,33 +139,36 @@ impl Position {
139139
#[derive(Clone, Copy, Debug)]
140140
enum RepeatState {
141141
None,
142-
// Track,
142+
Track,
143143
All,
144144
}
145145

146146
impl RepeatState {
147147
fn to_mpris(self) -> &'static str {
148148
match self {
149149
RepeatState::None => "None",
150-
// RepeatState::Track => "Track",
150+
RepeatState::Track => "Track",
151151
RepeatState::All => "Playlist",
152152
}
153153
}
154-
}
155154

156-
impl From<RepeatState> for bool {
157-
fn from(repeat: RepeatState) -> Self {
158-
match repeat {
159-
RepeatState::None => false,
160-
RepeatState::All => true,
161-
}
155+
fn repeat_track(self) -> bool {
156+
matches!(self, RepeatState::Track)
157+
}
158+
159+
fn repeat_context(self) -> bool {
160+
!matches!(self, RepeatState::None)
162161
}
163162
}
164163

165-
impl From<bool> for RepeatState {
166-
fn from(repeat: bool) -> Self {
167-
if repeat {
168-
RepeatState::All
164+
impl From<(bool, bool)> for RepeatState {
165+
fn from((context, track): (bool, bool)) -> Self {
166+
if context {
167+
if track {
168+
RepeatState::Track
169+
} else {
170+
RepeatState::All
171+
}
169172
} else {
170173
RepeatState::None
171174
}
@@ -264,6 +267,7 @@ impl CurrentStateInner {
264267
insert_attr(&mut changed, "Metadata", self.to_metadata());
265268
}
266269
PlayerEvent::PositionCorrection { position_ms, .. }
270+
| PlayerEvent::PositionChanged { position_ms, .. }
267271
| PlayerEvent::Seeked { position_ms, .. } => {
268272
self.update_position(Duration::milliseconds(position_ms as i64));
269273
seeked = true;
@@ -272,8 +276,8 @@ impl CurrentStateInner {
272276
self.shuffle = shuffle;
273277
insert_attr(&mut changed, "Shuffle", self.shuffle);
274278
}
275-
PlayerEvent::RepeatChanged { context: _, track } => {
276-
self.repeat = track.into();
279+
PlayerEvent::RepeatChanged { context, track } => {
280+
self.repeat = (context, track).into();
277281
insert_attr(
278282
&mut changed,
279283
"LoopStatus",
@@ -293,7 +297,6 @@ impl CurrentStateInner {
293297
| PlayerEvent::SessionConnected { .. }
294298
| PlayerEvent::SessionDisconnected { .. }
295299
| PlayerEvent::SessionClientChanged { .. } => (),
296-
PlayerEvent::PositionChanged { .. } => (),
297300
}
298301

299302
(changed, seeked)
@@ -644,8 +647,9 @@ fn register_player_interface(
644647
});
645648
let local_spirc = spirc.clone();
646649
b.method("Stop", (), (), move |_, _, (): ()| {
650+
let pause_playback = false;
647651
local_spirc
648-
.disconnect(false)
652+
.disconnect(pause_playback)
649653
.map_err(|e| MethodErr::failed(&e))
650654
});
651655

@@ -710,23 +714,25 @@ fn register_player_interface(
710714
let local_state = current_state.clone();
711715
b.method("OpenUri", ("uri",), (), move |_, _, (uri,): (String,)| {
712716
let id = SpotifyId::from_uri(&uri).map_err(|e| MethodErr::invalid_arg(&e))?;
713-
let CurrentStateInner { shuffle, .. } = *local_state.read()?;
717+
let CurrentStateInner {
718+
shuffle, repeat, ..
719+
} = *local_state.read()?;
714720

715721
let session = session.clone();
716722

717723
let (playing_track_index, context_uri) = Handle::current()
718724
.block_on(async move {
719725
use librespot_metadata::*;
720726
Ok::<_, librespot_core::Error>(match id.item_type {
721-
SpotifyItemType::Album => (0, uri),
722-
SpotifyItemType::Artist => (0, uri),
723-
SpotifyItemType::Playlist => (0, uri),
724727
SpotifyItemType::Track => {
725728
let track = Track::get(&session, &id).await?;
726729
(track.number as u32, track.album.id.to_uri()?)
727730
}
728-
SpotifyItemType::Episode => (0, uri),
729-
SpotifyItemType::Show => (0, uri),
731+
SpotifyItemType::Album
732+
| SpotifyItemType::Artist
733+
| SpotifyItemType::Playlist
734+
| SpotifyItemType::Episode
735+
| SpotifyItemType::Show => (0, uri),
730736
SpotifyItemType::Local | SpotifyItemType::Unknown => {
731737
return Err(librespot_core::Error::unimplemented(
732738
"this type of uri is not supported",
@@ -746,11 +752,11 @@ fn register_player_interface(
746752
LoadRequestOptions {
747753
start_playing: true,
748754
seek_to: 0,
749-
context_options: Some(librespot_connect::LoadContextOptions::Options(
755+
context_options: Some(LoadContextOptions::Options(
750756
librespot_connect::Options {
751757
shuffle,
752-
repeat: false,
753-
repeat_track: false,
758+
repeat: repeat.repeat_context(),
759+
repeat_track: repeat.repeat_track(),
754760
},
755761
)),
756762
playing_track: Some(librespot_connect::PlayingTrack::Index(
@@ -769,18 +775,17 @@ fn register_player_interface(
769775
Ok(playback_state.to_mpris().to_string())
770776
});
771777

772-
// let local_spirc = spirc.clone();
778+
let local_spirc = spirc.clone();
773779
let local_state = current_state.clone();
774780
b.property("Shuffle")
775781
.emits_changed_false()
776-
.get(move |_, _| Ok(local_state.read()?.shuffle));
777-
// TODO: re-enable, once setting shuffle via spirc works
778-
// .set(move |_, _, value| {
779-
// local_spirc
780-
// .shuffle(value)
781-
// .map(|_| None)
782-
// .map_err(|err| dbus::MethodErr::failed(&err))
783-
// });
782+
.get(move |_, _| Ok(local_state.read()?.shuffle))
783+
.set(move |_, _, value| {
784+
local_spirc
785+
.shuffle(value)
786+
.map(|_| None)
787+
.map_err(|err| dbus::MethodErr::failed(&err))
788+
});
784789

785790
b.property("Rate").emits_changed_const().get(|_, _| Ok(1.0));
786791
b.property("MaximumRate")
@@ -811,20 +816,25 @@ fn register_player_interface(
811816
Ok(repeat.to_mpris().to_string())
812817
})
813818
.set(move |_, _, value| {
814-
let new_repeat = match value.as_str() {
815-
"None" => false,
816-
"Playlist" => true,
819+
let repeat = match value.as_str() {
820+
"None" => RepeatState::None,
821+
"Playlist" => RepeatState::All,
822+
"Track" => RepeatState::Track,
817823
mode => {
818824
return Err(dbus::MethodErr::failed(&format!(
819825
"unsupported repeat mode: {mode}"
820826
)));
821827
}
822828
};
829+
823830
local_spirc
824-
.repeat(new_repeat)
831+
.repeat(repeat.repeat_context())
825832
.map_err(|e| MethodErr::failed(&e))?;
826-
// TODO: remove, once librespot sends us updates here
827-
Ok(Some(value))
833+
local_spirc
834+
.repeat_track(repeat.repeat_track())
835+
.map_err(|e| MethodErr::failed(&e))?;
836+
837+
Ok(None)
828838
});
829839

830840
let local_state = current_state.clone();

src/main_loop.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,9 @@ impl MainLoop {
125125
ConnectConfig {
126126
name: self.device_name.clone(),
127127
device_type: self.device_type,
128-
is_group: false,
129128
initial_volume: self.initial_volume,
130129
disable_volume: self.disable_volume,
131-
volume_steps: 64,
130+
..ConnectConfig::default()
132131
},
133132
session.clone(),
134133
creds.clone(),

src/oauth.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use color_eyre::{
44
};
55
use librespot_core::SessionConfig;
66
use librespot_core::{Session, authentication::Credentials};
7+
use librespot_oauth::OAuthClientBuilder;
78
use log::info;
89
use tokio::runtime::Runtime;
910

@@ -55,18 +56,18 @@ pub(crate) fn run_oauth(mut cli_config: CliConfig, oauth_port: u16) -> eyre::Res
5556
..Default::default()
5657
};
5758

58-
let client = librespot_oauth::OAuthClientBuilder::new(
59+
let oauth_client = OAuthClientBuilder::new(
5960
&session_config.client_id,
6061
&format!("http://127.0.0.1:{oauth_port}/login"),
6162
OAUTH_SCOPES.to_vec(),
6263
)
6364
.with_custom_message(r#"<h3 style="color: darkgreen; align: center;">Authentication successful! You can now return to spotifyd.</h3>"#)
6465
.open_in_browser()
6566
.build()
66-
.wrap_err("token retrieval failed")?;
67+
.wrap_err("client creation failed")?;
6768

6869
Runtime::new().unwrap().block_on(async move {
69-
let token = client.get_access_token_async().await?;
70+
let token = oauth_client.get_access_token_async().await?;
7071
let creds = Credentials::with_access_token(token.access_token);
7172

7273
let session = Session::new(session_config, Some(cache));

src/process.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::error::Error;
22
use librespot_metadata::audio::AudioItem;
33
use librespot_playback::player::PlayerEvent;
44
use log::info;
5+
56
use std::{collections::HashMap, process::Stdio};
67
use tokio::{
78
io::{self, AsyncWriteExt},
@@ -179,10 +180,13 @@ pub(crate) fn spawn_program_on_event(
179180
env.insert("PLAYER_EVENT", "shuffle_changed".to_string());
180181
env.insert("SHUFFLE", shuffle.to_string());
181182
}
182-
PlayerEvent::RepeatChanged { context: _, track } => {
183+
PlayerEvent::RepeatChanged { context, track } => {
183184
env.insert("PLAYER_EVENT", "repeat_changed".to_string());
184-
let val = match track {
185-
true => "all",
185+
let val = match context {
186+
true => match track {
187+
true => "track",
188+
false => "all",
189+
},
186190
false => "none",
187191
}
188192
.to_string();
@@ -197,10 +201,15 @@ pub(crate) fn spawn_program_on_event(
197201
env.insert("FILTEREXPLICIT", filter.to_string());
198202
}
199203
PlayerEvent::PositionChanged {
200-
play_request_id: _,
201-
track_id: _,
202-
position_ms: _,
203-
} => todo!(),
204+
play_request_id,
205+
position_ms,
206+
track_id,
207+
} => {
208+
env.insert("PLAYER_EVENT", "position_changed".to_string());
209+
env.insert("TRACK_ID", track_id.to_base62().unwrap());
210+
env.insert("POSITION_MS", position_ms.to_string());
211+
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
212+
}
204213
}
205214
spawn_program(shell, cmd, env)
206215
}

src/setup.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ pub(crate) fn initial_state(
5757
}
5858
_ => {
5959
info!("Using software volume controller.");
60-
let soft_mixer = mixer::softmixer::SoftMixer::open(MixerConfig::default())
61-
.expect("softmixer should initialize");
62-
Arc::new(soft_mixer)
60+
let mixer = mixer::softmixer::SoftMixer::open(MixerConfig::default())
61+
.expect("SoftMixer::open never returns an Error");
62+
Arc::new(mixer)
6363
}
6464
}
6565
};

0 commit comments

Comments
 (0)