Update to use latest librespot from GithHub repo

This commit is contained in:
grufkork 2024-09-08 13:24:17 +02:00
parent f0a8720853
commit ec66b5ad91
6 changed files with 1370 additions and 708 deletions

1997
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,7 @@ reqwest = "0"
colored = "2"
lame = "0"
aspotify = "0"
librespot = { git = "ssh://git@github.com/oSumAtrIX/free-librespot.git" }
librespot = { git = "https://github.com/librespot-org/librespot" }
async-std = { version = "1", features = ["attributes", "tokio1"] }
serde_json = "1"
async-stream = "0"

View file

@ -1,3 +1,4 @@
use aspotify::Tracks;
use async_std::channel::{bounded, Receiver, Sender};
use async_stream::try_stream;
use chrono::NaiveDate;
@ -7,7 +8,8 @@ use librespot::audio::{AudioDecrypt, AudioFile};
use librespot::core::audio_key::AudioKey;
use librespot::core::session::Session;
use librespot::core::spotify_id::SpotifyId;
use librespot::metadata::{FileFormat, Metadata, Track};
use librespot::metadata::{Metadata, Track};
use librespot::protocol::metadata::audio_file::Format as FileFormat;
use sanitize_filename::sanitize;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
@ -483,16 +485,20 @@ impl DownloaderInternal {
Ok(())
}
async fn find_alternative(session: &Session, track: Track) -> Result<Track, SpotifyError> {
for alt in track.alternatives {
let t = Track::get(session, alt).await?;
if t.available {
return Ok(t);
}
}
async fn find_alternative(session: &Session, track: Track) -> Result<Track, SpotifyError> {
let librespot::metadata::track::Tracks(ids) = track.alternatives;
for alt in ids {
let t = Track::get(session, &alt).await.unwrap(); // TODO ?
let librespot::metadata::availability::Availabilities(avalabilities) = t.availability;
for a in avalabilities {
// TODO: figure out if available
}
}
Err(SpotifyError::Unavailable)
}
Err(SpotifyError::Unavailable)
}
/// Download track by id
async fn download_track(
@ -504,12 +510,12 @@ impl DownloaderInternal {
job_id: i64,
) -> Result<(PathBuf, AudioFormat), SpotifyError> {
let id = SpotifyId::from_base62(id)?;
let mut track = Track::get(session, id).await?;
let mut track = Track::get(session, &id).await?;
// Fallback if unavailable
if !track.available {
/*if !track.available {
track = DownloaderInternal::find_alternative(session, track).await?;
}
}*/ //TODO
// Quality fallback
let mut quality = config.quality;
@ -554,8 +560,8 @@ impl DownloaderInternal {
let path_clone = path.clone();
let key = session.audio_key().request(track.id, *file_id).await?;
let encrypted = AudioFile::open(session, *file_id, 1024 * 1024, true).await?;
let size = encrypted.get_stream_loader_controller().len();
let encrypted = AudioFile::open(session, *file_id, 1024 * 1024).await?;
let size = encrypted.get_stream_loader_controller()?.len();
// Download
let s = match config.convert_to_mp3 {
true => {
@ -604,7 +610,7 @@ impl DownloaderInternal {
) -> impl Stream<Item = Result<usize, SpotifyError>> {
try_stream! {
let mut file = File::create(path).await?;
let mut decrypted = AudioDecrypt::new(key, encrypted);
let mut decrypted = AudioDecrypt::new(Some(key), encrypted);
// Skip (i guess encrypted shit)
let mut skip: [u8; 0xa7] = [0; 0xa7];
let mut decrypted = tokio::task::spawn_blocking(move || {
@ -642,7 +648,7 @@ impl DownloaderInternal {
) -> impl Stream<Item = Result<usize, SpotifyError>> {
try_stream! {
let mut file = File::create(path).await?;
let mut decrypted = AudioDecrypt::new(key, encrypted);
let mut decrypted = AudioDecrypt::new(Some(key), encrypted);
// Skip (i guess encrypted shit)
let mut skip: [u8; 0xa7] = [0; 0xa7];
let decrypted = tokio::task::spawn_blocking(move || {
@ -711,12 +717,9 @@ impl From<FileFormat> for AudioFormat {
FileFormat::MP3_160 => Self::Mp3,
FileFormat::MP3_96 => Self::Mp3,
FileFormat::MP3_160_ENC => Self::Mp3,
FileFormat::MP4_128_DUAL => Self::Mp4,
FileFormat::OTHER3 => Self::Unknown,
FileFormat::AAC_160 => Self::Aac,
FileFormat::AAC_320 => Self::Aac,
FileFormat::MP4_128 => Self::Mp4,
FileFormat::OTHER5 => Self::Unknown,
FileFormat::AAC_24 => Self::Aac,
FileFormat::AAC_48 => Self::Aac,
FileFormat::FLAC_FLAC => Self::Unknown
}
}
}
@ -727,13 +730,13 @@ impl Quality {
match self {
Self::Q320 => vec![
FileFormat::OGG_VORBIS_320,
FileFormat::AAC_320,
FileFormat::AAC_48, // TODO
FileFormat::MP3_320,
],
Self::Q256 => vec![FileFormat::MP3_256],
Self::Q160 => vec![
FileFormat::OGG_VORBIS_160,
FileFormat::AAC_160,
FileFormat::AAC_24, // TODO
FileFormat::MP3_160,
],
Self::Q96 => vec![FileFormat::OGG_VORBIS_96, FileFormat::MP3_96],

View file

@ -19,6 +19,8 @@ pub enum SpotifyError {
ID3Error(String, String),
Reqwest(String),
InvalidFormat,
NotConnected,
UnknownPacket(u8),
AlreadyDownloaded,
}
@ -43,6 +45,8 @@ impl fmt::Display for SpotifyError {
SpotifyError::ID3Error(k, e) => write!(f, "ID3 Error: {} {}", k, e),
SpotifyError::Reqwest(e) => write!(f, "Reqwest Error: {}", e),
SpotifyError::InvalidFormat => write!(f, "Invalid Format!"),
SpotifyError::NotConnected => write!(f, "Not Connected"),
SpotifyError::UnknownPacket(e) => write!(f, "Unknown Packet: {}", e),
SpotifyError::AlreadyDownloaded => write!(f, "Already Downloaded"),
}
}
@ -70,7 +74,9 @@ impl From<librespot::core::session::SessionError> for SpotifyError {
librespot::core::session::SessionError::IoError(e) => e.into(),
librespot::core::session::SessionError::AuthenticationError(_) => {
SpotifyError::AuthenticationError
}
},
librespot::core::session::SessionError::NotConnected => SpotifyError::NotConnected,
librespot::core::session::SessionError::Packet(e) => SpotifyError::UnknownPacket(e)
}
}
}

View file

@ -14,6 +14,7 @@ use async_std::task;
use colored::Colorize;
use downloader::{DownloadState, Downloader};
use error::SpotifyError;
use librespot::core::spotify_id::SpotifyIdResult;
use settings::Settings;
use spotify::Spotify;
use std::time::{Duration, Instant};
@ -26,6 +27,12 @@ async fn main() {
start().await;
}
impl From<librespot::core::error::Error> for SpotifyError {
fn from(e: librespot::core::error::Error) -> Self {
SpotifyError::Error(e.to_string())
}
}
#[cfg(windows)]
#[tokio::main]
async fn main() {

View file

@ -12,6 +12,7 @@ use url::Url;
use crate::error::SpotifyError;
pub struct Spotify {
// librespotify sessopm
pub session: Session,
@ -34,13 +35,9 @@ impl Spotify {
Some(creds) => creds,
None => Credentials::with_password(username, password),
};
let (session, _) = Session::connect(
SessionConfig::default(),
credentials,
Some(cache),
true,
)
.await?;
let session = Session::new(SessionConfig::default(), Some(cache));
session.connect(credentials, true).await?;
//aspotify
let credentials = ClientCredentials {