Using SystemMediaTransportControls to get current playing song info from other app
Asked Answered
R

3

6

I write a some program that should work with another player and retrieve info about current playing song. That player is written using UWP, so Windows knows what track is playing, so i can see it's name and other info when changing volume:

https://i.sstatic.net/WSmwh.png

Things I tried:

var systemMediaControls = SystemMediaTransportControls.GetForCurrentView();

From Get current playing track info from Microsoft Groove Music app

Unfortunately, as I understand, it's just for local media, playing from my app.

Background media player doesn't helped too because of same reason.

Is it possible at all to get it from Windows? Or I should directly read memory of that player, heh?

Redhead answered 20/8, 2019 at 19:2 Comment(0)
V
0

The screen control bar displayed by the music application is not controlled by the system but belongs to the application itself.

You don't have a way to get playing music in other music software just as you can't get files from the application folder of other applications.

Anyway, if you just want to get current song from OS, there’s no such API.

Best regards.

Velocipede answered 21/8, 2019 at 2:26 Comment(0)
T
15

How to display artist and song name:

Get the Microsoft.Windows.SDK.Contracts package if you're not developing a WinRT app.

(Visual Studio) In your NuGet Package Manager settings (Tools->NuGet Package Manager->Package Manager Settings) you need to have 'PackageManagement\Default package management format' set to 'PackageReference'

If you've done that, the package should show up in your References. If that isn't the case, you need to deinstall the package and its dependencies and try again.

Here's example code:

using System;
using System.Threading.Tasks;
using Windows.Media.Control;

public static class Program {
    public static async Task Main(string[] args) {
        var gsmtcsm = await GetSystemMediaTransportControlsSessionManager();
        var mediaProperties = await GetMediaProperties(gsmtcsm.GetCurrentSession());

        Console.WriteLine("{0} - {1}", mediaProperties.Artist, mediaProperties.Title);

        Console.WriteLine("Press any key to quit..");
        Console.ReadKey(true);
    }

    private static async Task<GlobalSystemMediaTransportControlsSessionManager> GetSystemMediaTransportControlsSessionManager() =>
        await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();

    private static async Task<GlobalSystemMediaTransportControlsSessionMediaProperties> GetMediaProperties(GlobalSystemMediaTransportControlsSession session) =>
        await session.TryGetMediaPropertiesAsync();
}
Tomchay answered 26/7, 2020 at 12:4 Comment(7)
If you're still having issues finding the Windows.Media namespace, manually add the reference (using the Add Reference panel in the project menu), browse to "C:\Program Files (x86)\Windows Kits\10\References\", then the folder in there, then Windows.Foundation.UniversalApiContract, then the folder in there, then set the file type selector to all files, and select "Windows.Foundation.UniversalApiContract.winmd"Downs
could you take a look at this, please. #64889780Cofer
Any Idea how I can subscribe to track changes events like next/prev or play/pause thanks?Ara
@PhaniRithvij My friend made a library for exactly that, take a look: github.com/DubyaDude/WindowsMediaController/blob/master/…Tomchay
@PhaniRithvij Oh sorry I probably misunderstood you. You can subscribe to the PlaybackInfosChanged event in a GlobalSystemMediaTransportControlsSession object. You can then get the playback info via session.GetPlaybackInfo() and on this object you can put a switch around PlaybackStatus to track those changes.Tomchay
@LucaMarini thank you for replying and providing a reference project, I have one more question if you don't mind, do you know how to do the reverse i.e. act as an audio player application that lets the os (windows) know what's currently playing? I would really appreciate any github repos (c# or c++) which does this as a reference. I've been trying to google this for the last couple of days but only MSDN docs show up. Thank you.Ara
@PhaniRithvij Take a look here: github.com/MicrosoftDocs/windows-uwp/blob/docs/windows-apps-src/…Tomchay
C
1

I needed something similar (getting the currently playing media from apps like spotify or any other mediaplayer that utilizes SystemMediaTransportControls and found the way for it. according to this link: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/desktop-to-uwp-enhance if you are using .net 6 or later you need to set your target pltform to windows10.0.17763.0 or just modify your project file:

<TargetFramework>net7.0-windows10.0.17763.0</TargetFramework>

and if you are using .NET Framework 4.6+ or .NET Core 3.0+ you must install the Microsoft.Windows.SDK.Contracts nuget package. then you can add using Windows.Media.Control;

and here's a sample code (it isn't well-written but you can see how to use the API) that displays your currently playing media (also utilizes events to display new media and media playback status)

using System;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Windows.Media.Control;

namespace TestGetCurrentMedia
{
   internal class Program
   {
      public static async Task Main(string[] args)
      {
         var gsmtcsm = await GetSystemMediaTransportControlsSessionManager();
         Gsmtcsm_CurrentSessionChanged(gsmtcsm, null);
         gsmtcsm.CurrentSessionChanged += Gsmtcsm_CurrentSessionChanged;
         Console.ReadLine();
      }
      static string LastString = "";
      private static async void Gsmtcsm_CurrentSessionChanged(GlobalSystemMediaTransportControlsSessionManager sender, CurrentSessionChangedEventArgs args)
      {
         var s = sender.GetCurrentSession();
         if (s != null)
         {
            s.MediaPropertiesChanged += S_MediaPropertiesChanged;
            S_MediaPropertiesChanged(s, null);
            s.PlaybackInfoChanged += S_PlaybackInfoChanged;
            S_PlaybackInfoChanged(s, null);
         }
         //GC.Collect();
      }

      private static void S_PlaybackInfoChanged(GlobalSystemMediaTransportControlsSession sender, PlaybackInfoChangedEventArgs args)
      {
         GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo = sender.GetPlaybackInfo();
         Console.WriteLine(LastString + " => " + playbackInfo.PlaybackStatus);
      }

      private static async void S_MediaPropertiesChanged(GlobalSystemMediaTransportControlsSession sender, MediaPropertiesChangedEventArgs args)
      {
         GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties = await sender.TryGetMediaPropertiesAsync();
         if (mediaProperties != null)
         {
            string Curr = ($"{mediaProperties.Artist} - {mediaProperties.Title} - {mediaProperties.TrackNumber}");
            if (!Curr.Equals(LastString))
            {
               //Console.WriteLine(Curr);
               LastString = Curr;
               S_PlaybackInfoChanged(sender, null);
            }
         }
      }
      private static async Task<GlobalSystemMediaTransportControlsSessionManager> GetSystemMediaTransportControlsSessionManager() =>
          await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
   }
}

The above code in action

Cestode answered 3/12, 2023 at 21:59 Comment(0)
V
0

The screen control bar displayed by the music application is not controlled by the system but belongs to the application itself.

You don't have a way to get playing music in other music software just as you can't get files from the application folder of other applications.

Anyway, if you just want to get current song from OS, there’s no such API.

Best regards.

Velocipede answered 21/8, 2019 at 2:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.