与系统媒体传输控件集成

本文介绍如何与系统媒体传输控件(SMTC)交互。 SMTC 是所有 Windows 10 设备通用的一组控件,为用户提供一致的方式来控制所有使用 MediaPlayer 播放的正在运行的应用的媒体播放。

系统媒体传输控件使媒体应用程序开发人员能够与内置系统 UI 集成以显示媒体元数据,例如艺术家、专辑标题或章节标题。 系统传输控件还允许用户使用内置系统 UI 控制媒体应用的播放,例如暂停播放以及在播放列表中向前和向后跳过。

系统媒体转网控件

有关演示如何与 SMTC 集成的完整示例,请参阅 github 上的系统媒体传输控件示例。

与 SMTC 自动集成

从 Windows 10 版本 1607 开始,使用 MediaPlayer 类播放媒体的 UWP 应用默认情况下会自动与 SMTC 集成。 只需实例化 MediaPlayer 的新实例,并将 MediaSourceMediaPlaybackItem MediaPlaybackList 分配给玩家的 Source 属性,用户即可在 SMTC 中看到应用名称,并且可以使用 SMTC 控件播放、暂停和移动播放列表。

你的应用可以一次性创建和使用多个 MediaPlayer 对象。 对于应用中的每个活动 MediaPlayer 实例,在 SMTC 中创建一个单独的选项卡,允许用户在活动媒体播放器和其他正在运行的应用之间切换。 在 SMTC 中当前选择哪个媒体播放器是控件会影响的播放器。

有关在应用中使用 MediaPlayer 的详细信息,包括将其绑定到 XAML 页面中的 MediaPlayerElement,请参阅使用 MediaPlayer 播放音频和视频。

有关使用 MediaSource、MediaPlaybackItemMediaPlaybackList 的详细信息,请参阅媒体项、播放列表和曲目

添加要由 SMTC 显示的元数据

如果要添加或修改 SMTC 中媒体项显示的元数据(如视频或歌曲标题),则需要更新表示媒体项的 MediaPlaybackItem 的显示属性。 首先,通过调用 GetDisplayProperties 获取对 MediaItemDisplayProperties 对象的引用。 接下来,使用 Type 属性设置项的媒体、音乐或视频类型。 然后,可以根据指定的媒体类型填充 MusicProperties VideoProperties 的字段。 最后,通过调用 ApplyDisplayProperties 更新媒体项的元数据。

MediaItemDisplayProperties props = mediaPlaybackItem.GetDisplayProperties();
props.Type = Windows.Media.MediaPlaybackType.Video;
props.VideoProperties.Title = "Video title";
props.VideoProperties.Subtitle = "Video subtitle";
props.VideoProperties.Genres.Add("Documentary");
mediaPlaybackItem.ApplyDisplayProperties(props);
props = mediaPlaybackItem.GetDisplayProperties();
props.Type = Windows.Media.MediaPlaybackType.Music;
props.MusicProperties.Title = "Song title";
props.MusicProperties.Artist = "Song artist";
props.MusicProperties.Genres.Add("Polka");
mediaPlaybackItem.ApplyDisplayProperties(props);

注意

应用程序应该为 Type 属性设置一个值,即使它们没有提供要由系统媒体传输控件显示的其他媒体元数据。 此值有助于系统正确处理媒体内容,包括防止屏幕保护在播放期间激活。

使用 CommandManager 修改或替代默认 SMTC 命令

你的应用可以使用 MediaPlaybackCommandManager 类修改或完全替代 SMTC 控件的行为。 可以通过访问 CommandManager 属性来获取 MediaPlayer 类的每个实例的命令管理器实例

对于每个命令(例如,默认情况下跳到 MediaPlaybackList 中的下一项)命令管理器都会公开接收的事件(如 NextReceived),以及管理命令行为的对象,如 NextBehavior

以下示例为 NextReceived 事件和 NextBehaviorIsEnabledChanged 事件注册处理程序。

_mediaPlayer.CommandManager.NextReceived += CommandManager_NextReceived;
_mediaPlayer.CommandManager.NextBehavior.IsEnabledChanged += NextBehavior_IsEnabledChanged;

