aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan Perry <np@nathanperry.dev>2024-08-16 23:09:41 -0400
committerNathan Perry <np@nathanperry.dev>2024-08-16 23:09:43 -0400
commit584f0ebc6e33ddc2905d82f44e7b42faea122668 (patch)
treee4a2bbc3d801086649c29a1de741dd49fc466b96 /src
parente0a9b18f45858829f88cbe20611aaf696fc5bf6a (diff)
fill in queued playback info
Diffstat (limited to 'src')
-rw-r--r--src/bot.rs8
-rw-r--r--src/commands/playback.rs58
-rw-r--r--src/commands/today/mod.rs21
3 files changed, 73 insertions, 14 deletions
diff --git a/src/bot.rs b/src/bot.rs
index d9047e6..4ad22c6 100644
--- a/src/bot.rs
+++ b/src/bot.rs
@@ -69,6 +69,12 @@ impl TypeMapKey for VolumeKey {
type Value = DashMap<GuildId, f64>;
}
+pub struct PlaybackKey;
+
+impl TypeMapKey for PlaybackKey {
+ type Value = Arc<DashMap<uuid::Uuid, songbird::input::AuxMetadata>>;
+}
+
#[cfg(debug_assertions)]
const BOTNAME: &str = "thulani (dev)";
@@ -127,6 +133,7 @@ struct SongbirdHandler(Arc<Mutex<Call>>);
impl songbird::events::EventHandler for SongbirdHandler {
async fn act(&self, _ctx: &EventContext<'_>) -> Option<Event> {
let mut call = self.0.lock().await;
+
if call.queue().is_empty() {
let _ = call.leave().await;
}
@@ -416,6 +423,7 @@ pub async fn run() -> anyhow::Result<()> {
.register_songbird_from_config(sb_config)
.type_map_insert::<HttpKey>(reqwest::Client::new())
.type_map_insert::<VolumeKey>(DashMap::new())
+ .type_map_insert::<PlaybackKey>(Arc::new(DashMap::new()))
.framework(framework().await)
.await?;
diff --git a/src/commands/playback.rs b/src/commands/playback.rs
index 4d6d0be..e7bf830 100644
--- a/src/commands/playback.rs
+++ b/src/commands/playback.rs
@@ -1,4 +1,7 @@
-use std::sync::Arc;
+use std::{
+ fmt::Debug,
+ sync::Arc,
+};
use grate::tracing;
use serenity::prelude::*;
@@ -10,7 +13,10 @@ use songbird::{
use tap::Conv;
use crate::{
- bot::HttpKey,
+ bot::{
+ HttpKey,
+ PlaybackKey,
+ },
util,
PoiseContext,
PoiseData,
@@ -21,9 +27,7 @@ pub fn commands() -> impl IntoIterator<Item = poise::Command<PoiseData, anyhow::
}
pub async fn songbird(ctx: PoiseContext<'_>) -> anyhow::Result<(Arc<Songbird>, Arc<Mutex<Call>>)> {
- let Some(gid) = ctx.guild_id() else {
- return Err(anyhow::anyhow!("no guild id").into());
- };
+ let gid = util::guild_id(ctx)?;
let sb = songbird::get(ctx.serenity_context()).await.expect("acquiring songbird handle");
let call = sb.get_or_insert(gid);
@@ -196,19 +200,51 @@ pub async fn die(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
/// List queued audio.
#[poise::command(prefix_command, guild_only, category = "playback", aliases("queue"))]
pub async fn list(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
- let (_sb, call) = songbird(ctx).await?;
+ let current_queue = {
+ let (_sb, call) = songbird(ctx).await?;
- let call = call.lock().await;
- let queue = call.queue();
+ let call = call.lock().await;
+ let queue = call.queue();
- if queue.current_queue().is_empty() {
+ queue.current_queue()
+ };
+
+ let playback_data = {
+ let data = ctx.serenity_context().data.read().await;
+ data.get::<PlaybackKey>().cloned().unwrap()
+ };
+
+ if current_queue.is_empty() {
util::reply(ctx, "nothing queued").await?;
}
- for track in queue.current_queue().into_iter() {
+ fn fmt_option<T>(name: &str, opt: Option<T>) -> String
+ where
+ T: std::fmt::Display,
+ {
+ if let Some(opt) = opt {
+ format!("{opt}")
+ } else {
+ format!("<no {name}>")
+ }
+ }
+
+ for track in current_queue.into_iter() {
let info = track.get_info().await?;
- let fmt = format!("track playing for {:?}", info.play_time);
+ let meta = playback_data.get(&track.uuid()).map(|x| x.clone());
+ let meta = meta.as_ref();
+
+ let fmt = format!(
+ "{}: {:?} / {}",
+ fmt_option("title", meta.and_then(|x| x.title.as_ref())),
+ humantime::format_duration(info.position),
+ fmt_option(
+ "duration",
+ meta.and_then(|x| x.duration.as_ref().map(|&dur| humantime::format_duration(dur)))
+ )
+ );
+
util::reply(ctx, fmt).await?;
}
diff --git a/src/commands/today/mod.rs b/src/commands/today/mod.rs
index f8f38c7..2c47e83 100644
--- a/src/commands/today/mod.rs
+++ b/src/commands/today/mod.rs
@@ -5,11 +5,17 @@ use rand::{
seq::SliceRandom,
thread_rng,
};
-use songbird::input::YoutubeDl;
+use songbird::input::{
+ Compose,
+ YoutubeDl,
+};
use tap::Conv;
use crate::{
- bot::HttpKey,
+ bot::{
+ HttpKey,
+ PlaybackKey,
+ },
commands::playback::songbird,
util,
PoiseContext,
@@ -117,12 +123,21 @@ pub async fn today(ctx: PoiseContext<'_>, #[rest] _rest: Option<String>) -> anyh
data.get::<HttpKey>().unwrap().clone()
};
- let input =
+ let mut input =
YoutubeDl::new_ytdl_like("yt-dlp", client.clone(), play_args.url.conv::<String>());
+ let meta = input.aux_metadata().await?;
+
let handle = call.enqueue_input(input.into()).await;
handle.set_volume(volume as _)?;
+ let playback = {
+ let data = ctx.serenity_context().data.read().await;
+ data.get::<PlaybackKey>().unwrap().clone()
+ };
+
+ playback.insert(handle.uuid(), meta);
+
let q = call.queue();
q.pause()?;
q.modify_queue(move |q| {