Interact with "system-wide" media player
Asked Answered
P

3

14

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. I've tried Googling to get more information about it but I haven't had any success whatsoever. 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:

screen shot

I was wondering how I could create this dialog in my own app and what windows API's I'd have to look into.

Pournaras answered 16/7, 2015 at 20:53 Comment(1)
I'm also looking for a way to access information on a song playing in Groove Music programmatically. I didn't find anything.Maidel
S
9

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).

First thing, it does still require a reference to the universal winmd files, so it will only work on 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. They are found here on my PC:

  • Windows.Foundation.UniversalApiContract:
    C:\Program Files (x86)\Windows Kits\10\References\Windows.Foundation.UniversalApiContract\1.0.0.0\Windows.Foundation.UniversalApiContract.winmd
  • Windows.Foundation.FoundationContract:
    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(); (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.

Sendoff answered 29/4, 2016 at 21:10 Comment(0)
A
7

You need to use SystemMediaTransportControls

Here is a basic setup with Play and Pause. If you like to enable more controls you can do using the available properties for ex.

systemControls.IsNextEnabled = true;

and you have to add the case in the button switch.

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

xaml

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

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

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

enter image description here

Aweather answered 27/4, 2016 at 20:46 Comment(1)
Good answer, but i did find a way to use this from a native app as well, so I've also posted an answer detailing this.Sendoff
D
-1
<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.

Distort answered 27/4, 2016 at 11:33 Comment(4)
Right, the proper thing to use now is SystemMediaTransportControls, this answer led me to it. Still curious if there is any way to access this as a native windows app instead of a universal app.Sendoff
@Sendoff SystemMediaTransportControls is only evailable to 'Metro' apps also @DanielFilipov TransportControls are for the MediaElements default control in the Element itself not the SystemMediaTransportControls.Aweather
@Aweather I agree and your answer is more clear but still i don't see why would you put a down vote after other already commented it is useful.Distort
@DanielFilipov As I said in my comment TransportControls are for the MediaElement default controls and its not the same as SystemMediaTransportControl. I down voted because its not the answer and has nothink yo do with your question.Aweather

© 2022 - 2024 — McMap. All rights reserved.