Media (Windows): finalize Windows support

This commit is contained in:
李通洲
2024-06-11 16:41:57 +08:00
parent c4751eb834
commit cf4ed9d9dc
6 changed files with 148 additions and 106 deletions
+38
View File
@@ -0,0 +1,38 @@
#include "common/library.h"
#include "util/windows/unicode.h"
#include "media.h"
#include "media_windows.dll.h"
static const char* getMedia(FFMediaResult* media)
{
FF_LIBRARY_LOAD(libffwinrt, NULL, "dlopen libffwinrt" FF_LIBRARY_EXTENSION " failed", "libffwinrt" FF_LIBRARY_EXTENSION, 0)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libffwinrt, ffWinrtDetectMedia)
libffwinrt = NULL; // Don't close libffwinrt or it may crash
FFWinrtMediaResult result = {};
const char* error = ffffWinrtDetectMedia(&result);
if (error)
{
ffStrbufSetStatic(&media->error, error);
return NULL;
}
ffStrbufSetWS(&media->playerId, result.playerId);
ffStrbufSet(&media->player, &media->playerId);
if (ffStrbufEndsWithIgnCaseS(&media->player, ".exe"))
ffStrbufSubstrBefore(&media->player, media->player.length - 4);
else
ffStrbufSubstrAfterFirstC(&media->player, '!'); // UWP ID
ffStrbufSetWS(&media->song, result.song);
ffStrbufSetWS(&media->artist, result.artist);
ffStrbufSetWS(&media->album, result.album);
ffStrbufSetStatic(&media->status, result.status);
return NULL;
}
void ffDetectMediaImpl(FFMediaResult* media)
{
const char* error = getMedia(media);
ffStrbufAppendS(&media->error, error);
}
-65
View File
@@ -1,65 +0,0 @@
extern "C"
{
#include "media.h"
#include "util/windows/unicode.h"
}
#include <winrt/Windows.Foundation.h>
#include <winrt/windows.Media.Control.h>
#include <winrt/Windows.Media.Playback.h>
extern "C"
{
static const char* getMedia(FFMediaResult* media)
{
using namespace winrt::Windows::Media::Control;
auto manager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
if (!manager)
return "GlobalSystemMediaTransportControlsSessionManager::RequestAsync() failed";
auto session = manager.GetCurrentSession();
if (!session)
return "GetCurrentSession() failed";
auto mediaProps = session
.TryGetMediaPropertiesAsync()
.get();
if (!mediaProps)
return "TryGetMediaPropertiesAsync() failed";
if (auto playbackInfo = session.GetPlaybackInfo())
{
switch (playbackInfo.PlaybackStatus())
{
#define FF_MEDIA_SET_STATUS(status_code) \
case GlobalSystemMediaTransportControlsSessionPlaybackStatus::status_code: ffStrbufSetStatic(&media->status, #status_code); break
FF_MEDIA_SET_STATUS(Closed);
FF_MEDIA_SET_STATUS(Opened);
FF_MEDIA_SET_STATUS(Changing);
FF_MEDIA_SET_STATUS(Stopped);
FF_MEDIA_SET_STATUS(Playing);
FF_MEDIA_SET_STATUS(Paused);
#undef FF_MEDIA_SET_STATUS
}
}
ffStrbufSetNWS(&media->playerId, session.SourceAppUserModelId().size(), session.SourceAppUserModelId().data());
ffStrbufSet(&media->player, &media->playerId);
if (ffStrbufEndsWithIgnCaseS(&media->player, ".exe"))
ffStrbufSubstrBefore(&media->player, media->player.length - 4);
else
ffStrbufSubstrAfterFirstC(&media->player, '!'); // UWP ID
ffStrbufSetNWS(&media->song, mediaProps.Title().size(), mediaProps.Title().data());
ffStrbufSetNWS(&media->artist, mediaProps.Artist().size(), mediaProps.Artist().data());
ffStrbufSetNWS(&media->album, mediaProps.AlbumTitle().size(), mediaProps.AlbumTitle().data());
return NULL;
}
void ffDetectMediaImpl(FFMediaResult* media)
{
const char* error = getMedia(media);
ffStrbufAppendS(&media->error, error);
}
}
+53
View File
@@ -0,0 +1,53 @@
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Media.Control.h>
#include <wchar.h>
extern "C"
{
#include "media_windows.dll.h"
const char* ffWinrtDetectMedia(FFWinrtMediaResult* result)
{
// C++/WinRT requires Windows 8.1 or later and C++ runtime (std::string and other stuff)
// Make it a separate dll in order not to break Windows 7 support
using namespace winrt::Windows::Media::Control;
auto manager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
if (!manager)
return "winrt: GlobalSystemMediaTransportControlsSessionManager::RequestAsync() failed";
auto session = manager.GetCurrentSession();
if (!session)
return "winrt: GetCurrentSession() failed";
auto mediaProps = session
.TryGetMediaPropertiesAsync()
.get();
if (!mediaProps)
return "winrt: TryGetMediaPropertiesAsync() failed";
if (auto playbackInfo = session.GetPlaybackInfo())
{
switch (playbackInfo.PlaybackStatus())
{
#define FF_MEDIA_SET_STATUS(status_code) \
case GlobalSystemMediaTransportControlsSessionPlaybackStatus::status_code: result->status = #status_code; break
FF_MEDIA_SET_STATUS(Closed);
FF_MEDIA_SET_STATUS(Opened);
FF_MEDIA_SET_STATUS(Changing);
FF_MEDIA_SET_STATUS(Stopped);
FF_MEDIA_SET_STATUS(Playing);
FF_MEDIA_SET_STATUS(Paused);
#undef FF_MEDIA_SET_STATUS
}
}
::wcsncpy(result->playerId, session.SourceAppUserModelId().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
::wcsncpy(result->song, mediaProps.Title().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
::wcsncpy(result->artist, mediaProps.Artist().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
::wcsncpy(result->album, mediaProps.AlbumTitle().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
return NULL;
}
} // extern "C"
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#define FF_MEDIA_WIN_RESULT_BUFLEN 256
typedef struct FFWinrtMediaResult
{
wchar_t playerId[FF_MEDIA_WIN_RESULT_BUFLEN];
wchar_t song[FF_MEDIA_WIN_RESULT_BUFLEN];
wchar_t artist[FF_MEDIA_WIN_RESULT_BUFLEN];
wchar_t album[FF_MEDIA_WIN_RESULT_BUFLEN];
const char* status;
} FFWinrtMediaResult;
__attribute__((__dllexport__))
const char* ffWinrtDetectMedia(FFWinrtMediaResult* result);