2015-04-25 20:32:07 +00:00
|
|
|
#![crate_name = "librespot"]
|
|
|
|
|
2015-07-01 17:49:03 +00:00
|
|
|
#![feature(plugin,zero_one,iter_arith,slice_position_elem,slice_bytes,bitset,mpsc_select,arc_weak,append)]
|
2015-07-01 18:47:51 +00:00
|
|
|
#![allow(unused_imports,dead_code)]
|
2015-04-25 20:32:07 +00:00
|
|
|
|
|
|
|
#![plugin(protobuf_macros)]
|
|
|
|
#[macro_use] extern crate lazy_static;
|
|
|
|
|
2015-07-01 18:47:51 +00:00
|
|
|
|
2015-04-25 20:32:07 +00:00
|
|
|
extern crate byteorder;
|
|
|
|
extern crate crypto;
|
|
|
|
extern crate gmp;
|
|
|
|
extern crate num;
|
2015-06-23 14:38:29 +00:00
|
|
|
extern crate portaudio;
|
2015-04-25 20:32:07 +00:00
|
|
|
extern crate protobuf;
|
2015-05-09 10:07:24 +00:00
|
|
|
extern crate shannon;
|
2015-04-25 20:32:07 +00:00
|
|
|
extern crate rand;
|
2015-05-09 10:07:24 +00:00
|
|
|
extern crate readall;
|
2015-06-23 14:38:29 +00:00
|
|
|
extern crate vorbis;
|
2015-05-09 10:07:24 +00:00
|
|
|
|
|
|
|
extern crate librespot_protocol;
|
2015-04-25 20:32:07 +00:00
|
|
|
|
2015-06-23 14:38:29 +00:00
|
|
|
#[macro_use] mod util;
|
|
|
|
mod audio_decrypt;
|
|
|
|
mod audio_file;
|
|
|
|
mod audio_key;
|
2015-04-25 20:32:07 +00:00
|
|
|
mod connection;
|
2015-05-09 10:07:24 +00:00
|
|
|
mod keys;
|
2015-06-23 14:38:29 +00:00
|
|
|
mod mercury;
|
|
|
|
mod metadata;
|
|
|
|
mod player;
|
2015-04-25 20:32:07 +00:00
|
|
|
mod session;
|
2015-06-23 14:38:29 +00:00
|
|
|
mod stream;
|
|
|
|
mod subsystem;
|
2015-04-25 20:32:07 +00:00
|
|
|
|
2015-06-23 14:38:29 +00:00
|
|
|
use std::clone::Clone;
|
2015-05-09 10:07:24 +00:00
|
|
|
use std::fs::File;
|
2015-06-23 14:38:29 +00:00
|
|
|
use std::io::{Read, Write};
|
2015-05-09 10:07:24 +00:00
|
|
|
use std::path::Path;
|
2015-07-01 18:47:51 +00:00
|
|
|
use std::sync::mpsc;
|
2015-05-09 10:07:24 +00:00
|
|
|
|
2015-06-23 14:38:29 +00:00
|
|
|
use metadata::{MetadataCache, AlbumRef, ArtistRef, TrackRef};
|
|
|
|
use session::{Config, Session};
|
|
|
|
use util::SpotifyId;
|
|
|
|
use player::Player;
|
2015-07-01 18:47:51 +00:00
|
|
|
use mercury::{MercuryRequest, MercuryMethod};
|
|
|
|
use librespot_protocol as protocol;
|
2015-04-25 20:32:07 +00:00
|
|
|
|
|
|
|
fn main() {
|
2015-05-09 10:07:24 +00:00
|
|
|
let mut args = std::env::args().skip(1);
|
|
|
|
let mut appkey_file = File::open(Path::new(&args.next().unwrap())).unwrap();
|
|
|
|
let username = args.next().unwrap();
|
|
|
|
let password = args.next().unwrap();
|
|
|
|
|
|
|
|
let mut appkey = Vec::new();
|
|
|
|
appkey_file.read_to_end(&mut appkey).unwrap();
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
application_key: appkey,
|
|
|
|
user_agent: "ABC".to_string(),
|
|
|
|
device_id: "ABC".to_string()
|
|
|
|
};
|
2015-06-23 14:38:29 +00:00
|
|
|
let session = Session::new(config);
|
|
|
|
session.login(username, password);
|
|
|
|
session.poll();
|
2015-05-09 10:07:24 +00:00
|
|
|
|
2015-06-23 14:38:29 +00:00
|
|
|
let mut cache = MetadataCache::new(session.metadata.clone());
|
2015-07-01 17:49:03 +00:00
|
|
|
|
2015-07-01 18:47:51 +00:00
|
|
|
let (tx, rx) = mpsc::channel();
|
|
|
|
|
|
|
|
session.mercury.send(MercuryRequest{
|
|
|
|
method: MercuryMethod::SUB,
|
|
|
|
uri: "hm://remote/user/lietar/v23".to_string(),
|
|
|
|
content_type: None,
|
|
|
|
callback: Some(tx)
|
|
|
|
}).unwrap();
|
|
|
|
|
|
|
|
for pkt in rx.iter() {
|
|
|
|
let frame : protocol::spirc::Frame =
|
|
|
|
protobuf::parse_from_bytes(pkt.payload.front().unwrap()).unwrap();
|
|
|
|
|
|
|
|
if frame.get_device_state().get_is_active() &&
|
|
|
|
frame.has_state() {
|
|
|
|
let index = frame.get_state().get_playing_track_index();
|
|
|
|
let ref track = frame.get_state().get_track()[index as usize];
|
|
|
|
println!("{}", frame.get_device_state().get_name());
|
|
|
|
print_track(&mut cache, SpotifyId::from_raw(track.get_gid()));
|
|
|
|
println!("");
|
|
|
|
}
|
|
|
|
}
|
2015-07-01 17:49:03 +00:00
|
|
|
|
|
|
|
loop {
|
|
|
|
session.poll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_track(cache: &mut MetadataCache, track_id: SpotifyId) {
|
2015-06-23 14:38:29 +00:00
|
|
|
let track : TrackRef = cache.get(track_id);
|
|
|
|
|
|
|
|
let album : AlbumRef = {
|
|
|
|
let handle = track.wait();
|
|
|
|
let data = handle.unwrap();
|
|
|
|
eprintln!("{}", data.name);
|
|
|
|
cache.get(data.album)
|
|
|
|
};
|
|
|
|
|
|
|
|
let artists : Vec<ArtistRef> = {
|
|
|
|
let handle = album.wait();
|
|
|
|
let data = handle.unwrap();
|
|
|
|
eprintln!("{}", data.name);
|
|
|
|
data.artists.iter().map(|id| {
|
|
|
|
cache.get(*id)
|
|
|
|
}).collect()
|
|
|
|
};
|
|
|
|
|
|
|
|
for artist in artists {
|
|
|
|
let handle = artist.wait();
|
|
|
|
let data = handle.unwrap();
|
|
|
|
eprintln!("{}", data.name);
|
|
|
|
}
|
2015-04-25 20:32:07 +00:00
|
|
|
}
|
|
|
|
|