Added more control fields for playback control

api
Joey Hines 2024-10-14 20:44:48 -06:00
parent 10a13d3daa
commit f360e253b8
Signed by: joeyahines
GPG Key ID: 995E531F7A569DDB
7 changed files with 63 additions and 23 deletions

2
Cargo.lock generated
View File

@ -4141,6 +4141,7 @@ dependencies = [
"prost",
"spoticord_api_grpc",
"spoticord_database",
"spoticord_player",
"spoticord_session",
"thiserror",
"tokio",
@ -4198,6 +4199,7 @@ dependencies = [
"hex",
"librespot",
"log",
"rand",
"songbird",
"spoticord_audio",
"spoticord_utils",

View File

@ -7,10 +7,11 @@ edition = "2021"
spoticord_database = { path = "../spoticord_database" }
spoticord_session = { path = "../spoticord_session" }
spoticord_api_grpc = { path = "../spoticord_api_grpc"}
spoticord_player = { path = "../spoticord_player"}
prost = "0.13.3"
tokio = {version = "1.38.0", features = ["io-util", "net", "rt-multi-thread"]}
axum = "0.7.5"
env_logger = "0.11.3"
log = "0.4.21"
thiserror = "1.0.61"
tonic = "0.12.3"
tonic = "0.12.3"

View File

@ -1,5 +1,6 @@
use log::info;
use spoticord_api_grpc::spoticord_api::service::PlayPlaylistRequest;
use spoticord_api_grpc::spoticord_api::service::{PlayModes, PlayPlaylistRequest};
use spoticord_player::playback_control::{PlayPlaylist, StartAt};
use spoticord_session::manager::{SessionManager, SessionQuery};
use tonic::{Request, Response, Status};
@ -26,7 +27,19 @@ impl spoticord_api_grpc::spoticord_api::service::spoticord_api_server::Spoticord
.get_session(SessionQuery::Owner(playlist.discord_user_id.into()))
.unwrap();
session.queue_playlist(playlist.playlist_uri).await.unwrap();
let shuffle = match playlist.order() {
PlayModes::Shuffle => true,
PlayModes::InOrder => false,
};
let play_playlist = PlayPlaylist {
uri: playlist.playlist_uri,
shuffle,
repeat: true,
start_at: StartAt::FirstSong,
};
session.queue_playlist(play_playlist).await.unwrap();
let response = spoticord_api_grpc::spoticord_api::service::Response {
resp: Option::from(

View File

@ -16,3 +16,4 @@ anyhow = "1.0.86"
log = "0.4.22"
symphonia = { version = "0.5.4", default-features = false, features = ["pcm"] }
hex = "0.4.3"
rand = "0.8.5"

View File

@ -1,5 +1,7 @@
pub mod info;
pub mod playback_control;
use crate::playback_control::{PlayPlaylist, StartAt};
use anyhow::Result;
use info::PlaybackInfo;
use librespot::connect::spirc::SpircLoadCommand;
@ -18,6 +20,7 @@ use librespot::{
},
};
use log::{error, trace};
use rand::{thread_rng, Rng};
use songbird::{input::RawAdapter, tracks::TrackHandle, Call};
use spoticord_audio::{
sink::{SinkEvent, StreamSink},
@ -38,7 +41,7 @@ enum PlayerCommand {
GetPlaybackInfo(oneshot::Sender<Option<PlaybackInfo>>),
GetLyrics(oneshot::Sender<Option<Lyrics>>),
QueuePlaylist { uri: String },
QueuePlaylist(PlayPlaylist),
Shutdown,
}
@ -218,7 +221,7 @@ impl Player {
PlayerCommand::GetLyrics(tx) => self.get_lyrics(tx).await,
PlayerCommand::Shutdown => self.commands.close(),
PlayerCommand::QueuePlaylist { uri } => self.queue_playlist(uri).await,
PlayerCommand::QueuePlaylist(play_playlist) => self.queue_playlist(play_playlist).await,
};
}
@ -307,12 +310,15 @@ impl Player {
_ = tx.send(Some(lyrics));
}
async fn queue_playlist(&self, playlist_uri: String) {
let playlist = Playlist::get(&self.session, &SpotifyId::from_uri(&playlist_uri).unwrap())
.await
.unwrap();
async fn queue_playlist(&self, playlist_control: PlayPlaylist) {
let playlist = Playlist::get(
&self.session,
&SpotifyId::from_uri(&playlist_control.uri).unwrap(),
)
.await
.unwrap();
let tracks = playlist
let tracks: Vec<_> = playlist
.tracks()
.map(|track_id| {
let mut track = TrackRef::new();
@ -323,13 +329,18 @@ impl Player {
self.spirc.activate().unwrap();
let start_ndx = match playlist_control.start_at {
StartAt::FirstSong => 0u32,
StartAt::Random => thread_rng().gen_range(0..tracks.len()) as u32,
};
self.spirc
.load(SpircLoadCommand {
context_uri: playlist_uri,
context_uri: playlist_control.uri,
start_playing: true,
shuffle: true,
repeat: true,
playing_track_index: 0,
shuffle: playlist_control.shuffle,
repeat: playlist_control.repeat,
playing_track_index: start_ndx,
tracks,
})
.unwrap();
@ -389,9 +400,9 @@ impl PlayerHandle {
_ = self.commands.send(PlayerCommand::Shutdown).await;
}
pub async fn queue_playlist(&self, playlist_uri: String) {
pub async fn queue_playlist(&self, play_playlist: PlayPlaylist) {
self.commands
.send(PlayerCommand::QueuePlaylist { uri: playlist_uri })
.send(PlayerCommand::QueuePlaylist(play_playlist))
.await
.unwrap()
}

View File

@ -0,0 +1,13 @@
#[derive(Debug, Clone)]
pub enum StartAt {
FirstSong,
Random,
}
#[derive(Debug, Clone)]
pub struct PlayPlaylist {
pub uri: String,
pub shuffle: bool,
pub repeat: bool,
pub start_at: StartAt,
}

View File

@ -17,6 +17,7 @@ use serenity::{
};
use songbird::{model::payload::ClientDisconnect, Call, CoreEvent, Event, EventContext};
use spoticord_database::Database;
use spoticord_player::playback_control::PlayPlaylist;
use spoticord_player::{Player, PlayerEvent, PlayerHandle};
use spoticord_utils::{discord::Colors, spotify};
use std::{ops::ControlFlow, sync::Arc, time::Duration};
@ -42,9 +43,7 @@ pub enum SessionCommand {
ShutdownPlayer,
Disconnect,
DisconnectTimedOut,
QueuePlaylist {
playlist_uri: String,
},
QueuePlaylist(PlayPlaylist),
}
pub struct Session {
@ -292,8 +291,8 @@ impl Session {
return ControlFlow::Break(());
}
SessionCommand::QueuePlaylist { playlist_uri } => {
self.player.queue_playlist(playlist_uri).await;
SessionCommand::QueuePlaylist(play_playlist) => {
self.player.queue_playlist(play_playlist).await;
}
};
@ -557,9 +556,9 @@ impl SessionHandle {
}
}
pub async fn queue_playlist(&self, playlist_uri: String) -> Result<()> {
pub async fn queue_playlist(&self, play_playlist: PlayPlaylist) -> Result<()> {
self.commands
.send(SessionCommand::QueuePlaylist { playlist_uri })
.send(SessionCommand::QueuePlaylist(play_playlist))
.await?;
Ok(())