aboutsummaryrefslogtreecommitdiff
path: root/src/commands/playback.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/playback.rs')
-rw-r--r--src/commands/playback.rs215
1 files changed, 55 insertions, 160 deletions
diff --git a/src/commands/playback.rs b/src/commands/playback.rs
index 21393a2..7ecef47 100644
--- a/src/commands/playback.rs
+++ b/src/commands/playback.rs
@@ -1,7 +1,3 @@
-use either::{
- Left,
- Right,
-};
use log::{
debug,
error,
@@ -18,32 +14,43 @@ use serenity::{
CommandError,
CommandResult,
},
- futures::TryFutureExt,
model::channel::Message,
prelude::*,
};
-use tap::{
- Conv,
- Pipe,
+use songbird::{
+ input::YoutubeDl,
+ Call,
+ Songbird,
};
+use std::sync::Arc;
+use tap::Conv;
use crate::{
- audio::{
- parse_times,
- PlayArgs,
- PlayQueue,
- VoiceManager,
- },
+ bot::HttpKey,
commands::sound_levels::*,
util,
CONFIG,
};
#[group]
-#[commands(skip, pause, resume, list, die, mute, unmute, play, volume)]
+#[commands(skip, pause, resume, list, die, mute, unmute, play)]
#[only_in(guild)]
struct Playback;
+pub async fn songbird(
+ ctx: &Context,
+ msg: &Message,
+) -> Result<(Arc<Songbird>, Arc<Mutex<Call>>), CommandError> {
+ let Some(gid) = msg.guild_id else {
+ return Err(anyhow::anyhow!("no guild id").into());
+ };
+
+ let sb = songbird::get(ctx).await.expect("acquiring songbird handle");
+ let call = sb.get_or_insert(gid);
+
+ Ok((sb, call))
+}
+
pub async fn _play(ctx: &Context, msg: &Message, url: &str) -> CommandResult {
use url::{
Host,
@@ -83,18 +90,20 @@ pub async fn _play(ctx: &Context, msg: &Message, url: &str) -> CommandResult {
return Ok(());
}
- let (start, end) = parse_times(&msg.content);
+ let (_sb, call) = songbird(ctx, msg).await?;
+ let mut call = call.lock().await;
- let queue_lock = ctx.data.write().await.get::<PlayQueue>().cloned().unwrap();
- let mut play_queue = queue_lock.write().unwrap();
+ if call.current_channel().is_none() {
+ call.join(CONFIG.discord.voice_channel()).await?;
+ }
- play_queue.general_queue.push_back(PlayArgs {
- initiator: msg.author.name.clone(),
- data: Left(url.conv::<String>()),
- sender_channel: msg.channel_id,
- start,
- end,
- });
+ let client = {
+ let data = ctx.data.read().await;
+ data.get::<HttpKey>().unwrap().clone()
+ };
+
+ let input = YoutubeDl::new_ytdl_like("yt-dlp", client.clone(), url.conv::<String>());
+ call.enqueue_input(input.into()).await;
Ok(())
}
@@ -115,37 +124,15 @@ pub async fn play(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
},
};
- _play(ctx, msg, &url)
+ _play(ctx, msg, &url).await
}
#[command]
pub async fn pause(ctx: &Context, msg: &Message, _: Args) -> CommandResult {
- let queue_lock = ctx.data.write().await.get::<PlayQueue>().cloned().unwrap();
+ let (_sb, call) = songbird(ctx, msg).await?;
- let done = || util::send(ctx, msg.channel_id, "r u srs", msg.tts).map_err(CommandError::from);
- let playing = {
- let play_queue = queue_lock.read().unwrap();
-
- let current_item = match play_queue.playing {
- Some(ref x) => x,
- None => return done().await,
- };
-
- let audio = current_item.audio.lock();
- audio.playing
- };
-
- if !playing {
- return done().await;
- }
-
- {
- let queue = queue_lock.write().unwrap();
- let ref audio = queue.playing.clone().unwrap().audio;
- audio.lock().pause();
-
- info!("paused playback");
- }
+ let call = call.lock().await;
+ call.queue().pause()?;
Ok(())
}
@@ -157,58 +144,21 @@ pub async fn resume(ctx: &Context, msg: &Message, _: Args) -> CommandResult {
}
async fn _resume(ctx: &Context, msg: &Message) -> CommandResult {
- let queue_lock = ctx.data.write().await.get::<PlayQueue>().cloned().unwrap();
+ let (_sb, call) = songbird(ctx, msg).await?;
- let done = || util::send(ctx, msg.channel_id, "r u srs", msg.tts).map_err(CommandError::from);
- let playing = {
- let play_queue = queue_lock.read().unwrap();
-
- let current_item = match play_queue.playing {
- Some(ref x) => x,
- None => {
- done().await?;
- return Ok(());
- },
- };
-
- let audio = current_item.audio.lock();
- audio.playing
- };
-
- if playing {
- done().await?;
- debug!("attempted to resume playback while sound was already playing");
- return Ok(());
- }
-
- {
- let queue = queue_lock.write().unwrap();
- let ref audio = queue.playing.clone().unwrap().audio;
- audio.lock().play();
- info!("playback resumed");
- }
+ let call = call.lock().await;
+ call.queue().resume()?;
Ok(())
}
#[command]
#[aliases("next")]
-pub async fn skip(ctx: &Context, _msg: &Message, _args: Args) -> CommandResult {
- let data = ctx.data.write().await;
-
- let mgr_lock = data.get::<VoiceManager>().cloned().unwrap();
- let mut manager = mgr_lock.lock();
+pub async fn skip(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
+ let (_sb, call) = songbird(ctx, msg).await?;
- let queue_lock = data.get::<PlayQueue>().cloned().unwrap();
-
- if let Some(handler) = manager.get_mut(CONFIG.discord.guild()) {
- handler.stop();
- let mut play_queue = queue_lock.write().unwrap();
- play_queue.playing = None;
- info!("skipped currently-playing audio");
- } else {
- debug!("got skip with no handler attached");
- }
+ let call = call.lock().await;
+ call.queue().skip()?;
Ok(())
}
@@ -216,29 +166,10 @@ pub async fn skip(ctx: &Context, _msg: &Message, _args: Args) -> CommandResult {
#[command]
#[aliases("sudoku", "fuckoff", "stop")]
pub async fn die(ctx: &Context, msg: &Message, _: Args) -> CommandResult {
- let data = ctx.data.write().await;
-
- let mgr_lock = data.get::<VoiceManager>().cloned().unwrap();
- let mut manager = mgr_lock.lock();
+ let (_sb, call) = songbird(ctx, msg).await?;
- let queue_lock = data.get::<PlayQueue>().cloned().unwrap();
-
- {
- let mut play_queue = queue_lock.write().unwrap();
-
- play_queue.playing = None;
- play_queue.general_queue.clear();
- play_queue.meme_queue.clear();
- }
-
- if let Some(handler) = manager.get_mut(CONFIG.discord.guild()) {
- info!("killing playback");
- handler.stop();
- handler.leave();
- } else {
- util::send(ctx, msg.channel_id, "YOU die", msg.tts).await?;
- debug!("got die with no handler attached");
- }
+ let call = call.lock().await;
+ call.queue().stop();
Ok(())
}
@@ -246,55 +177,19 @@ pub async fn die(ctx: &Context, msg: &Message, _: Args) -> CommandResult {
#[command]
#[aliases("queue")]
pub async fn list(ctx: &Context, msg: &Message, _: Args) -> CommandResult {
- let queue_lock = ctx.data.write().await.get::<PlayQueue>().cloned().unwrap();
- let play_queue = queue_lock.read().unwrap();
+ let (_sb, call) = songbird(ctx, msg).await?;
- let channel = msg.channel(&ctx).await.unwrap().guild().unwrap();
+ let call = call.lock().await;
+ let queue = call.queue();
- info!("listing queue");
- match play_queue.playing {
- Some(ref info) => {
- let audio = info.audio.lock();
- let status = if audio.playing {
- "playing"
- } else {
- "paused:"
- };
+ util::send(ctx, msg.channel_id, "(command fix work-in-progress)", msg.tts).await?;
- let playing_info = match info.init_args.data {
- Left(ref url) => format!(" `{}`", url),
- Right(_) => "memeing".to_owned(),
- };
+ for track in queue.current_queue().into_iter() {
+ let info = track.get_info().await?;
- util::send(
- ctx,
- msg.channel_id,
- &format!("Currently {} {} ({})", status, playing_info, info.init_args.initiator),
- msg.tts,
- )
+ util::send(ctx, msg.channel_id, format!("track playing for {:?}", info.play_time), msg.tts)
.await?;
- },
- None => {
- debug!("`list` called with no items in queue");
- util::send(ctx, msg.channel_id, "Nothing is playing you meme", msg.tts).await?;
- return Ok(());
- },
}
- play_queue
- .meme_queue
- .iter()
- .chain(play_queue.general_queue.iter())
- .pipe(serenity::futures::stream::iter)
- .for_each(|info| async move {
- let playing_info = match info.data {
- Left(ref url) => format!("`{}`", url),
- Right(_) => "meme".to_owned(),
- };
-
- let _ = channel.say(&ctx, &format!("{} ({})", playing_info, info.initiator)).await;
- })
- .await;
-
Ok(())
}