loading
Note:
Getting the type right is most of the value Without a declared type the browser guesses, and a guess that treats a UI click like a podcast silences whatever the user was listening to. Ambient for effects, Playback for content the user came for, TransientSolo for something that must be heard alone.
Warning:
Early, and Chromium only Elsewhere IsSupported is false and every call is a no-op.

Support check

IsSupported

True when the runtime exposes navigator.audioSession. During prerender/SSR the check returns false rather than throwing.

C#
@inject Bit.Butil.AudioSession audioSession

var supported = await audioSession.IsSupported();
Live sample
support check output
Results will appear here when you interact with the samples.

Declare the intent

GetSessionType / SetSessionType

Set it before playback starts - changing it mid-playback can make the OS re-evaluate the routing audibly. Playback interrupts other audio and survives the ringer switch; Ambient mixes with other audio and obeys it; Transient ducks other audio briefly; TransientSolo pauses it.

C#
// game sound effects: never silence the user's music
await audioSession.SetSessionType(AudioSessionType.Ambient);

// a video the user chose to watch
await audioSession.SetSessionType(AudioSessionType.Playback);
Live sample
session type output
Results will appear here when you interact with the samples.

Notice interruptions

GetState / OnStateChange

The case worth handling is Interrupted going back to Active: a phone call or another app took the audio, playback stopped, and the browser will not resume it for you. Fires once immediately with the current state. Dispose the returned subscription.

C#
_sub = await audioSession.OnStateChange(state =>
{
    if (state == AudioSessionState.Interrupted) PauseUi();
    if (state == AudioSessionState.Active && _wasInterrupted) Resume();
    InvokeAsync(StateHasChanged);
});
Live sample
state output
Results will appear here when you interact with the samples.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes navigator.audioSession.
GetSessionType
ValueTask<AudioSessionType> GetSessionType()
The type currently declared, or Unknown without the API.
SetSessionType
ValueTask<bool> SetSessionType(AudioSessionType type)
Declares what this page's audio is for. False when the runtime has no audio session.
GetState
ValueTask<AudioSessionState> GetState()
Whether the session currently holds the audio focus.
OnStateChange
Task<ButilSubscription> OnStateChange(Action<AudioSessionState> handler)
Watches the session's state, and fires once immediately with the current one.
DisposeAsync
ValueTask DisposeAsync()
Detaches every listener registered through this instance and releases its interop reference.
An unhandled error has occurred. Reload 🗙