diff --git a/src/commands/voice/mod.rs b/src/commands/voice/mod.rs index 284b48d..f3d7e73 100644 --- a/src/commands/voice/mod.rs +++ b/src/commands/voice/mod.rs @@ -2,4 +2,5 @@ pub mod util; pub mod player_common; pub mod radio; // pub mod spotify; -pub mod general; \ No newline at end of file +pub mod general; +pub mod yt; \ No newline at end of file diff --git a/src/commands/voice/yt/mod.rs b/src/commands/voice/yt/mod.rs new file mode 100644 index 0000000..989288e --- /dev/null +++ b/src/commands/voice/yt/mod.rs @@ -0,0 +1,3 @@ +pub use yt_player::*; + +pub mod yt_player; \ No newline at end of file diff --git a/src/commands/voice/yt/yt_player.rs b/src/commands/voice/yt/yt_player.rs new file mode 100644 index 0000000..ff5098b --- /dev/null +++ b/src/commands/voice/yt/yt_player.rs @@ -0,0 +1,88 @@ +use std::vec; +use std::env; + +use songbird::input::YoutubeDl; + +use crate::commands::util::connect; +use crate::util::poise_context_extension::ContextExt; +use crate::types::{Context, Error}; +use crate::commands::voice::util::autocomplete_channel; + +// TODO: search, queue +#[poise::command( + slash_command, + description_localized("en-US", "Plays music from YouTube URL") +)] +pub async fn play_yt(ctx: Context<'_>, + #[autocomplete = "autocomplete_channel"] + #[description = "Voice channel name: "] + channel: Option, + #[description = "Source URL: "] + url: String, +) -> Result<(), Error> { + + if ctx.guild().is_none() { + ctx.reply_ephemeral("Can't use this outside of guild").await?; + return Ok(()); + } + + let manager = songbird::get(ctx.serenity_context()) + .await + .expect("Songbird Voice client placed in at initialisation.") + .clone(); + + let Some(guild_id) = ctx.guild_id() else { + ctx.reply_ephemeral("Guild id not found").await?; + return Ok(()) + }; + + let http_client = ctx.data().http_client.clone(); + + if manager.get(guild_id).is_none() { + match connect(&ctx, guild_id, channel).await { + Ok(_) => (), + Err(e) => { + ctx.reply_ephemeral(&e.to_string()).await?; + return Ok(()) + } + } + } + + if let Some(handler_lock) = manager.get(guild_id) { + let mut handler = handler_lock.lock().await; + + let cookies_path = match env::var("COOKIES") { + Ok(path) => path, + Err(e) => { + let _ = ctx.reply_ephemeral("There was an error (did not find cookies)").await; + dbg!(e); + return Ok(()); + } + }; + + let po_token = match env::var("PO_TOKEN") { + Ok(token) => token, + Err(e) => { + let _ = ctx.reply_ephemeral("There was an error (did not find token)").await; + dbg!(e); + return Ok(()); + } + }; + + let arguments: Vec = vec![ + "--extractor-args".into(), + format!("youtube:player-client=web,default;po_token=web+{po_token}"), + "--cookies".into(), + cookies_path + ]; + let src = YoutubeDl::new(http_client, url).user_args(arguments); + handler.enqueue_input(src.into()).await; + } + else { + ctx.reply_ephemeral("Not in a voice channel").await?; + return Ok(()) + } + + ctx.reply_ephemeral("Done!").await?; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 44bd0d3..66380e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,7 @@ impl EventHandler for Handler { } async fn ready(&self, ctx: Context, ready: Ready) { - println!("{} v3.3.0 is connected!", ready.user.name); + println!("{} v3.3.1 is connected!", ready.user.name); #[cfg(feature="RELEASE")] { use util::debug::hello; @@ -89,7 +89,8 @@ async fn main() -> anyhow::Result<()> { // commands::player::play_local(), commands::player_common::disconnect(), commands::radio::radio(), - commands::general::play() + commands::general::play(), + commands::yt::play_yt() ], prefix_options: poise::PrefixFrameworkOptions { prefix: Some("/".into()),