From 197129cf728f06f5b1bdbb342121e2d3798d2b24 Mon Sep 17 00:00:00 2001 From: Johannes Heuel Date: Wed, 14 Feb 2024 17:37:53 +0100 Subject: [PATCH] add queue --- Cargo.toml | 2 +- src/main.rs | 196 ++++------------------------------------------------ 2 files changed, 16 insertions(+), 182 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b418258..2d82d60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT" [dependencies] symphonia = { version = "0.5.2", features=["all"] } -songbird = { version = "0.4.0", features = ["driver", "gateway", "twilight", "rustls"] } +songbird = { version = "0.4.0", features = ["driver", "gateway", "twilight", "rustls", "builtin-queue"] } tokio = { features = ["macros", "rt-multi-thread", "signal", "sync"], version = "1" } regex = { version = "1", features = ["unicode-case"] } futures = "0.3" diff --git a/src/main.rs b/src/main.rs index aec61f5..c9727b1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,11 @@ use futures::StreamExt; use songbird::{ input::{Compose, YoutubeDl}, shards::TwilightMap, - tracks::{PlayMode, TrackHandle}, Songbird, }; -use std::{collections::HashMap, env, error::Error, future::Future, num::NonZeroU64, sync::Arc}; -use tokio::{process::Command, sync::RwLock}; +use std::{ + env, error::Error, future::Future, num::NonZeroU64, ops::Sub, sync::Arc, time::Duration, +}; use tracing::{debug, info}; use twilight_cache_inmemory::InMemoryCache; use twilight_gateway::{ @@ -15,11 +15,7 @@ use twilight_gateway::{ Event, Intents, Shard, }; use twilight_http::Client as HttpClient; -use twilight_model::{ - channel::Message, - gateway::payload::incoming::MessageCreate, - id::{marker::GuildMarker, Id}, -}; +use twilight_model::channel::Message; use twilight_standby::Standby; type State = Arc; @@ -28,7 +24,6 @@ type State = Arc; struct StateRef { http: HttpClient, cache: InMemoryCache, - trackdata: RwLock, TrackHandle>>, songbird: Songbird, standby: Standby, } @@ -83,7 +78,6 @@ async fn main() -> Result<(), Box> { Arc::new(StateRef { http, cache, - trackdata: Default::default(), songbird, standby: Standby::new(), }), @@ -120,11 +114,8 @@ async fn main() -> Result<(), Box> { match msg.content.split(' ').next() { Some("!join") => spawn(join(msg.0, Arc::clone(&state))), Some("!leave") => spawn(leave(msg.0, Arc::clone(&state))), - Some("!pause") => spawn(pause(msg.0, Arc::clone(&state))), Some("!play") => spawn(play(msg.0, Arc::clone(&state))), - Some("!seek") => spawn(seek(msg.0, Arc::clone(&state))), Some("!stop") => spawn(stop(msg.0, Arc::clone(&state))), - Some("!volume") => spawn(volume(msg.0, Arc::clone(&state))), _ => continue, } } @@ -185,7 +176,6 @@ async fn play(msg: Message, state: State) -> Result<(), Box Result<(), Box Duration { + if duration.as_secs() > 5 { + duration.sub(Duration::from_secs(5)) + } else { + duration + } + }), + ); } } else { state @@ -219,118 +215,6 @@ async fn play(msg: Message, state: State) -> Result<(), Box0]/bestaudio/best", // select best quality audio-only - // "-R", - // "infinite", // infinite number of download retries - // "--no-playlist", // only download the video if URL also has playlist info - // "--ignore-config", // disable all configuration files for a yt-dlp run - // "--no-warnings", // don't print out warnings - // &msg.content, // URL to download - // "-o", - // "-", // stream data to stdout - // ]; - // let output = Command::new("yt-dlp") - // .args(ytdl_args) - // .output() - // .await?; - // let stdout = output.stdout; - - // info!("metadata: {:?}", output.stderr); - - // if let Some(call_lock) = state.songbird.get(guild_id) { - // let mut call = call_lock.lock().await; - // let handle = call.play(stdout.into()); - - // let mut store = state.trackdata.write().await; - // store.insert(guild_id, handle); - // } - - Ok(()) -} - -async fn pause(msg: Message, state: State) -> Result<(), Box> { - tracing::debug!( - "pause command in channel {} by {}", - msg.channel_id, - msg.author.name - ); - - let guild_id = msg.guild_id.unwrap(); - - let store = state.trackdata.read().await; - - let content = if let Some(handle) = store.get(&guild_id) { - let info = handle.get_info().await?; - - let paused = match info.playing { - PlayMode::Play => { - let _success = handle.pause(); - false - } - _ => { - let _success = handle.play(); - true - } - }; - - let action = if paused { "Unpaused" } else { "Paused" }; - - format!("{} the track", action) - } else { - format!("No track to (un)pause!") - }; - - state - .http - .create_message(msg.channel_id) - .content(&content)? - .await?; - - Ok(()) -} - -async fn seek(msg: Message, state: State) -> Result<(), Box> { - tracing::debug!( - "seek command in channel {} by {}", - msg.channel_id, - msg.author.name - ); - state - .http - .create_message(msg.channel_id) - .content("Where in the track do you want to seek to (in seconds)?")? - .await?; - - let author_id = msg.author.id; - let msg = state - .standby - .wait_for_message(msg.channel_id, move |new_msg: &MessageCreate| { - new_msg.author.id == author_id - }) - .await?; - let guild_id = msg.guild_id.unwrap(); - let position = msg.content.parse::()?; - - let store = state.trackdata.read().await; - - let content = if let Some(handle) = store.get(&guild_id) { - let _success = handle.seek(std::time::Duration::from_secs(position)); - format!("Seeking to {}s", position) - } else { - format!("No track to seek over!") - }; - - state - .http - .create_message(msg.channel_id) - .content(&content)? - .await?; Ok(()) } @@ -346,7 +230,7 @@ async fn stop(msg: Message, state: State) -> Result<(), Box Result<(), Box Result<(), Box> { - tracing::debug!( - "volume command in channel {} by {}", - msg.channel_id, - msg.author.name - ); - state - .http - .create_message(msg.channel_id) - .content("What's the volume you want to set (0.0-10.0, 1.0 being the default)?")? - .await?; - - let author_id = msg.author.id; - let msg = state - .standby - .wait_for_message(msg.channel_id, move |new_msg: &MessageCreate| { - new_msg.author.id == author_id - }) - .await?; - let guild_id = msg.guild_id.unwrap(); - let volume = msg.content.parse::()?; - - if !volume.is_finite() || volume > 10.0 || volume < 0.0 { - state - .http - .create_message(msg.channel_id) - .content("Invalid volume!")? - .await?; - - return Ok(()); - } - - let store = state.trackdata.read().await; - - let content = if let Some(handle) = store.get(&guild_id) { - let _success = handle.set_volume(volume as f32); - format!("Set the volume to {}", volume) - } else { - format!("No track to change volume!") - }; - - state - .http - .create_message(msg.channel_id) - .content(&content)? - .await?; - - Ok(()) -}