From f8956166ea37a010c3529099cc256959bcf4cf28 Mon Sep 17 00:00:00 2001 From: Paul Lietar Date: Sat, 2 Jan 2016 03:30:24 +0100 Subject: [PATCH] Add option to specify bitrate. --- src/main.rs | 27 +++++++++++++++++++-------- src/metadata.rs | 6 ++++-- src/player.rs | 11 ++++++++--- src/session.rs | 7 +++++++ 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 89bf7b31..1422c785 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use std::thread; use librespot::discovery::DiscoveryManager; use librespot::player::Player; -use librespot::session::{Config, Session}; +use librespot::session::{Bitrate, Config, Session}; use librespot::spirc::SpircManager; use librespot::util::version::version_string; @@ -28,11 +28,13 @@ fn main() { let program = args[0].clone(); let mut opts = Options::new(); - opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY"); - opts.optopt("u", "username", "Username to sign in with (optional)", "USERNAME"); - opts.optopt("p", "password", "Password (optional)", "PASSWORD"); - opts.reqopt("c", "cache", "Path to a directory where files will be cached.", "CACHE"); - opts.reqopt("n", "name", "Device name", "NAME"); + opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY") + .optopt("u", "username", "Username to sign in with (optional)", "USERNAME") + .optopt("p", "password", "Password (optional)", "PASSWORD") + .reqopt("c", "cache", "Path to a directory where files will be cached.", "CACHE") + .reqopt("n", "name", "Device name", "NAME") + .optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE"); + let matches = match opts.parse(&args[1..]) { Ok(m) => { m }, Err(f) => { @@ -67,14 +69,23 @@ fn main() { (u, password) }); - std::env::remove_var(PASSWORD_ENV_NAME); + let bitrate = match matches.opt_str("b").as_ref().map(String::as_ref) { + None => Bitrate::Bitrate160, // default value + + Some("96") => Bitrate::Bitrate96, + Some("160") => Bitrate::Bitrate160, + Some("320") => Bitrate::Bitrate320, + Some(b) => panic!("Invalid bitrate {}", b), + }; + let config = Config { application_key: appkey, user_agent: version_string(), device_name: name, - cache_location: PathBuf::from(cache_location) + cache_location: PathBuf::from(cache_location), + bitrate: bitrate }; let session = Session::new(config); diff --git a/src/metadata.rs b/src/metadata.rs index 37e70c54..7104b4f1 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -6,6 +6,8 @@ use mercury::{MercuryRequest, MercuryMethod}; use util::{SpotifyId, FileId, StrChunksExt}; use session::Session; +pub use librespot_protocol::metadata::AudioFile_Format as FileFormat; + fn countrylist_contains(list: &str, country: &str) -> bool { list.chunks(2).any(|cc| cc == country) } @@ -31,7 +33,7 @@ pub struct Track { pub id: SpotifyId, pub name: String, pub album: SpotifyId, - pub files: Vec, + pub files: Vec<(FileId, FileFormat)>, pub alternatives: Vec, pub available: bool, } @@ -71,7 +73,7 @@ impl MetadataTrait for Track { .map(|file| { let mut dst = [0u8; 20]; dst.clone_from_slice(&file.get_file_id()); - FileId(dst) + (FileId(dst), file.get_format()) }) .collect(), alternatives: msg.get_alternative().iter() diff --git a/src/player.rs b/src/player.rs index b5fcbcaf..a3898a50 100644 --- a/src/player.rs +++ b/src/player.rs @@ -4,8 +4,8 @@ use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard}; use std::thread; use vorbis; -use metadata::{Track, TrackRef}; -use session::Session; +use metadata::{FileFormat, Track, TrackRef}; +use session::{Bitrate, Session}; use audio_decrypt::AudioDecrypt; use util::{self, SpotifyId, Subfile}; use spirc::{SpircState, SpircDelegate, PlayStatus}; @@ -120,7 +120,12 @@ impl PlayerInternal { track = eventual::sequence(alternatives.into_iter()).iter().find(|alt| alt.available).unwrap(); } - let file_id = track.files[0]; + let format = match self.session.0.config.bitrate { + Bitrate::Bitrate96 => FileFormat::OGG_VORBIS_96, + Bitrate::Bitrate160 => FileFormat::OGG_VORBIS_160, + Bitrate::Bitrate320 => FileFormat::OGG_VORBIS_320, + }; + let (file_id, _) = track.files.into_iter().find(|&(_, f)| f == format).unwrap(); let key = self.session.audio_key(track.id, file_id).await().unwrap(); decoder = Some( diff --git a/src/session.rs b/src/session.rs index d20ccb0b..4eed3078 100644 --- a/src/session.rs +++ b/src/session.rs @@ -22,11 +22,18 @@ use util::{SpotifyId, FileId, mkdir_existing}; use util; +pub enum Bitrate { + Bitrate96, + Bitrate160, + Bitrate320 +} + pub struct Config { pub application_key: Vec, pub user_agent: String, pub device_name: String, pub cache_location: PathBuf, + pub bitrate: Bitrate, } pub struct SessionData {