Browse Source

adding feature: bot sends an embed when a new song starts playing

Zhizhou Ma 3 years ago
parent
commit
7528227fa7
6 changed files with 77 additions and 17 deletions
  1. 1 1
      .spotify_token_cache.json
  2. 7 3
      src/audio/audio.rs
  3. 41 7
      src/audio/audio_state.rs
  4. 4 0
      src/audio/config.rs
  5. 1 5
      src/util/mod.rs
  6. 23 1
      src/util/util.rs

+ 1 - 1
.spotify_token_cache.json

@@ -1 +1 @@
-{"access_token":"BQAniTN-wEbdSkII6q4VyxilAvCembgGe03hLmElnTWYJfKbdmTPWu_e0rEqq3_6iWTzzt7dHpg1XlzInC0","expires_in":3600,"expires_at":"2021-06-23T18:29:14.432292300Z","refresh_token":null,"scope":""}
+{"access_token":"BQCzWaEY5LFBxCi-tRIfsHHbfIVzYxWCuJ_AXhcr2Wm95svCPAVSbBBysnw62Ain9vObQGOeD6dIki_K36s","expires_in":3600,"expires_at":"2021-06-23T19:21:06.445574Z","refresh_token":null,"scope":""}

+ 7 - 3
src/audio/audio.rs

@@ -19,6 +19,8 @@ use super::{
     audio_state::AudioState,
 };
 
