diff --git a/src/detection/media/media_windows.c b/src/detection/media/media_windows.c index 54175aa3f..cdc01cac0 100644 --- a/src/detection/media/media_windows.c +++ b/src/detection/media/media_windows.c @@ -33,6 +33,11 @@ static const char* getMedia(FFMediaResult* media) ffStrbufSetWS(&media->artist, result.artist); ffStrbufSetWS(&media->album, result.album); ffStrbufSetStatic(&media->status, result.status); + + ffStrbufDestroy(&media->cover); + media->cover.chars = (char*) result.coverImageData; + media->cover.length = result.coverImageSize; + media->cover.allocated = result.coverImageSize + 1; return NULL; } diff --git a/src/detection/media/media_windows.dll.cpp b/src/detection/media/media_windows.dll.cpp index 34f46219b..cf81cf09c 100644 --- a/src/detection/media/media_windows.dll.cpp +++ b/src/detection/media/media_windows.dll.cpp @@ -1,7 +1,10 @@ +#include #include #include -#include +#include #include +#include + extern "C" { @@ -13,6 +16,7 @@ const char* ffWinrtDetectMedia(FFWinrtMediaResult* result) // Make it a separate dll in order not to break Windows 7 support using namespace winrt::Windows::Media::Control; using namespace winrt::Windows::ApplicationModel; + using namespace winrt::Windows::Storage::Streams; try { @@ -47,15 +51,46 @@ const char* ffWinrtDetectMedia(FFWinrtMediaResult* result) } ::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 (auto thumbRef = mediaProps.Thumbnail()) + { + try + { + auto stream = thumbRef.OpenReadAsync().get(); + uint64_t size = stream.Size(); + if (size > 0) + { + auto contentType = stream.ContentType(); + auto ibuffer = Buffer(static_cast(size)); + auto readBuffer = stream.ReadAsync(ibuffer, static_cast(size), InputStreamOptions::None).get(); + uint32_t length = readBuffer.Length(); + auto reader = DataReader::FromBuffer(readBuffer); + + result->coverImageSize = length; + result->coverImageData = (uint8_t*) ::malloc(length + 1); + reader.ReadBytes(winrt::array_view(result->coverImageData, result->coverImageSize)); + result->coverImageData[length] = 0; + } + } + catch (...) + { + // Ignore thumbnail errors + } + } + return NULL; } catch (...) diff --git a/src/detection/media/media_windows.dll.h b/src/detection/media/media_windows.dll.h index aae081e88..9118328f8 100644 --- a/src/detection/media/media_windows.dll.h +++ b/src/detection/media/media_windows.dll.h @@ -10,6 +10,10 @@ typedef struct FFWinrtMediaResult wchar_t artist[FF_MEDIA_WIN_RESULT_BUFLEN]; wchar_t album[FF_MEDIA_WIN_RESULT_BUFLEN]; const char* status; + + // Caller is responsible for freeing it using free() + uint8_t* coverImageData; + uint32_t coverImageSize; } FFWinrtMediaResult; __attribute__((__dllexport__))