Refactor AudioManager Lifecycle & Architecture #51

Closed
opened 2026-05-15 15:28:16 +00:00 by FrauJulian · 0 comments
FrauJulian commented 2026-05-15 15:28:16 +00:00 (Migrated from github.com)

Refactor AudioManager Lifecycle & Architecture

Goal

Make AudioManager stable, testable and maintainable by separating Discord voice connection handling, ffmpeg process management, audio playback control and lifecycle cleanup.

Problem

AudioManager currently owns too many responsibilities:

  • Discord voice connection creation
  • ffmpeg process spawning
  • PCM stream handling
  • AudioResource creation
  • AudioPlayer creation
  • renewal timer handling
  • cleanup/dispose logic

This makes the class fragile in reconnect, error and dispose scenarios, especially for 24/7 audio playback.

Scope

  • Split internal responsibilities into smaller components:
    • VoiceConnectionService
    • FfmpegStreamFactory
    • AudioPlayerController
    • RenewalScheduler
  • Improve ffmpeg lifecycle:
    • terminate process cleanly
    • handle stderr, error, and exit
    • avoid zombie processes
  • Consolidate StopConnection() and Dispose() cleanup behavior.
  • Remove non-null assertions from AudioManager.
  • Reuse AudioPlayer instead of recreating it on each play call.
  • Introduce a clear internal state model.
  • Add unit tests for lifecycle behavior.

Acceptance Criteria

  • Build passes.
  • Lint passes.
  • Tests exist and pass.
  • StopConnection() cleans up ffmpeg and streams.
  • Dispose() is idempotent.
  • No empty catch {} blocks remain.
  • No non-null assertions remain in AudioManager.
  • Existing public API remains compatible.
## Refactor AudioManager Lifecycle & Architecture ### Goal Make `AudioManager` stable, testable and maintainable by separating Discord voice connection handling, ffmpeg process management, audio playback control and lifecycle cleanup. ### Problem `AudioManager` currently owns too many responsibilities: - Discord voice connection creation - ffmpeg process spawning - PCM stream handling - AudioResource creation - AudioPlayer creation - renewal timer handling - cleanup/dispose logic This makes the class fragile in reconnect, error and dispose scenarios, especially for 24/7 audio playback. ### Scope - Split internal responsibilities into smaller components: - `VoiceConnectionService` - `FfmpegStreamFactory` - `AudioPlayerController` - `RenewalScheduler` - Improve ffmpeg lifecycle: - terminate process cleanly - handle `stderr`, `error`, and `exit` - avoid zombie processes - Consolidate `StopConnection()` and `Dispose()` cleanup behavior. - Remove non-null assertions from `AudioManager`. - Reuse `AudioPlayer` instead of recreating it on each play call. - Introduce a clear internal state model. - Add unit tests for lifecycle behavior. ### Acceptance Criteria - Build passes. - Lint passes. - Tests exist and pass. - `StopConnection()` cleans up ffmpeg and streams. - `Dispose()` is idempotent. - No empty `catch {}` blocks remain. - No non-null assertions remain in `AudioManager`. - Existing public API remains compatible.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: fraujulian/Discord-Audio-Stream#51