Quellcode durchsuchen

Add option to specify bitrate.

Paul Lietar vor 9 Jahren
Ursprung
Commit
f8956166ea
4 geänderte Dateien mit 38 neuen und 13 gelöschten Zeilen
  1. 19 8
      src/main.rs
  2. 4 2
      src/metadata.rs
  3. 8 3
      src/player.rs
  4. 7 0
      src/session.rs

+ 19 - 8
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);

+ 4 - 2
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<FileId>,
+    pub files: Vec<(FileId, FileFormat)>,
     pub alternatives: Vec<SpotifyId>,
     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()

+ 8 - 3
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(

+ 7 - 0
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<u8>,
     pub user_agent: String,
     pub device_name: String,
     pub cache_location: PathBuf,
+    pub bitrate: Bitrate,
 }
 
 pub struct SessionData {