mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
parent
d0a84d7915
commit
7ba3d766c0
5 changed files with 42 additions and 22 deletions
|
@ -14,6 +14,7 @@
|
||||||
extern crate bit_set;
|
extern crate bit_set;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate crypto;
|
extern crate crypto;
|
||||||
|
extern crate env_logger;
|
||||||
extern crate eventual;
|
extern crate eventual;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -1,13 +1,10 @@
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate librespot;
|
extern crate librespot;
|
||||||
extern crate env_logger;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate log;
|
|
||||||
extern crate ctrlc;
|
extern crate ctrlc;
|
||||||
|
|
||||||
|
use std::io::{stderr, Write};
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::env;
|
|
||||||
|
|
||||||
use librespot::spirc::SpircManager;
|
use librespot::spirc::SpircManager;
|
||||||
use librespot::main_helper;
|
use librespot::main_helper;
|
||||||
|
@ -18,27 +15,23 @@ fn usage(program: &str, opts: &getopts::Options) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if env::var("RUST_LOG").is_err() {
|
|
||||||
env::set_var("RUST_LOG", "mdns=info,librespot=trace")
|
|
||||||
}
|
|
||||||
env_logger::init().unwrap();
|
|
||||||
|
|
||||||
let mut opts = getopts::Options::new();
|
let mut opts = getopts::Options::new();
|
||||||
main_helper::add_session_arguments(&mut opts);
|
main_helper::add_session_arguments(&mut opts);
|
||||||
main_helper::add_authentication_arguments(&mut opts);
|
main_helper::add_authentication_arguments(&mut opts);
|
||||||
main_helper::add_player_arguments(&mut opts);
|
main_helper::add_player_arguments(&mut opts);
|
||||||
main_helper::add_program_arguments(&mut opts);
|
|
||||||
|
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
|
|
||||||
let matches = match opts.parse(&args[1..]) {
|
let matches = match opts.parse(&args[1..]) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => {
|
Err(f) => {
|
||||||
error!("Error: {}\n{}", f.to_string(), usage(&args[0], &opts));
|
writeln!(stderr(), "error: {}\n{}", f.to_string(), usage(&args[0], &opts)).unwrap();
|
||||||
exit(1)
|
exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
main_helper::setup_logging(&matches);
|
||||||
|
|
||||||
let session = main_helper::create_session(&matches);
|
let session = main_helper::create_session(&matches);
|
||||||
let credentials = main_helper::get_credentials(&session, &matches);
|
let credentials = main_helper::get_credentials(&session, &matches);
|
||||||
session.login(credentials).unwrap();
|
session.login(credentials).unwrap();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
use env_logger::LogBuilder;
|
||||||
use getopts;
|
use getopts;
|
||||||
use rpassword;
|
use rpassword;
|
||||||
|
use std::env;
|
||||||
use std::io::{stderr, Write};
|
use std::io::{stderr, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
@ -37,7 +39,10 @@ pub fn find_backend(name: Option<&str>) -> &'static (Fn(Option<&str>) -> Box<Sin
|
||||||
pub fn add_session_arguments(opts: &mut getopts::Options) {
|
pub fn add_session_arguments(opts: &mut getopts::Options) {
|
||||||
opts.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
|
opts.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
|
||||||
.reqopt("n", "name", "Device name", "NAME")
|
.reqopt("n", "name", "Device name", "NAME")
|
||||||
.optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE");
|
.optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE")
|
||||||
|
.optopt("", "onstart", "Run PROGRAM when playback is about to begin.", "PROGRAM")
|
||||||
|
.optopt("", "onstop", "Run PROGRAM when playback has ended.", "PROGRAM")
|
||||||
|
.optflag("v", "verbose", "Enable verbose output");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_authentication_arguments(opts: &mut getopts::Options) {
|
pub fn add_authentication_arguments(opts: &mut getopts::Options) {
|
||||||
|
@ -47,13 +52,8 @@ pub fn add_authentication_arguments(opts: &mut getopts::Options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_player_arguments(opts: &mut getopts::Options) {
|
pub fn add_player_arguments(opts: &mut getopts::Options) {
|
||||||
opts.optopt("", "backend", "Audio backend to use. Use '?' to list options", "BACKEND");
|
opts.optopt("", "backend", "Audio backend to use. Use '?' to list options", "BACKEND")
|
||||||
opts.optopt("", "device", "Audio device to use. Use '?' to list options", "DEVICE");
|
.optopt("", "device", "Audio device to use. Use '?' to list options", "DEVICE");
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_program_arguments(opts: &mut getopts::Options) {
|
|
||||||
opts.optopt("", "onstart", "Run PROGRAM when playback is about to begin.", "PROGRAM");
|
|
||||||
opts.optopt("", "onstop", "Run PROGRAM when playback has ended.", "PROGRAM");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_session(matches: &getopts::Matches) -> Session {
|
pub fn create_session(matches: &getopts::Matches) -> Session {
|
||||||
|
@ -136,3 +136,27 @@ pub fn create_player(session: &Session, matches: &getopts::Matches) -> Player {
|
||||||
make_backend(device_name.as_ref().map(AsRef::as_ref))
|
make_backend(device_name.as_ref().map(AsRef::as_ref))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setup_logging(matches: &getopts::Matches) {
|
||||||
|
let verbose = matches.opt_present("verbose");
|
||||||
|
let mut builder = LogBuilder::new();
|
||||||
|
|
||||||
|
match env::var("RUST_LOG") {
|
||||||
|
Ok(config) => {
|
||||||
|
builder.parse(&config);
|
||||||
|
builder.init().unwrap();
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
warn!("`--verbose` flag overidden by `RUST_LOG` environment variable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
if verbose {
|
||||||
|
builder.parse("mdns=info,librespot=trace");
|
||||||
|
} else {
|
||||||
|
builder.parse("mdns=info,librespot=info");
|
||||||
|
}
|
||||||
|
builder.init().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -180,10 +180,12 @@ fn find_available_alternative<'a>(session: &Session, track: &'a Track) -> Option
|
||||||
fn load_track(session: &Session, track_id: SpotifyId) -> Option<vorbis::Decoder<Subfile<AudioDecrypt<Box<ReadSeek>>>>> {
|
fn load_track(session: &Session, track_id: SpotifyId) -> Option<vorbis::Decoder<Subfile<AudioDecrypt<Box<ReadSeek>>>>> {
|
||||||
let track = session.metadata::<Track>(track_id).await().unwrap();
|
let track = session.metadata::<Track>(track_id).await().unwrap();
|
||||||
|
|
||||||
|
info!("Loading track {:?}", track.name);
|
||||||
|
|
||||||
let track = match find_available_alternative(session, &track) {
|
let track = match find_available_alternative(session, &track) {
|
||||||
Some(track) => track,
|
Some(track) => track,
|
||||||
None => {
|
None => {
|
||||||
warn!("Track \"{}\" is not available", track.name);
|
warn!("Track {:?} is not available", track.name);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl Channel {
|
||||||
packet.read_u16::<BigEndian>().unwrap(); // Skip channel id
|
packet.read_u16::<BigEndian>().unwrap(); // Skip channel id
|
||||||
|
|
||||||
if cmd == 0xa {
|
if cmd == 0xa {
|
||||||
error!("error: {} {}", data.len(), packet.read_u16::<BigEndian>().unwrap());
|
trace!("error: {} {}", data.len(), packet.read_u16::<BigEndian>().unwrap());
|
||||||
return match handler.box_on_error(session) {
|
return match handler.box_on_error(session) {
|
||||||
Response::Continue(_) => Response::Close,
|
Response::Continue(_) => Response::Close,
|
||||||
Response::Spawn(f) => Response::Spawn(f),
|
Response::Spawn(f) => Response::Spawn(f),
|
||||||
|
|
Loading…
Reference in a new issue