@@ -3,11 +3,13 @@ use crate::model::playable::Playable;
33use crate :: queue:: QueueEvent ;
44use crate :: spotify:: PlayerEvent ;
55use futures:: Future ;
6+ use librespot_connect:: { ConnectConfig , LoadRequest , LoadRequestOptions , Spirc } ;
67use librespot_core:: session:: Session ;
78use librespot_core:: spotify_id:: SpotifyId ;
89use librespot_core:: token:: Token ;
910use librespot_playback:: mixer:: Mixer ;
1011use librespot_playback:: player:: { Player , PlayerEvent as LibrespotPlayerEvent } ;
12+ use librespot_protocol:: credentials;
1113use log:: { debug, error, info, warn} ;
1214use std:: sync:: Arc ;
1315use std:: sync:: mpsc:: Sender ;
@@ -41,31 +43,39 @@ pub struct Worker {
4143 events : EventManager ,
4244 player_events : UnboundedReceiverStream < LibrespotPlayerEvent > ,
4345 commands : UnboundedReceiverStream < WorkerCommand > ,
44- session : Session ,
45- player : Arc < Player > ,
4646 token_task : Pin < Box < dyn Future < Output = ( ) > + Send > > ,
4747 player_status : PlayerStatus ,
48- mixer : Arc < dyn Mixer > ,
48+ session : Session ,
49+ spirc : Spirc ,
50+ spirc_task : Pin < Box < dyn Future < Output = ( ) > + Send > > ,
4951}
5052
5153impl Worker {
52- pub ( crate ) fn new (
54+ pub ( crate ) async fn new (
5355 events : EventManager ,
56+ credentials : librespot_core:: authentication:: Credentials ,
5457 player_events : mpsc:: UnboundedReceiver < LibrespotPlayerEvent > ,
5558 commands : mpsc:: UnboundedReceiver < WorkerCommand > ,
5659 session : Session ,
5760 player : Arc < Player > ,
5861 mixer : Arc < dyn Mixer > ,
5962 ) -> Self {
63+ let config = ConnectConfig {
64+ name : "ncspot" . to_string ( ) ,
65+ ..Default :: default ( )
66+ } ;
67+ let ( spirc, spirc_task) = Spirc :: new ( config, session. clone ( ) , credentials, player, mixer)
68+ . await
69+ . expect ( "Spirc should be initialized" ) ;
6070 Self {
6171 events,
6272 player_events : UnboundedReceiverStream :: new ( player_events) ,
6373 commands : UnboundedReceiverStream :: new ( commands) ,
64- player,
65- session,
6674 token_task : Box :: pin ( futures:: future:: pending ( ) ) ,
6775 player_status : PlayerStatus :: Stopped ,
68- mixer,
76+ session,
77+ spirc,
78+ spirc_task : Box :: pin ( spirc_task) ,
6979 }
7080 }
7181
@@ -98,14 +108,22 @@ impl Worker {
98108 tokio:: select! {
99109 cmd = self . commands. next( ) => match cmd {
100110 Some ( WorkerCommand :: Load ( playable, start_playing, position_ms) ) => {
111+ self . spirc. activate( ) ;
101112 match SpotifyId :: from_uri( & playable. uri( ) ) {
102113 Ok ( id) => {
103114 info!( "player loading track: {id:?}" ) ;
104115 if !id. is_playable( ) {
105116 warn!( "track is not playable" ) ;
106117 self . events. send( Event :: Player ( PlayerEvent :: FinishedTrack ) ) ;
107118 } else {
108- self . player. load( id, start_playing, position_ms) ;
119+ let options = LoadRequestOptions {
120+ start_playing,
121+ seek_to: position_ms,
122+ context_options: None ,
123+ playing_track: None ,
124+ } ;
125+ let req = LoadRequest :: from_tracks( vec![ id. to_uri( ) . expect( "uri" ) ] , options) ;
126+ self . spirc. load( req) ;
109127 }
110128 }
111129 Err ( e) => {
@@ -115,32 +133,31 @@ impl Worker {
115133 }
116134 }
117135 Some ( WorkerCommand :: Play ) => {
118- self . player . play( ) ;
136+ self . spirc . play( ) ;
119137 }
120138 Some ( WorkerCommand :: Pause ) => {
121- self . player . pause( ) ;
139+ self . spirc . pause( ) ;
122140 }
123141 Some ( WorkerCommand :: Stop ) => {
124- self . player . stop ( ) ;
142+ //todo!("stop spirc" );
125143 }
126144 Some ( WorkerCommand :: Seek ( pos) ) => {
127- self . player . seek ( pos) ;
145+ self . spirc . set_position_ms ( pos) ;
128146 }
129147 Some ( WorkerCommand :: SetVolume ( volume) ) => {
130- self . mixer . set_volume( volume) ;
148+ self . spirc . set_volume( volume) ;
131149 }
132150 Some ( WorkerCommand :: RequestToken ( sender) ) => {
133151 self . token_task = Box :: pin( Self :: get_token( self . session. clone( ) , sender) ) ;
134152 }
135153 Some ( WorkerCommand :: Preload ( playable) ) => {
136154 if let Ok ( id) = SpotifyId :: from_uri( & playable. uri( ) ) {
137155 debug!( "Preloading {id:?}" ) ;
138- self . player. preload( id) ;
156+ // self.player.preload(id);
139157 }
140158 }
141159 Some ( WorkerCommand :: Shutdown ) => {
142- self . player. stop( ) ;
143- self . session. shutdown( ) ;
160+ self . spirc. shutdown( ) ;
144161 }
145162 None => info!( "empty stream" )
146163 } ,
@@ -197,6 +214,9 @@ impl Worker {
197214 break
198215 } ,
199216 } ,
217+ _ = self . spirc_task. as_mut( ) => {
218+ info!( "spirc task tick" ) ;
219+ } ,
200220 // Update animated parts of the UI (e.g. statusbar during playback).
201221 _ = ui_refresh. tick( ) => {
202222 if !matches!( self . player_status, PlayerStatus :: Stopped ) {
@@ -215,6 +235,6 @@ impl Worker {
215235impl Drop for Worker {
216236 fn drop ( & mut self ) {
217237 debug ! ( "Worker thread is shutting down, stopping player" ) ;
218- self . player . stop ( ) ;
238+ self . spirc . shutdown ( ) ;
219239 }
220240}
0 commit comments