|
@@ -12,8 +12,10 @@ use songbird::{
|
|
|
tracks::{TrackCommand, TrackHandle},
|
|
|
Call, Event, EventContext, EventHandler as VoiceEventHandler, TrackEvent,
|
|
|
};
|
|
|
+use std::time::Duration;
|
|
|
use std::{mem::drop, sync::Arc};
|
|
|
use tokio::sync::Mutex;
|
|
|
+use tokio::time::sleep;
|
|
|
|
|
|
pub struct AudioState {
|
|
|
queue: SongQueue,
|
|
@@ -39,12 +41,18 @@ impl AudioState {
|
|
|
http: Mutex::new(ctx.http.clone()),
|
|
|
};
|
|
|
let audio_state = Arc::new(audio_state);
|
|
|
- {
|
|
|
- let audio_state = audio_state.clone();
|
|
|
- tokio::spawn(async {
|
|
|
- AudioState::play_audio(audio_state).await;
|
|
|
- });
|
|
|
- }
|
|
|
+ let my_audio_state = audio_state.clone();
|
|
|
+ tokio::spawn(async move {
|
|
|
+ // Leave if no music is playing within 1 minute
|
|
|
+ sleep(Duration::from_secs(60)).await;
|
|
|
+ let current_song = my_audio_state.current_song.lock().await;
|
|
|
+ if current_song.is_none() {
|
|
|
+ let mut handler = my_audio_state.handler.lock().await;
|
|
|
+ if let Err(e) = handler.leave().await {
|
|
|
+ println!("Automatic leave failed: {:?}", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
audio_state
|
|
|
}
|
|
|
|
|
@@ -63,14 +71,23 @@ impl AudioState {
|
|
|
let is_looping = audio_state.is_looping.lock().await;
|
|
|
let song = if *is_looping {
|
|
|
let mut current_song = audio_state.current_song.lock().await;
|
|
|
- current_song
|
|
|
- .take()
|
|
|
- .expect("logical error: expected current_song to be non-empty")
|
|
|
+ current_song.take()
|
|
|
} else {
|
|
|
audio_state.queue.pop().await
|
|
|
};
|
|
|
drop(is_looping);
|
|
|
|
|
|
+ let song = match song {
|
|
|
+ Some(song) => song,
|
|
|
+ None => {
|
|
|
+ let mut handler = audio_state.handler.lock().await;
|
|
|
+ if let Err(e) = handler.leave().await {
|
|
|
+ println!("Error leaving channel: {:?}", e);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
let source = ffmpeg_pcm(&song.url).await;
|
|
|
let source = match source {
|
|
|
Ok(source) => source,
|
|
@@ -120,6 +137,13 @@ impl AudioState {
|
|
|
}
|
|
|
};
|
|
|
audio_state.queue.push(vec![song]).await;
|
|
|
+ let current_song = audio_state.current_song.lock().await;
|
|
|
+ if current_song.is_none() {
|
|
|
+ let audio_state = audio_state.clone();
|
|
|
+ tokio::spawn(async {
|
|
|
+ AudioState::play_audio(audio_state).await;
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
pub async fn send_track_command(
|
|
@@ -155,22 +179,6 @@ impl AudioState {
|
|
|
let mut is_looping = audio_state.is_looping.lock().await;
|
|
|
*is_looping = !*is_looping;
|
|
|
Ok(*is_looping)
|
|
|
- /*
|
|
|
- if looping{
|
|
|
- if *is_looping{
|
|
|
- Err("already looping".to_string())
|
|
|
- }else{
|
|
|
- *is_looping = true;
|
|
|
- Ok(())
|
|
|
- }
|
|
|
- }else{
|
|
|
- if !*is_looping{
|
|
|
- Err("not looping at the moment".to_string())
|
|
|
- }else{
|
|
|
- *is_looping = false;
|
|
|
- Ok(())
|
|
|
- }
|
|
|
- }*/
|
|
|
}
|
|
|
|
|
|
pub async fn get_string(audio_state: Arc<AudioState>) -> String {
|