PooledPlayback mixin
PooledPlayback
Opt-in audio pooling for instant retrigger/overlap of short sounds. Intended for SFX-style channels that often replay the same clip rapidly.
What it does
- Keeps a tiny pool of pre-prepared
AudioPlayers per sound key. - Inherits the channel’s
AudioContextso focus/ducking rules match. - Supports assets, device files, URLs, and bytes sources.
- Automatically marks the channel as multi-player capable, so
BaseAudioChannel.waitUntilStopped()/playAndWait()will throw (waiting is ambiguous when multiple players can run).
Typical usage
class SfxChannel extends BaseAudioChannel with PooledPlayback {
SfxChannel() : super('sfx_player');
@override PlayerMode get playerMode => PlayerMode.lowLatency;
@override ReleaseMode get releaseMode => ReleaseMode.stop;
// Make pooling transparent for .play(path)
@override
Future<void> play(String path) async {
await playPooledPath(path, key: path, volume: volume);
}
@override
Future<void> dispose() async {
await disposePools(); // ← clean pooled players
return super.dispose();
}
}
// Configure pooling (optional; defaults shown)
SoundEngine.instance.sfx.enablePooling(
enabled: true,
poolSizePerSound: 4, // max concurrent players for a given sound
minPlayersPerSound: 1, // pre-warmed instances per sound
);
// Fire-and-forget retriggers (instant overlaps)
await SoundEngine.instance.sfx.play('assets/sfx/click.mp3');
When to refresh pools
If you change a channel’s AudioContext after some pools were built,
call refreshPoolsAudioContext to recreate existing pools with the new
context:
await sfx.setAudioContext(newCtx);
await sfx.refreshPoolsAudioContext();
Waiting caveat
Pooling enables concurrent playbacks; a single “wait until stop” has no
unambiguous target. The mixin reports concurrency via
hasMultipleConcurrentPlayers, so waitUntilStopped / playAndWait will
throw UnsupportedError. If you need blocking behavior, disable pooling
(globally or for the duration) or use a dedicated non-pooled channel.
- Superclass constraints
- Mixin applications
Properties
- currentAudioContext → AudioContext?
-
Current audio context getter (nullable if never set).
no setterinherited
- hashCode → int
-
The hash code for this object.
no setterinherited
- hasMultipleConcurrentPlayers → bool
-
Report concurrency to the base so wait-helpers throw automatically.
no setteroverride
- isActive → bool
-
Active Flag
no setterinherited
- isMuted → bool
-
Muted Flag
no setterinherited
- isPlaying → bool
-
Current Status
no setterinherited
- isPoolingEnabled → bool
-
Whether pooling is currently enabled.
no setter
- minPlayersPerSound → int
-
Pre-warmed players per sound key.
no setter
-
onDurationChanged
→ Stream<
Duration> -
Duration Stream
no setterinherited
-
onIsPlayingChanged
→ Stream<
bool> -
Reactive
isPlayingStreamno setterinherited -
onPlayerComplete
→ Stream<
void> -
Completion Event
no setterinherited
-
onPositionChanged
→ Stream<
Duration> -
Position Stream
no setterinherited
- playerId → String
-
Stable Identifier
finalinherited
- playerMode → PlayerMode
-
Player Mode
no setterinherited
- poolSizePerSound → int
-
Maximum concurrent players per sound key.
no setter
- releaseMode → ReleaseMode
-
Release Mode
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- volume → double
-
Current Volume (0.0 → 1.0)
no setterinherited
Methods
-
activate(
) → void -
Activate
inherited
-
changeSource(
AudioSourceBuilder builder) → void -
Swap Loader
inherited
-
deactivate(
) → void -
Deactivate
inherited
-
disableLifecycle(
) → void -
Disable lifecycle handling for this channel.
inherited
-
dispose(
) → Future< void> -
Dispose
inherited
-
disposePools(
) → Future< void> - Dispose all pools.
-
enableLifecycle(
[ChannelLifecycleConfig cfg = const ChannelLifecycleConfig()]) → void -
Enable per-channel lifecycle handling
inherited
-
enablePooling(
{bool enabled = true, int poolSizePerSound = 4, int minPlayersPerSound = 1}) → void - Enable/disable pooling and configure pool sizes.
-
ensureWaitSupported(
String methodName) → void -
Throws if waiting semantics are unsupported for this channel.
inherited
-
fadeIn(
{Duration duration = const Duration(seconds: 2), Curve curve = Curves.easeInOut}) → Future< void> -
Fade In
inherited
-
fadeInVolume(
FadePreset preset) → Future< void> -
Helper: Fade In via FadePreset
inherited
-
fadeOut(
{Duration duration = const Duration(seconds: 2), Curve curve = Curves.easeOut}) → Future< void> -
Fade Out
inherited
-
fadeOutVolume(
FadePreset preset) → Future< void> -
Helper: Fade Out via FadePreset
inherited
-
fadeTo(
double targetVolume, {Duration duration = const Duration(seconds: 2), Curve curve = Curves.linear}) → Future< void> -
Fade To Target Volume
inherited
-
getDuration(
) → Future< Duration?> -
Current Media Duration
inherited
-
mute(
) → Future< void> -
Mute (volume → 0.0)
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
onStateChanged(
PlayerState state) → void -
Subclass Hook: Player State Changed
inherited
-
pause(
) → Future< void> -
Pause
inherited
-
play(
String path) → Future< void> -
Play by Path
inherited
-
playAndWait(
String path, {Duration startTimeout = const Duration(seconds: 3), Duration timeout = const Duration(minutes: 2), bool forceStopOnTimeout = true}) → Future< bool> -
Convenience: play a path and wait for completion/stop
inherited
-
playFromSource(
Source source) → Future< void> -
Play from Source
inherited
-
playFromSourceAndWait(
Source source, {Duration startTimeout = const Duration(seconds: 3), Duration timeout = const Duration(minutes: 2), bool forceStopOnTimeout = true}) → Future< bool> -
Convenience: play a Source and wait for completion/stop
inherited
-
playPooled(
String key, Source source, {double? volume}) → Future< StopFunction?> - Play using a pooled player (or fallback to the single channel player).
-
playPooledPath(
String path, {String? key, double? volume}) → Future< StopFunction?> -
Play a path using pooling, resolving the path with the channel’s
current loader (respects
changeSource(...)). -
refreshPoolsAudioContext(
) → Future< void> -
Rebuild all pools so they inherit the channel’s current
AudioContext. Useful after callingsetAudioContext(...)at runtime. -
resolveSource(
String path) → Source -
Resolve a path into a Source using the current builder (assets/files/urls).
Override via changeSource to switch the strategy at runtime.
inherited
-
resume(
) → Future< void> -
Resume
inherited
-
seek(
Duration position) → Future< void> -
Seek
inherited
-
setAudioContext(
AudioContext audioContext) → Future< void> -
Apply Platform Audio Context
inherited
-
setVolume(
double volume) → Future< void> -
Set Volume
inherited
-
stop(
) → Future< void> -
Stop
inherited
-
toggleActive(
) → void -
Toggle Active
inherited
-
toString(
) → String -
A string representation of this object.
inherited
-
unmute(
) → Future< void> -
Unmute (volume → 1.0)
inherited
-
waitUntilStarted(
{Duration timeout = const Duration(seconds: 3)}) → Future< bool> -
Wait until playback starts (first
true)inherited -
waitUntilStopped(
{Duration startTimeout = const Duration(seconds: 3), Duration timeout = const Duration(minutes: 2), bool forceStopOnTimeout = true}) → Future< bool> -
Wait until playback stops/completes
inherited
-
withFade(
Future< void> action(), {FadePreset fadeOut = FadePreset.fast, FadePreset fadeIn = FadePreset.normal}) → Future<void> -
withFade
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited