简体   繁体   English

与“系统级”媒体播放器互动

[英]Interact with “system-wide” media player

I want to develop a music app for Windows 10 and I'm curious about the interface provided by Groove Music next to the volume bar. 我想开发一个适用于Windows 10的音乐应用程序,我对卷条旁边的Groove Music提供的界面感到好奇。 I've tried Googling to get more information about it but I haven't had any success whatsoever. 我已经尝试使用Google搜索来获取更多相关信息,但我没有取得任何成功。 When I'm playing music in Groove Music and I raise or lower the volume, the name as well as the artist and album artwork of the current song show up with music controls next to the volume indicator this: 当我在Groove Music中播放音乐并且我提高或降低音量时,当前歌曲的名称以及艺术家和专辑封面显示音量控制器旁边的音量控制器:

屏幕截图

I was wondering how I could create this dialog in my own app and what windows API's I'd have to look into. 我想知道如何在我自己的应用程序中创建此对话框以及我需要查看的Windows API。

You need to use SystemMediaTransportControls 您需要使用SystemMediaTransportControls

Here is a basic setup with Play and Pause. 这是Play和Pause的基本设置。 If you like to enable more controls you can do using the available properties for ex. 如果您想启用更多控件,可以使用ex的可用属性。

systemControls.IsNextEnabled = true;

and you have to add the case in the button switch. 你必须在按钮开关中添加case

case SystemMediaTransportControlsButton.Next:
                    //handle next song
                    break;

xaml XAML

<MediaElement x:Name="mediaElement" Height="100" Width="100" AreTransportControlsEnabled="True"/>

C# C#

public MainPage()
{
    this.InitializeComponent();

    systemControls = SystemMediaTransportControls.GetForCurrentView();

    // Register to handle the following system transpot control buttons.
    systemControls.ButtonPressed += SystemControls_ButtonPressed;

    mediaElement.CurrentStateChanged += MediaElement_CurrentStateChanged;


    systemControls.IsPlayEnabled = true;
    systemControls.IsPauseEnabled = true;
}

private void MediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
{
    switch (mediaElement.CurrentState)
    {
        case MediaElementState.Playing:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Playing;
            break;
        case MediaElementState.Paused:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Paused;
            break;
        case MediaElementState.Stopped:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Stopped;
            break;
        case MediaElementState.Closed:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Closed;
            break;
        default:
            break;
    }
}



void SystemControls_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
{
    switch (args.Button)
    {
        case SystemMediaTransportControlsButton.Play:
            PlayMedia();
            break;
        case SystemMediaTransportControlsButton.Pause:
            PauseMedia();
            break;
        case SystemMediaTransportControlsButton.Stop:
            StopMedia();
            break;
        default:
            break;
    }
}

private async void StopMedia()
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        mediaElement.Stop();
    });
}

async void PlayMedia()
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        if (mediaElement.CurrentState == MediaElementState.Playing)
            mediaElement.Pause();
        else
            mediaElement.Play();
    });
}

async void PauseMedia()
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        mediaElement.Pause();
    });
}

Output 产量

产量

Also if you want all this to work in background you will have to do a Declaration in Package.appxmanifest for a Background Tasks, enable audio and add an entry point like TestUWP.MainPage 此外,如果您希望所有这些在后台工作,您将必须在Package.appxmanifest为后台任务执行声明,启用音频并添加一个入口点,如TestUWP.MainPage

在此输入图像描述

I'm going to add my input to this even though there is a great answer already by @Stamos , because I've found that it is actually possible to use SystemMediaTransportControls from a native windows app (not only a universal app). 即使@Stamos已经有一个很好的答案,我也会添加我的输入,因为我发现实际上可以从本机Windows应用程序(不仅仅是通用应用程序)使用SystemMediaTransportControls

