feat!: queue system
This commit is contained in:
150
src/player.rs
150
src/player.rs
@@ -6,11 +6,13 @@ use tokio_stream::{wrappers::ReceiverStream, Stream};
|
||||
|
||||
use crate::{
|
||||
database::tracks::{get_track, get_track_full_path},
|
||||
music::queue::queue_to_track_vec,
|
||||
proto::{
|
||||
self,
|
||||
player::{
|
||||
player_server::Player, PauseState, PlayTrackRequest, PlayTrackResponse, PlayerStatus,
|
||||
player_server::Player, PauseState, PlayTrackResponse, PlayerStatus, Queue,
|
||||
SeekPositionRequest, SeekPositionResponse, SetVolumeRequest, SetVolumeResponse,
|
||||
SkipToQueueIndexRequest, TrackRequest,
|
||||
},
|
||||
},
|
||||
state::GrooveState,
|
||||
@@ -33,7 +35,7 @@ impl Player for PlayerService {
|
||||
|
||||
async fn play_track(
|
||||
&self,
|
||||
request: tonic::Request<PlayTrackRequest>,
|
||||
request: tonic::Request<TrackRequest>,
|
||||
) -> Result<tonic::Response<PlayTrackResponse>, tonic::Status> {
|
||||
let Ok(db) = self.pool.get() else {
|
||||
return Err(tonic::Status::internal(""));
|
||||
@@ -49,9 +51,14 @@ impl Player for PlayerService {
|
||||
return Err(tonic::Status::not_found(""));
|
||||
};
|
||||
|
||||
let mut state = self.state.lock().await;
|
||||
let state = self.state.lock().await;
|
||||
|
||||
let _ = state.player.play_track(track.clone(), track_path);
|
||||
let _ = state
|
||||
.player
|
||||
.lock()
|
||||
.await
|
||||
.play_track(track.clone(), track_path, true)
|
||||
.await;
|
||||
|
||||
let response = PlayTrackResponse {
|
||||
track: Some(proto::library::Track::from(track.into())),
|
||||
@@ -63,11 +70,11 @@ impl Player for PlayerService {
|
||||
|
||||
async fn resume_track(
|
||||
&self,
|
||||
_request: tonic::Request<()>,
|
||||
_: tonic::Request<()>,
|
||||
) -> Result<tonic::Response<PauseState>, tonic::Status> {
|
||||
let state = self.state.lock().await;
|
||||
|
||||
state.player.resume();
|
||||
state.player.lock().await.resume().await;
|
||||
|
||||
let response = PauseState { is_paused: false };
|
||||
|
||||
@@ -76,11 +83,11 @@ impl Player for PlayerService {
|
||||
|
||||
async fn pause_track(
|
||||
&self,
|
||||
_request: tonic::Request<()>,
|
||||
_: tonic::Request<()>,
|
||||
) -> Result<tonic::Response<PauseState>, tonic::Status> {
|
||||
let state = self.state.lock().await;
|
||||
|
||||
state.player.pause();
|
||||
state.player.lock().await.pause().await;
|
||||
|
||||
let response = PauseState { is_paused: true };
|
||||
|
||||
@@ -89,11 +96,11 @@ impl Player for PlayerService {
|
||||
|
||||
async fn toggle_pause(
|
||||
&self,
|
||||
_request: tonic::Request<()>,
|
||||
_: tonic::Request<()>,
|
||||
) -> Result<tonic::Response<PauseState>, tonic::Status> {
|
||||
let state = self.state.lock().await;
|
||||
|
||||
let is_paused = state.player.toggle_pause();
|
||||
let is_paused = state.player.lock().await.toggle_pause().await;
|
||||
|
||||
let response = PauseState { is_paused };
|
||||
|
||||
@@ -107,7 +114,7 @@ impl Player for PlayerService {
|
||||
let input = request.get_ref();
|
||||
let state = self.state.lock().await;
|
||||
|
||||
state.player.set_position(input.position);
|
||||
state.player.lock().await.set_position(input.position).await;
|
||||
|
||||
let response = SeekPositionResponse {
|
||||
position: input.position,
|
||||
@@ -123,7 +130,7 @@ impl Player for PlayerService {
|
||||
let input = request.get_ref();
|
||||
let state = self.state.lock().await;
|
||||
|
||||
state.player.set_volume(input.volume);
|
||||
state.player.lock().await.set_volume(input.volume).await;
|
||||
|
||||
let response = SetVolumeResponse {
|
||||
volume: input.volume,
|
||||
@@ -134,7 +141,7 @@ impl Player for PlayerService {
|
||||
|
||||
async fn get_status(
|
||||
&self,
|
||||
_request: tonic::Request<()>,
|
||||
_: tonic::Request<()>,
|
||||
) -> Result<tonic::Response<Self::GetStatusStream>, tonic::Status> {
|
||||
let state = self.state.clone();
|
||||
|
||||
@@ -145,7 +152,15 @@ impl Player for PlayerService {
|
||||
tokio::spawn(async move {
|
||||
while !tx.is_closed() {
|
||||
if let Err(_) = tx
|
||||
.send(Ok(state.lock().await.player.get_snapshot().into()))
|
||||
.send(Ok(state
|
||||
.lock()
|
||||
.await
|
||||
.player
|
||||
.lock()
|
||||
.await
|
||||
.get_snapshot()
|
||||
.await
|
||||
.into()))
|
||||
.await
|
||||
{
|
||||
break;
|
||||
@@ -161,4 +176,111 @@ impl Player for PlayerService {
|
||||
|
||||
Ok(tonic::Response::new(response))
|
||||
}
|
||||
|
||||
async fn add_track_to_queue(
|
||||
&self,
|
||||
request: tonic::Request<TrackRequest>,
|
||||
) -> Result<tonic::Response<Queue>, tonic::Status> {
|
||||
let Ok(db) = self.pool.get() else {
|
||||
return Err(tonic::Status::internal(""));
|
||||
};
|
||||
|
||||
let input = request.get_ref();
|
||||
|
||||
let Ok(track) = get_track(&db, input.hash.as_str()) else {
|
||||
return Err(tonic::Status::not_found(""));
|
||||
};
|
||||
|
||||
let Ok(track_path) = get_track_full_path(&db, input.hash.as_str()) else {
|
||||
return Err(tonic::Status::not_found(""));
|
||||
};
|
||||
|
||||
let state = self.state.lock().await;
|
||||
let mut player = state.player.lock().await;
|
||||
|
||||
if let Err(_) = player.add_to_queue(track, &track_path).await {
|
||||
return Err(tonic::Status::internal(""));
|
||||
}
|
||||
|
||||
let queue = player.queue().await;
|
||||
|
||||
let response = Queue {
|
||||
tracks: queue_to_track_vec(queue),
|
||||
};
|
||||
|
||||
Ok(tonic::Response::new(response))
|
||||
}
|
||||
|
||||
async fn play_track_next(
|
||||
&self,
|
||||
request: tonic::Request<TrackRequest>,
|
||||
) -> Result<tonic::Response<Queue>, tonic::Status> {
|
||||
let Ok(db) = self.pool.get() else {
|
||||
return Err(tonic::Status::internal(""));
|
||||
};
|
||||
|
||||
let input = request.get_ref();
|
||||
|
||||
let Ok(track) = get_track(&db, input.hash.as_str()) else {
|
||||
return Err(tonic::Status::not_found(""));
|
||||
};
|
||||
|
||||
let Ok(track_path) = get_track_full_path(&db, input.hash.as_str()) else {
|
||||
return Err(tonic::Status::not_found(""));
|
||||
};
|
||||
|
||||
let state = self.state.lock().await;
|
||||
let mut player = state.player.lock().await;
|
||||
|
||||
if let Err(_) = player.play_track_next(track, &track_path).await {
|
||||
return Err(tonic::Status::internal(""));
|
||||
}
|
||||
|
||||
let queue = player.queue().await;
|
||||
|
||||
let response = Queue {
|
||||
tracks: queue_to_track_vec(queue),
|
||||
};
|
||||
|
||||
Ok(tonic::Response::new(response))
|
||||
}
|
||||
|
||||
async fn skip_track(
|
||||
&self,
|
||||
_: tonic::Request<()>,
|
||||
) -> Result<tonic::Response<PlayerStatus>, tonic::Status> {
|
||||
let state = self.state.lock().await;
|
||||
|
||||
let mut player = state.player.lock().await;
|
||||
|
||||
if let Err(_) = player.skip_track().await {
|
||||
return Err(tonic::Status::internal(""));
|
||||
};
|
||||
|
||||
let response = player.get_snapshot().await.into();
|
||||
|
||||
Ok(tonic::Response::new(response))
|
||||
}
|
||||
|
||||
async fn skip_to_queue_index(
|
||||
&self,
|
||||
request: tonic::Request<SkipToQueueIndexRequest>,
|
||||
) -> Result<tonic::Response<PlayerStatus>, tonic::Status> {
|
||||
let input = request.get_ref();
|
||||
|
||||
let Ok(index) = input.index.try_into() else {
|
||||
return Err(tonic::Status::internal(""));
|
||||
};
|
||||
|
||||
let state = self.state.lock().await;
|
||||
let mut player = state.player.lock().await;
|
||||
|
||||
if let Err(_) = player.skip_to_queue_index(index).await {
|
||||
return Err(tonic::Status::internal(""));
|
||||
};
|
||||
|
||||
let response = player.get_snapshot().await.into();
|
||||
|
||||
Ok(tonic::Response::new(response))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user