Add option to specify bitrate.

This commit is contained in:
Paul Lietar 2016-01-02 03:30:24 +01:00
parent 47c6d60b12
commit f8956166ea
4 changed files with 38 additions and 13 deletions

View file

@ -12,7 +12,7 @@ use std::thread;
use librespot::discovery::DiscoveryManager; use librespot::discovery::DiscoveryManager;
use librespot::player::Player; use librespot::player::Player;
use librespot::session::{Config, Session}; use librespot::session::{Bitrate, Config, Session};
use librespot::spirc::SpircManager; use librespot::spirc::SpircManager;
use librespot::util::version::version_string; use librespot::util::version::version_string;
@ -28,11 +28,13 @@ fn main() {
let program = args[0].clone(); let program = args[0].clone();
let mut opts = Options::new(); let mut opts = Options::new();
opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY"); opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY")
opts.optopt("u", "username", "Username to sign in with (optional)", "USERNAME"); .optopt("u", "username", "Username to sign in with (optional)", "USERNAME")
opts.optopt("p", "password", "Password (optional)", "PASSWORD"); .optopt("p", "password", "Password (optional)", "PASSWORD")
opts.reqopt("c", "cache", "Path to a directory where files will be cached.", "CACHE"); .reqopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
opts.reqopt("n", "name", "Device name", "NAME"); .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..]) { let matches = match opts.parse(&args[1..]) {
Ok(m) => { m }, Ok(m) => { m },
Err(f) => { Err(f) => {
@ -67,14 +69,23 @@ fn main() {
(u, password) (u, password)
}); });
std::env::remove_var(PASSWORD_ENV_NAME); 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 { let config = Config {
application_key: appkey, application_key: appkey,
user_agent: version_string(), user_agent: version_string(),
device_name: name, device_name: name,
cache_location: PathBuf::from(cache_location) cache_location: PathBuf::from(cache_location),
bitrate: bitrate
}; };
let session = Session::new(config); let session = Session::new(config);

View file

@ -6,6 +6,8 @@ use mercury::{MercuryRequest, MercuryMethod};
use util::{SpotifyId, FileId, StrChunksExt}; use util::{SpotifyId, FileId, StrChunksExt};
use session::Session; use session::Session;
pub use librespot_protocol::metadata::AudioFile_Format as FileFormat;
fn countrylist_contains(list: &str, country: &str) -> bool { fn countrylist_contains(list: &str, country: &str) -> bool {
list.chunks(2).any(|cc| cc == country) list.chunks(2).any(|cc| cc == country)
} }
@ -31,7 +33,7 @@ pub struct Track {
pub id: SpotifyId, pub id: SpotifyId,
pub name: String, pub name: String,
pub album: SpotifyId, pub album: SpotifyId,
pub files: Vec<FileId>, pub files: Vec<(FileId, FileFormat)>,
pub alternatives: Vec<SpotifyId>, pub alternatives: Vec<SpotifyId>,
pub available: bool, pub available: bool,
} }
@ -71,7 +73,7 @@ impl MetadataTrait for Track {
.map(|file| { .map(|file| {
let mut dst = [0u8; 20]; let mut dst = [0u8; 20];
dst.clone_from_slice(&file.get_file_id()); dst.clone_from_slice(&file.get_file_id());
FileId(dst) (FileId(dst), file.get_format())
}) })
.collect(), .collect(),
alternatives: msg.get_alternative().iter() alternatives: msg.get_alternative().iter()

View file

@ -4,8 +4,8 @@ use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard};
use std::thread; use std::thread;
use vorbis; use vorbis;
use metadata::{Track, TrackRef}; use metadata::{FileFormat, Track, TrackRef};
use session::Session; use session::{Bitrate, Session};
use audio_decrypt::AudioDecrypt; use audio_decrypt::AudioDecrypt;
use util::{self, SpotifyId, Subfile}; use util::{self, SpotifyId, Subfile};
use spirc::{SpircState, SpircDelegate, PlayStatus}; use spirc::{SpircState, SpircDelegate, PlayStatus};
@ -120,7 +120,12 @@ impl PlayerInternal {
track = eventual::sequence(alternatives.into_iter()).iter().find(|alt| alt.available).unwrap(); 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(); let key = self.session.audio_key(track.id, file_id).await().unwrap();
decoder = Some( decoder = Some(

View file

@ -22,11 +22,18 @@ use util::{SpotifyId, FileId, mkdir_existing};
use util; use util;
pub enum Bitrate {
Bitrate96,
Bitrate160,
Bitrate320
}
pub struct Config { pub struct Config {
pub application_key: Vec<u8>, pub application_key: Vec<u8>,
pub user_agent: String, pub user_agent: String,
pub device_name: String, pub device_name: String,
pub cache_location: PathBuf, pub cache_location: PathBuf,
pub bitrate: Bitrate,
} }
pub struct SessionData { pub struct SessionData {