Files
fastfetch/src/detection/media/media_windows.dll.cpp
T
李通洲 e0eba8ce21 Chore: run clang-format
```bash
find . -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) ! -path "src/3rdparty/*" -print0 | xargs -0 clang-format -i
```
2026-03-29 10:03:32 +08:00

100 lines
4.3 KiB
C++

#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Media.Control.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Storage.h>
#include <wchar.h>
#include <windows.h>
extern "C" {
#include "media_windows.dll.h"
const char* ffWinrtDetectMedia(FFWinrtMediaResult* result, bool saveCover) {
// C++/WinRT requires Windows 8.1+ and C++ runtime (std::string, exceptions and other stuff)
// Make it a separate dll in order not to break Windows 7 support
using namespace winrt::Windows::Media::Control;
using namespace winrt::Windows::ApplicationModel;
try {
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);
result->playerId[FF_MEDIA_WIN_RESULT_BUFLEN - 1] = L'\0';
::wcsncpy(result->song, mediaProps.Title().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
result->song[FF_MEDIA_WIN_RESULT_BUFLEN - 1] = L'\0';
::wcsncpy(result->artist, mediaProps.Artist().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
result->artist[FF_MEDIA_WIN_RESULT_BUFLEN - 1] = L'\0';
::wcsncpy(result->album, mediaProps.AlbumTitle().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
result->album[FF_MEDIA_WIN_RESULT_BUFLEN - 1] = L'\0';
try {
// Only works for UWP apps
::wcsncpy(result->playerName, AppInfo::GetFromAppUserModelId(session.SourceAppUserModelId()).DisplayInfo().DisplayName().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
result->playerName[FF_MEDIA_WIN_RESULT_BUFLEN - 1] = L'\0';
} catch (...) {}
if (saveCover) {
using namespace winrt::Windows::Storage;
using namespace winrt::Windows::Storage::Streams;
if (auto thumbRef = mediaProps.Thumbnail()) {
try {
if (auto stream = thumbRef.OpenReadAsync().get()) {
if (stream.Size() > 0) {
Buffer buffer(static_cast<uint32_t>(stream.Size()));
stream.ReadAsync(buffer, buffer.Capacity(), InputStreamOptions::None).get();
wchar_t tempPath[MAX_PATH];
if (GetTempPathW(MAX_PATH, tempPath) > 0) {
auto tempFolder = StorageFolder::GetFolderFromPathAsync(tempPath).get();
auto tempFile = tempFolder.CreateFileAsync(L"ff_thumb.img", CreationCollisionOption::GenerateUniqueName).get();
FileIO::WriteBufferAsync(tempFile, buffer).get();
::wcsncpy(result->cover, tempFile.Path().data(), FF_MEDIA_WIN_RESULT_BUFLEN);
result->cover[FF_MEDIA_WIN_RESULT_BUFLEN - 1] = L'\0';
}
}
}
} catch (...) {
// Ignore thumbnail errors
}
}
}
return NULL;
} catch (...) {
return "A C++ exception is thrown";
}
}
} // extern "C"