以下示例演示了应用希望在用户单击播放列表中的五个项目后禁用 “下一步 ”命令的方案,这可能需要在继续播放内容之前进行一些用户交互。 引发 NextReceived 事件的每个 ## 都会递增一个计数器。 计数器到达目标编号后,“下一步”命令的 EnablingRule 设置为 Never,这会禁用该命令。

int _nextPressCount = 0;
private void CommandManager_NextReceived(MediaPlaybackCommandManager sender, MediaPlaybackCommandManagerNextReceivedEventArgs args)
{
    _nextPressCount++;
    if (_nextPressCount > 5)
    {
        sender.NextBehavior.EnablingRule = MediaCommandEnablingRule.Never;
        // Perform app tasks while the Next button is disabled
    }
}

还可以将命令设置为 “始终”,这意味着即使对于 Next 命令示例,该命令也始终处于启用状态。对于下一 个命令示例,播放列表中没有其他项。 或者,可以将命令设置为 “自动”,其中系统确定是否应根据正在播放的当前内容启用该命令。

对于上述方案,在某些时候,应用需要重新启用“下一步”命令,并通过将“启用Rule”设置为“自动来执行此操作。

_mediaPlayer.CommandManager.NextBehavior.EnablingRule = MediaCommandEnablingRule.Auto;
_nextPressCount = 0;

由于应用在前台时可能具有用于控制播放的自己的 UI,因此你可以使用 IsEnabledChanged 事件更新自己的 UI 以匹配 SMTC,因为通过访问传递给处理程序的 MediaPlaybackCommandManagerCommandBehavior 的 IsEnabled 来启用或禁用命令。

private void NextBehavior_IsEnabledChanged(MediaPlaybackCommandManagerCommandBehavior sender, object args)
{
    MyNextButton.IsEnabled = sender.IsEnabled;
}

在某些情况下,你可能想要完全替代 SMTC 命令的行为。 下面的示例演示了应用使用 NextPrevious 命令在 Internet 广播电台之间切换,而不是在当前播放列表中的曲目之间跳过的情况。 与前面的示例一样,在收到命令时注册处理程序,在本例中 为 PreviousReceived 事件。

_mediaPlayer.CommandManager.PreviousReceived += CommandManager_PreviousReceived;

在 PreviousReceived 处理程序中,首先通过调用传递给处理程序的 MediaPlaybackCommandManagerPreviousReceivedEventArgs 的 GetDeferral 来获取 Deferral。 这会告知系统在执行命令之前等待延迟完成。 如果要在处理程序中进行异步调用,这一点非常重要。 此时,该示例调用一个自定义方法,该方法返回表示上一 电台的 MediaPlaybackItem

接下来, 检查 Handled 属性以确保事件尚未由另一个处理程序处理。 否则, Handled 属性设置为 true。 这样,SMTC 和任何其他订阅的处理程序就知道,它们不应采取任何操作来执行此命令,因为它已被处理。 然后,该代码设置媒体播放器的新源,并启动播放器。

最后, 在延迟对象上调用 Complete ,让系统知道你已完成处理命令。

private async void CommandManager_PreviousReceived(MediaPlaybackCommandManager sender, MediaPlaybackCommandManagerPreviousReceivedEventArgs args)
{
    var deferral = args.GetDeferral();
    MediaPlaybackItem mediaPlaybackItem = await GetPreviousStation();

    if(args.Handled != true)
    {
        args.Handled = true;
        sender.MediaPlayer.Source = mediaPlaybackItem;
        sender.MediaPlayer.Play();
    }
    deferral.Complete();
}

SMTC 的手动控制

如本文前面所述,SMTC 将自动检测和显示应用创建的每个 MediaPlayer 实例的信息。 如果要使用 MediaPlayer多个实例,但希望 SMTC 为应用提供单个条目,则必须手动控制 SMTC 的行为,而不是依赖自动集成。 此外,如果使用 MediaTimelineController 控制一个或多个媒体播放器,则必须使用手动 SMTC 集成。 此外,如果你的应用使用除 MediaPlayer 以外的 API(如 AudioGraph 类)来播放媒体,则必须为用户实现手动 SMTC 集成才能使用 SMTC 来控制应用。 有关如何手动控制 SMTC 的信息,请参阅 系统媒体传输控件的手动控制。