Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Librespot upgrade to 0.4 #1182

Merged
merged 1 commit into from
Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
320 changes: 187 additions & 133 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ tokio = {version = "1.6.1", features = ["signal", "rt-multi-thread", "process",
tokio-stream = "0.1.7"
url = "2.2.2"
xdg = "2.2"
librespot-audio = { version = "0.2.0", default-features=false, features = ["with-tremor"] }
librespot-playback = { version = "0.2.0", default-features=false }
librespot-core = { version = "0.2.0"}
librespot-connect = { version = "0.2.0"}
librespot-audio = { version = "0.4", default-features = false }
librespot-playback = { version = "0.4", default-features = false }
librespot-core = { version = "0.4" }
librespot-discovery = { version = "0.4" }
librespot-connect = { version = "0.4" }
toml = "0.7"
color-eyre = "0.6"

Expand Down
13 changes: 3 additions & 10 deletions src/alsa_mixer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use librespot_playback::mixer::{AudioFilter, Mixer, MixerConfig};
use librespot_playback::mixer::{Mixer, MixerConfig};
use log::error;
use std::error::Error;

#[derive(Clone)]
pub struct AlsaMixer {
pub device: String,
pub mixer: String,
Expand Down Expand Up @@ -35,18 +36,14 @@ impl AlsaMixer {
}

impl Mixer for AlsaMixer {
fn open(_: Option<MixerConfig>) -> AlsaMixer {
fn open(_: MixerConfig) -> AlsaMixer {
AlsaMixer {
device: "default".to_string(),
mixer: "Master".to_string(),
linear_scaling: false,
}
}

fn start(&self) {}

fn stop(&self) {}

fn volume(&self) -> u16 {
let selem_id = alsa::mixer::SelemId::new(&self.mixer, 0);
match alsa::mixer::Mixer::new(&self.device, false)
Expand Down Expand Up @@ -79,8 +76,4 @@ impl Mixer for AlsaMixer {
Err(e) => error!("Couldn't set volume: {:?}", e),
}
}

fn get_audio_filter(&self) -> Option<Box<dyn AudioFilter + Send>> {
None
}
}
18 changes: 11 additions & 7 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ pub struct SharedConfigValues {

/// A custom pregain applied before sending the audio to the output device
#[structopt(long, value_name = "number")]
normalisation_pregain: Option<f32>,
normalisation_pregain: Option<f64>,

/// The port used for the Spotify Connect discovery
#[structopt(long, value_name = "number")]
Expand Down Expand Up @@ -647,7 +647,14 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
let cache = config
.shared_config
.cache_path
.map(|path| Cache::new(Some(&path), audio_cache.then_some(&path), size_limit))
.map(|path| {
Cache::new(
Some(&path),
Some(&path),
audio_cache.then_some(&path),
size_limit,
)
})
.transpose()
.unwrap_or_else(|e| {
warn!("Cache couldn't be initialized: {e}");
Expand Down Expand Up @@ -692,7 +699,7 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {

let device_id = device_id(&device_name);

let normalisation_pregain = config.shared_config.normalisation_pregain.unwrap_or(0.0f32);
let normalisation_pregain = config.shared_config.normalisation_pregain.unwrap_or(0.0);

let dbus_type = config.shared_config.dbus_type.unwrap_or(DBusType::Session);
let autoplay = config.shared_config.autoplay;
Expand Down Expand Up @@ -759,10 +766,7 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
let pc = PlayerConfig {
bitrate,
normalisation: config.shared_config.volume_normalisation,
normalisation_pregain,
// Sensible default; the "default" supplied by PlayerConfig::default() sets this to -1.0,
// which turns the output to garbage.
normalisation_threshold: 1.0,
normalisation_pregain_db: normalisation_pregain,
gapless: true,
..Default::default()
};
Expand Down
4 changes: 2 additions & 2 deletions src/dbus_mpris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,12 @@ async fn create_dbus_server(
if let Some(track_id) = track_id {
let item = match track_id.audio_type {
SpotifyAudioType::Track => {
let track_id = TrackId::from_id(track_id.to_base62()).unwrap();
let track_id = TrackId::from_id(track_id.to_base62().unwrap()).unwrap();
let track = spotify_api_client.track(track_id).map(PlayableItem::Track);
Some(track)
}
SpotifyAudioType::Podcast => {
let id = EpisodeId::from_id(track_id.to_base62()).unwrap();
let id = EpisodeId::from_id(track_id.to_base62().unwrap()).unwrap();
let episode = spotify_api_client
.get_an_episode(id, None)
.map(PlayableItem::Episode);
Expand Down
30 changes: 16 additions & 14 deletions src/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ use futures::{
stream::Peekable,
Future, FutureExt, StreamExt,
};
use librespot_connect::{discovery::DiscoveryStream, spirc::Spirc};
use librespot_connect::spirc::Spirc;
use librespot_core::{
authentication::Credentials,
cache::Cache,
config::{ConnectConfig, DeviceType, SessionConfig, VolumeCtrl},
config::{ConnectConfig, DeviceType, SessionConfig},
session::{Session, SessionError},
};
use librespot_discovery::Discovery;
use librespot_playback::{
audio_backend::Sink,
config::{AudioFormat, PlayerConfig},
Expand All @@ -38,28 +39,28 @@ pub struct SpotifydState {
}

pub(crate) enum CredentialsProvider {
DiscoveryStream(Peekable<DiscoveryStream>),
Discovery(Peekable<Discovery>),
SpotifyCredentials(Credentials),
}

impl From<DiscoveryStream> for CredentialsProvider {
fn from(stream: DiscoveryStream) -> Self {
CredentialsProvider::DiscoveryStream(stream.peekable())
impl From<Discovery> for CredentialsProvider {
fn from(stream: Discovery) -> Self {
CredentialsProvider::Discovery(stream.peekable())
}
}

impl CredentialsProvider {
async fn get_credentials(&mut self) -> Credentials {
match self {
CredentialsProvider::DiscoveryStream(stream) => stream.next().await.unwrap(),
CredentialsProvider::Discovery(stream) => stream.next().await.unwrap(),
CredentialsProvider::SpotifyCredentials(creds) => creds.clone(),
}
}

// wait for an incoming connection if the underlying provider is a discovery stream
async fn incoming_connection(&mut self) {
match self {
CredentialsProvider::DiscoveryStream(stream) => {
CredentialsProvider::Discovery(stream) => {
let peeked = Pin::new(stream).peek().await;
if peeked.is_none() {
future::pending().await
Expand All @@ -76,7 +77,7 @@ pub(crate) struct MainLoop {
pub(crate) player_config: PlayerConfig,
pub(crate) session_config: SessionConfig,
pub(crate) autoplay: bool,
pub(crate) volume_ctrl: VolumeCtrl,
pub(crate) has_volume_ctrl: bool,
pub(crate) initial_volume: Option<u16>,
pub(crate) shell: String,
pub(crate) device_type: DeviceType,
Expand All @@ -94,7 +95,9 @@ impl MainLoop {
let session_config = self.session_config.clone();
let cache = self.spotifyd_state.cache.clone();

Session::connect(session_config, creds, cache).await
Session::connect(session_config, creds, cache, false)
.await
.map(|(session, _creds)| session)
Icelk marked this conversation as resolved.
Show resolved Hide resolved
}

pub(crate) async fn run(&mut self) {
Expand All @@ -119,13 +122,12 @@ impl MainLoop {
);

let mixer = (self.audio_setup.mixer)();
let audio_filter = mixer.get_audio_filter();
let backend = self.audio_setup.backend;
let audio_device = self.audio_setup.audio_device.clone();
let (player, mut event_channel) = Player::new(
self.player_config.clone(),
session.clone(),
audio_filter,
mixer.get_soft_volume(),
// TODO: dunno how to work with AudioFormat yet, maybe dig further if this
// doesn't work for all configurations
move || (backend)(audio_device, AudioFormat::default()),
Expand All @@ -136,8 +138,8 @@ impl MainLoop {
autoplay: self.autoplay,
name: self.spotifyd_state.device_name.clone(),
device_type: self.device_type,
volume: self.initial_volume.unwrap_or_else(|| mixer.volume()),
volume_ctrl: self.volume_ctrl.clone(),
initial_volume: self.initial_volume,
has_volume_ctrl: self.has_volume_ctrl,
},
session.clone(),
player,
Expand Down
14 changes: 3 additions & 11 deletions src/no_mixer.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
use librespot_playback::mixer::{AudioFilter, Mixer, MixerConfig};
use librespot_playback::mixer::{Mixer, MixerConfig};

pub struct NoMixer {}
pub struct NoMixer;

impl Mixer for NoMixer {
fn open(_: Option<MixerConfig>) -> NoMixer {
fn open(_: MixerConfig) -> NoMixer {
NoMixer {}
}

fn start(&self) {}

fn stop(&self) {}

fn volume(&self) -> u16 {
u16::MAX
}

fn set_volume(&self, _volume: u16) {}

fn get_audio_filter(&self) -> Option<Box<dyn AudioFilter + Send>> {
None
}
}
22 changes: 11 additions & 11 deletions src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@ pub(crate) fn spawn_program_on_event(
old_track_id,
new_track_id,
} => {
env.insert("OLD_TRACK_ID", old_track_id.to_base62());
env.insert("OLD_TRACK_ID", old_track_id.to_base62().unwrap());
env.insert("PLAYER_EVENT", "change".to_string());
env.insert("TRACK_ID", new_track_id.to_base62());
env.insert("TRACK_ID", new_track_id.to_base62().unwrap());
}
PlayerEvent::Started {
track_id,
play_request_id,
position_ms,
} => {
env.insert("PLAYER_EVENT", "start".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
env.insert("POSITION_MS", position_ms.to_string());
}
Expand All @@ -77,7 +77,7 @@ pub(crate) fn spawn_program_on_event(
play_request_id,
} => {
env.insert("PLAYER_EVENT", "stop".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
}
PlayerEvent::Loading {
Expand All @@ -86,7 +86,7 @@ pub(crate) fn spawn_program_on_event(
position_ms,
} => {
env.insert("PLAYER_EVENT", "load".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
env.insert("POSITION_MS", position_ms.to_string());
}
Expand All @@ -97,7 +97,7 @@ pub(crate) fn spawn_program_on_event(
duration_ms,
} => {
env.insert("PLAYER_EVENT", "play".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
env.insert("POSITION_MS", position_ms.to_string());
env.insert("DURATION_MS", duration_ms.to_string());
Expand All @@ -109,7 +109,7 @@ pub(crate) fn spawn_program_on_event(
duration_ms,
} => {
env.insert("PLAYER_EVENT", "pause".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
env.insert("POSITION_MS", position_ms.to_string());
env.insert("DURATION_MS", duration_ms.to_string());
Expand All @@ -119,15 +119,15 @@ pub(crate) fn spawn_program_on_event(
play_request_id,
} => {
env.insert("PLAYER_EVENT", "preload".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
}
PlayerEvent::EndOfTrack {
track_id,
play_request_id,
} => {
env.insert("PLAYER_EVENT", "endoftrack".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
}
PlayerEvent::VolumeSet { volume } => {
Expand All @@ -139,12 +139,12 @@ pub(crate) fn spawn_program_on_event(
track_id,
} => {
env.insert("PLAYER_EVENT", "unavailable".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
env.insert("PLAY_REQUEST_ID", play_request_id.to_string());
}
PlayerEvent::Preloading { track_id } => {
env.insert("PLAYER_EVENT", "preloading".to_string());
env.insert("TRACK_ID", track_id.to_base62());
env.insert("TRACK_ID", track_id.to_base62().unwrap());
}
}
spawn_program(shell, cmd, env)
Expand Down
Loading