+use super::config::audio as config_audio;
+
 use crate::util::{
     send_message,
     send_embed,
@@ -43,7 +45,9 @@ async fn get_audio_state(ctx: &Context, msg: &Message) -> Option<Arc<AudioState>
 
     match audio_states.get(&guild_id) {
         Some(state) => {
-            Some(state.clone())
+            let state = state.clone();
+            AudioState::set_context(state.clone(), ctx, msg).await;
+            Some(state)
         }
         None => {
             let channel_id = guild
@@ -66,7 +70,7 @@ async fn get_audio_state(ctx: &Context, msg: &Message) -> Option<Arc<AudioState>
                 println!("Error: {:?}", err);
                 return None;
             }
-            let audio_state = AudioState::new(handle_lock);
+            let audio_state = AudioState::new(handle_lock, ctx, msg);
             {
                 audio_states.insert(guild_id, audio_state.clone());
             }
@@ -187,7 +191,7 @@ async fn extend(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult{
     let extend_ratio = match args.single::<f64>(){
         Ok(amount) => amount,
         Err(_) => {
-            0.5
+            config_audio::EXTEND_RATIO
         }
     };
 

+ 41 - 7
src/audio/audio_state.rs

@@ -14,6 +14,7 @@ use super::{
     },
     subprocess::ffmpeg_pcm,
 };
+use crate::util::send_embed_http;
 use songbird::{Call, Event, EventContext, EventHandler as VoiceEventHandler, TrackEvent, 
     input::{
         self,
@@ -30,7 +31,13 @@ use serenity::{
     async_trait,
     prelude::{
         Mutex as SerenityMutex,
-    }
+    },
+    http::Http,
+    client::Context,
+    model::{
+        id::ChannelId,
+        channel::Message,
+    },
 };
 
 pub struct AudioState{
@@ -39,16 +46,22 @@ pub struct AudioState{
     current_song: Mutex<Option<Song>>,
     track_handle: Mutex<Option<TrackHandle>>,
     is_looping: Mutex<bool>,
+
+    channel_id: Mutex<ChannelId>,
+    http: Mutex<Arc<Http>>,
 }
 
 impl AudioState{
-    pub fn new(handler: Arc<SerenityMutex<Call>>) -> Arc<AudioState>{
+    pub fn new(handler: Arc<SerenityMutex<Call>>, ctx: &Context, msg: &Message) -> Arc<AudioState>{
         let audio_state = AudioState{
             queue: SongQueue::new(),
             handler,
             current_song: Mutex::new(None),
             track_handle: Mutex::new(None),
             is_looping: Mutex::new(false),
+
+            channel_id: Mutex::new(msg.channel_id),
+            http: Mutex::new(ctx.http.clone()),
         };
         let audio_state = Arc::new(audio_state);
         {
@@ -60,6 +73,17 @@ impl AudioState{
         audio_state
     }
 
+    pub async fn set_context(audio_state: Arc<AudioState>, ctx: &Context, msg: &Message){
+        {
+            let mut channel_id = audio_state.channel_id.lock().await;
+            *channel_id = msg.channel_id;
+        }
+        {
+            let mut http = audio_state.http.lock().await;
+            *http = ctx.http.clone();
+        }
+    }
+
     async fn play_audio(audio_state: Arc<AudioState>){
         let is_looping = audio_state.is_looping.lock().await;
         let mut song = if *is_looping{
@@ -70,6 +94,7 @@ impl AudioState{
         };
         drop(is_looping);
 
+        
         let url = song.get_url().await;
         let source = ffmpeg_pcm(url).await;
         let source = match source {
@@ -94,11 +119,20 @@ impl AudioState{
         ){
             panic!("Err AudioState::play_audio: {:?}", why);
         }
-        
-        let mut current_song = audio_state.current_song.lock().await;
-        *current_song = Some(song);
-        let mut track_handle = audio_state.track_handle.lock().await;
-        *track_handle = Some(handle);
+        {
+            let text = song.get_string().await;
+            let channel_id = audio_state.channel_id.lock().await;
+            let http = audio_state.http.lock().await;
+            send_embed_http(*channel_id, http.clone(), &format!(
+                "Now playing:\n\n {}", text
+            )).await;
+        }
+        {
+            let mut current_song = audio_state.current_song.lock().await;
+            *current_song = Some(song);
+            let mut track_handle = audio_state.track_handle.lock().await;
+            *track_handle = Some(handle);
+        }
     }
 
     pub async fn add_audio(audio_state: Arc<AudioState>, query: &str, shuffle: bool){

+ 4 - 0
src/audio/config.rs

@@ -4,3 +4,7 @@ pub mod spotify_recommend {
     pub const EXPLORE_ARTIST: u32 = 1;
     pub const EXPLORE_ALBUM: u32 = 0;
 }
+
+pub mod audio {
+    pub const EXTEND_RATIO: f64 = 1.5;
+}

+ 1 - 5
src/util/mod.rs

@@ -1,7 +1,3 @@
 pub mod util;
 
-pub use util::{
-    send_message,
-    send_embed,
-    message_react,
-};
+pub use util::*;

+ 23 - 1
src/util/util.rs

@@ -1,8 +1,15 @@
 use serenity::{
     client::Context, 
-    model::{channel::Message, prelude::ReactionType}
+    model::{
+        channel::Message, 
+        prelude::ReactionType,
+        id::ChannelId,
+    },
+    http::Http,
 };
 
+use std::sync::Arc;
+
 pub async fn send_message(ctx: &Context, msg: &Message, text: &str){
     let res = msg.channel_id.send_message(&ctx.http, |m| {
         m.content(text);
@@ -27,6 +34,21 @@ pub async fn send_embed(ctx: &Context, msg: &Message, text: &str){
     };
 }
 
+pub async fn send_embed_http(channel_id: ChannelId, http: Arc<Http>, text: &str){
+    let res = channel_id.send_message(http, |m| {
+        m.embed(|e| {
+            e.colour(0xf542bf);
+            e.description(text);
+            e
+        });
+        m
+    }).await;
+
+    if let Err(why) = res{
+        println!("Error sending embed: {:?}", why);
+    };
+}
+
 pub async fn message_react(ctx: &Context, msg: &Message, emoji: &str){
     let res = msg.react(&ctx.http, ReactionType::Unicode(emoji.to_string())).await;
     if let Err(why) = res{