检测和响应音频的状态变化

从 Windows 10 版本 1803 开始,应用可检测到系统何时降低或静音应用使用的音频流的音频级别。 可以接收捕获和呈现流、特定音频设备和音频类别或应用用于媒体播放的 MediaPlayer 对象的通知。 例如,当警报响起时,系统可能降低(或者“闪避”)音频播放级别。 如果应用没有在应用清单中声明 backgroundMediaPlayback 功能,系统将在应用进入后台时将其静音。

对于所有受支持的音频流,处理音频状态更改的模式是相同的。 首先,创建 AudioStateMonitor 类的实例。 在以下示例中,应用使用 MediaCapture 类捕获游戏聊天的音频。 调用工厂方法以获取与默认通信设备的游戏聊天音频捕获流相关联的音频状态监视器。 接下来,为 SoundLevelChanged 事件注册处理程序,这将在系统更改关联流的音频级别时引发。

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

在 SoundLevelChanged 事件处理程序中,查看传入处理程序的 AudioStateMonitor 发件人的 SoundLevel 属性,以确定流的新音频级别。 在此示例中,声音级别为静音时应用停止捕获音频,音频级别返回到完整音量时恢复捕获。

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;
    }
}

有关使用 MediaCapture 捕获音频的详细信息,请参阅使用 MediaCapture 捕获基本的照片、视频和音频

MediaPlayer 类的每个实例都具有与它相关联的 AudioStateMonitor,可用于检测系统何时更改当前播放的内容的音量级别。 根据正在播放内容的类型,可以决定以不同的方式处理音频状态更改。 例如,可以决定在音频降低时暂停播客的播放,但如果内容是音乐,则继续播放。

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;
        }
    }

}

有关使用 MediaPlayer 的详细信息,请查阅使用 MediaPlayer 播放音频和视频