diff options
Diffstat (limited to 'src/commands/playback/types.rs')
| -rw-r--r-- | src/commands/playback/types.rs | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/commands/playback/types.rs b/src/commands/playback/types.rs new file mode 100644 index 0000000..41592ec --- /dev/null +++ b/src/commands/playback/types.rs @@ -0,0 +1,139 @@ +use serenity::client::bridge::voice::ClientVoiceManager; +use typemap::Key; +use std::sync::{Arc, RwLock}; +use std::collections::VecDeque; +use super::*; + +pub struct VoiceManager; + +impl Key for VoiceManager { + type Value = Arc<Mutex<ClientVoiceManager>>; +} + +impl VoiceManager { + pub fn register(c: &mut Client) { + let mut data = c.data.lock(); + data.insert::<VoiceManager>(Arc::clone(&c.voice_manager)); + } +} + +#[derive(Clone, Debug)] +pub struct PlayArgs { + pub url: String, + pub initiator: String, + pub sender_channel: ChannelId, +} + +#[derive(Clone)] +pub struct CurrentItem { + pub init_args: PlayArgs, + pub audio: LockedAudio, +} + +#[derive(Clone)] +pub struct PlayQueue { + pub queue: VecDeque<PlayArgs>, + pub playing: Option<CurrentItem>, + pub volume: f32, +} + +impl Key for PlayQueue { + type Value = Arc<RwLock<PlayQueue>>; +} + +impl PlayQueue { + pub fn new() -> Self { + PlayQueue { + queue: VecDeque::new(), + playing: None, + volume: DEFAULT_VOLUME, + } + } + + pub fn register(c: &mut Client) { + let voice_manager = Arc::clone(&c.voice_manager); + + let mut data = c.data.lock(); + let queue = Arc::new(RwLock::new(PlayQueue::new())); + + data.insert::<PlayQueue>(Arc::clone(&queue)); + + thread::spawn(move || { + let queue_lck = Arc::clone(&queue); + let voice_manager = voice_manager; + + loop { + thread::sleep(Duration::from_millis(250)); + let (queue_is_empty, queue_has_playing) = { + let queue = queue_lck.read().unwrap(); + + let allow_continue = queue.playing.clone().map_or(false, |x| !x.audio.lock().finished); + + if allow_continue { + continue; + } + + (queue.queue.is_empty(), queue.playing.is_some()) + }; + + if queue_is_empty { + if queue_has_playing { + let mut queue = queue_lck.write().unwrap(); + + assert!({ + let audio_lck = queue.playing.clone().unwrap().audio; + let audio = audio_lck.lock(); + audio.finished + }); + + queue.playing = None; + + let mut manager = voice_manager.lock(); + manager.leave(*TARGET_GUILD_ID); + debug!("disconnected due to inactivity"); + } + continue; + } + + let mut queue = queue_lck.write().unwrap(); + let item = queue.queue.pop_front().unwrap(); + + trace!("checking ytdl for: {}", item.url); + + let src = match ytdl(&item.url) { + Ok(src) => src, + Err(e) => { + error!("bad link: {}; {:?}", &item.url, e); + let _ = send(item.sender_channel, &format!("what the fuck"), false); + continue; + } + }; + + trace!("got ytdl item for {}", item.url); + + let mut manager = voice_manager.lock(); + let handler = manager.join(*TARGET_GUILD_ID, must_env_lookup::<u64>("VOICE_CHANNEL")); + + match handler { + Some(handler) => { + let mut audio = handler.play_only(src); + { + audio.lock().volume(queue.volume); + } + + queue.playing = Some(CurrentItem { + init_args: item, + audio, + }); + + debug!("playing new song"); + }, + None => { + error!("couldn't join channel"); + let _ = send(item.sender_channel, "something happened somewhere somehow.", false); + } + } + } + }); + } +} |
