Detect and respond to audio state changes

Starting with Windows 10, version 1803, your app can detect when the system lowers or mutes the audio level of an audio stream your app is using. You can receive notifications for capture and render streams, for a particular audio device and audio category, or for a MediaPlayer object your app is using for media playback. For example, the system may lower, or "duck", the audio playback level when an alarm is ringing. The system will mute your app when it goes into the background if your app has not declared the backgroundMediaPlayback capability in the app manifest.

The pattern for handling audio state changes is the same for all supported audio streams. First, create an instance of the AudioStateMonitor class. In the following example, the app is using the MediaCapture class to capture audio for game chat. A factory method is called to get an audio state monitor associated with the game chat audio capture stream of the default communications device. Next, a handler is registered for the SoundLevelChanged event, which will be raised when the audio level for the associated stream is changed by the system.

AudioStateMonitor gameChatAudioStateMonitor;
string deviceId = Windows.Media.Devices.MediaDevice.GetDefaultAudioCaptureId(Windows.Media.Devices.AudioDeviceRole.Communications);
gameChatAudioStateMonitor = AudioStateMonitor.CreateForCaptureMonitoringWithCategoryAndDeviceId(MediaCategory.GameChat, deviceId);
gameChatAudioStateMonitor.SoundLevelChanged += GameChatSoundLevelChanged;

In the SoundLevelChanged event handler, check the SoundLevel property of the AudioStateMonitor sender passed into the handler to determine what the new audio level for the stream is. In this example, the app stops capturing audio when the sound level is muted and resumes capturing when the audio level returns to full volume.

private void GameChatSoundLevelChanged(AudioStateMonitor sender, object args)
{
    switch (sender.SoundLevel)
    {
        case SoundLevel.Full:
            StartAudioCapture();
            break;
        case SoundLevel.Muted:
            StopAudioCapture();
            break;
        case SoundLevel.Low:
            // Audio capture should never be "ducked", only muted or full volume.
            Debug.WriteLine("Unexpected audio state change.");
            break;
    }
}

For more information on capturing audio with MediaCapture, see Basic photo, video, and audio capture with MediaCapture.

Every instance of the MediaPlayer class has an AudioStateMonitor associated with it that you can use to detect when the system changes the volume level of the content currently being played. You may decide to handle audio state changes differently depending on what type of content is being played. For example, you may decide to pause playback of a podcast when the audio is lowered, but continue playback if the content is music.

bool isPodcast;
bool isPausedDueToAudioStateMonitor;
private void AudioStateMonitor_SoundLevelChanged(Windows.Media.Audio.AudioStateMonitor sender, object args)
{
    if ((sender.SoundLevel == SoundLevel.Full) || (sender.SoundLevel == SoundLevel.Low && !isPodcast))
    {
        if (isPausedDueToAudioStateMonitor)
        {
            mediaPlayer.Play();
            isPausedDueToAudioStateMonitor = false;
        }
    }
    else if ((sender.SoundLevel == SoundLevel.Muted) ||
         (sender.SoundLevel == SoundLevel.Low && isPodcast))
    {
        if (mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.Playing)
        {
            mediaPlayer.Pause();
            isPausedDueToAudioStateMonitor = true;
        }
    }

}

For more information on using MediaPlayer, see Play audio and video with MediaPlayer.