fix(deps): bump librespot to 0.7.0 (#1687)

* fix(deps): bump librespot to 0.7.0

* Bumps librespot to 0.7.0
* Changes worker authentication to use login5
* Solves minor API changes
* Adds alsa-lib to nix shell

* fix(ci): add libasound2 build dependency

* docs: updates changelog

* fix: Don't build with Rodio backend by default

Allow users to explicitly specify Librespot audio backend. This way we can also
drop the ALSA dependencies again.

---------

Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
This commit is contained in:
Tomas Guinzburg
2025-08-25 15:47:39 +02:00
committed by GitHub
parent 195b9fa260
commit e5e4c97431
7 changed files with 338 additions and 764 deletions

View File

@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.3.1]
### Fixed
- Bug preventing any type of playback due to spotify API changes.
- Bug preventing retrieval of new song metadata from spotify.
## [1.3.0]
### Added

1041
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -52,10 +52,10 @@ fern = "0.7"
futures = "0.3"
ioctl-rs = {version = "0.2", optional = true}
libc = "0.2.175"
librespot-core = "0.6.0"
librespot-oauth = "0.6.0"
librespot-playback = "0.6.0"
librespot-protocol = "0.6.0"
librespot-core = "0.7.0"
librespot-oauth = "0.7.0"
librespot-playback = {version = "0.7.0", default-features = false, features = ["native-tls"]}
librespot-protocol = "0.7.0"
log = "0.4.27"
pancurses = {version = "0.17.0", optional = true}
parse_duration = "2.1.1"

View File

@@ -1,6 +1,4 @@
{
pkgs ? import <nixpkgs> { },
}:
{pkgs ? import <nixpkgs> {}}:
pkgs.mkShell {
nativeBuildInputs = with pkgs.buildPackages; [
rustup

View File

@@ -2,7 +2,7 @@ use std::net::TcpListener;
use librespot_core::authentication::Credentials as RespotCredentials;
use librespot_core::cache::Cache;
use librespot_oauth::get_access_token;
use librespot_oauth::OAuthClientBuilder;
use log::info;
use crate::config::{self, Config};
@@ -86,13 +86,18 @@ fn credentials_prompt(error_message: Option<String>) -> Result<RespotCredentials
pub fn create_credentials() -> Result<RespotCredentials, String> {
println!("To login you need to perform OAuth2 authorization using your web browser\n");
get_access_token(
let client_builder = OAuthClientBuilder::new(
SPOTIFY_CLIENT_ID,
&get_client_redirect_uri(),
OAUTH_SCOPES.to_vec(),
)
.map(|token| RespotCredentials::with_access_token(token.access_token))
.map_err(|e| e.to_string())
);
let oauth_client = client_builder.build().map_err(|e| e.to_string())?;
oauth_client
.get_access_token()
.map(|token| RespotCredentials::with_access_token(token.access_token))
.map_err(|e| e.to_string())
}
#[derive(Serialize, Deserialize, Debug)]

View File

@@ -248,9 +248,10 @@ impl Spotify {
.expect("Could not create session");
user_tx.map(|tx| tx.send(session.username()));
let create_mixer = librespot_playback::mixer::find(Some(SoftMixer::NAME))
.expect("could not create softvol mixer");
let mixer = create_mixer(MixerConfig::default());
let mixer_factory_opt = librespot_playback::mixer::find(Some(SoftMixer::NAME));
let factory = mixer_factory_opt.expect("could not find softvol mixer factory");
let mixer = factory(MixerConfig::default()).expect("could not create softvol mixer");
mixer.set_volume(volume);
let audio_format: librespot_playback::config::AudioFormat = Default::default();

View File

@@ -3,7 +3,6 @@ use crate::model::playable::Playable;
use crate::queue::QueueEvent;
use crate::spotify::PlayerEvent;
use futures::Future;
use futures::FutureExt;
use librespot_core::session::Session;
use librespot_core::spotify_id::SpotifyId;
use librespot_core::token::Token;
@@ -71,12 +70,19 @@ impl Worker {
}
async fn get_token(session: Session, sender: Sender<Option<Token>>) {
let scopes = "user-read-private,playlist-read-private,playlist-read-collaborative,playlist-modify-public,playlist-modify-private,user-follow-modify,user-follow-read,user-library-read,user-library-modify,user-top-read,user-read-recently-played";
session
.token_provider()
.get_token(scopes)
.map(|response| sender.send(response.ok()).expect("token channel is closed"))
.await;
match session.login5().auth_token().await {
Ok(token) => {
if let Err(e) = sender.send(Some(token)) {
error!("could not send token: {e}")
}
}
Err(e) => {
error!("login5 token acquisition failed {e}");
if let Err(e) = sender.send(None) {
error!("could not send token failure {e}");
}
}
}
}
pub async fn run_loop(&mut self) {