Update to use latest librespot from GithHub repo
This commit is contained in:
parent
f0a8720853
commit
ec66b5ad91
6 changed files with 1370 additions and 708 deletions
1997
Cargo.lock
generated
1997
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue