From fc5e0f48477366641b97efb0541053cc1e061be5 Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 27 Oct 2026 18:14:07 +0100 Subject: music: add per-guild queue with now/next/last, skip and queue Tracks are queued in memory per guild, defaulting to append (last). Playback auto-advances on TrackEvent::End/Error with a per-track token so manual stops and skips cannot double-advance. /music queue shows the current track followed by pending items. /stop clears the queue. Cron audio now goes through the same MusicState instead of poking the track-handle map directly. --- src/main.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index df40481..4e308b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod database; mod error; mod events; mod lang; +mod music; mod openrouter; mod recording; mod tasks; @@ -49,8 +50,8 @@ pub struct Data { /// Populated by background tasks when the first search times out, so the /// next keystroke's autocomplete can serve real results immediately. pub ac_search_cache: AcSearchCache, - /// Active music track per guild (only one music source at a time). - pub music_tracks: Arc>>, + /// Active music queue and current track per guild. + pub music: Arc, /// TTS engine: piper model + audio cache. pub tts: Arc, } @@ -198,7 +199,11 @@ async fn main() -> Result<(), Box> { ) .await?; - let music_tracks: Arc>> = Arc::new(tokio::sync::Mutex::new(HashMap::new())); + let music = music::MusicState::new( + vm.clone(), + ctx.http.clone(), + http_client.clone(), + ); let tts = Arc::new(tts::TtsState::new(config.piper_model_path())); @@ -213,7 +218,7 @@ async fn main() -> Result<(), Box> { triggers: tokio::sync::Mutex::new(triggers), ac_cache: tokio::sync::Mutex::new(HashMap::new()), ac_search_cache: Arc::new(tokio::sync::Mutex::new(HashMap::new())), - music_tracks: music_tracks.clone(), + music, }; // Spawn cron scheduler loop. @@ -221,9 +226,8 @@ async fn main() -> Result<(), Box> { let cron_ctx = crate::tasks::CronContext { pool: data.db_pool.clone(), http: ctx.http.clone(), - voice_manager: data.voice_manager.clone(), copyparty: data.copyparty.clone(), - music_tracks: music_tracks.clone(), + music: data.music.clone(), }; tokio::spawn(async move { crate::tasks::cron_scheduler_loop(cron_ctx).await; -- cgit v1.2.3