First thing, it does still require a reference to the universal winmd files, so it will only work on Win10. 首先,它仍然需要引用通用winmd文件,因此它只适用于Win10。 They will be located in the 10 sdk, and you can add them via the regular Add Reference -> Browse but you may need to change the filter on the bottom right of the dialog to "All Files" for them to show up. 它们将位于10个sdk中,您可以通过常规的“ Add Reference -> Browse添加它们,但您可能需要将对话框右下角的过滤器更改为“所有文件”以便显示它们。 They are found here on my PC: 它们可以在我的电脑上找到:

  • Windows.Foundation.UniversalApiContract : Windows.Foundation.UniversalApiContract
    C:\\Program Files (x86)\\Windows Kits\\10\\References\\Windows.Foundation.UniversalApiContract\\1.0.0.0\\Windows.Foundation.UniversalApiContract.winmd C:\\ Program Files(x86)\\ Windows Kits \\ 10 \\ References \\ Windows.Foundation.UniversalApiContract \\ 1.0.0.0 \\ Windows.Foundation.UniversalApiContract.winmd
  • Windows.Foundation.FoundationContract : Windows.Foundation.FoundationContract
    C:\\Program Files (x86)\\Windows Kits\\10\\References\\Windows.Foundation.FoundationContract\\2.0.0.0\\Windows.Foundation.FoundationContract.winmd C:\\ Program Files(x86)\\ Windows Kits \\ 10 \\ References \\ Windows.Foundation.FoundationContract \\ 2.0.0.0 \\ Windows.Foundation.FoundationContract.winmd

After you have the necessary references, you'll run into another problem - you can't access the transport controls via the usual SystemMediaTransportControls.GetForCurrentView(); 在获得必要的引用后,您将遇到另一个问题 - 您无法通过常用的SystemMediaTransportControls.GetForCurrentView();访问传输控件SystemMediaTransportControls.GetForCurrentView(); (it will throw an exception) because you don't actually have a universal view. (它会抛出异常),因为你实际上没有通用视图。 This is alleviated by using the following: 使用以下内容可以缓解这种情况:

SystemMediaTransportControls systemControls =
    BackgroundMediaPlayer.Current.SystemMediaTransportControls;

After this, feel free to use any of the samples online or Stamos' answer. 在此之后,您可以随意使用在线任何样本或Stamos的回答。

<MediaElement x:Name="Media"
              AreTransportControlsEnabled="True">
    <MediaElement.TransportControls>
        <MediaTransportControls 
            Style="{StaticResource MediaTCStyle}"/>
    </MediaElement.TransportControls>
</MediaElement>

The style is quite big so i'm attaching a link MediaTransportControls styles and templates I got the style from the article(link above) and modified it in my own ResourceDictionary. 风格很大所以我附加了一个链接MediaTransportControls样式和模板我从文章(上面的链接)得到了样式,并在我自己的ResourceDictionary中修改它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 取消处理(取消注册)系统范围的“HotKey” - Unhandling (unregistering) a system-wide 'HotKey' 是.net系统范围内的垃圾收集器还是应用程序范围内的垃圾收集器? - Is the garbage collector in .net system-wide or application-wide? .NET系统范围内的EventWaitHandle名称允许的字符 - .NET system-wide EventWaitHandle name allowed characters 从DB处理队列时,系统范围互斥的替代方案? - alternatives to system-wide mutex when processing queue from DB? 是否可以定义在整个系统范围内使用的自定义URI方案? - Is possible to define custom URI scheme used system-wide? C#异步接收会导致系统范围的网络崩溃! - C# asynchronous receive causes system-wide network crash! 应用程序如何与系统范围的文本选择挂钩? - How can an app hook into text selection system-wide? Windows 7和8中的系统范围设置-注册表不再有用吗? - System-wide setting in Windows 7 and 8 - Registry is no longer useful? 如何在 C# 中与 Windows Media Player 交互 - How to interact with Windows Media Player in C# 如何在 .NET Core 中设置全局环境变量(用户范围或系统范围) - How to set a global environment variable in .NET Core (user-wide or system-wide)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM