mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Media: save media cover to temp file
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <CoreServices/CoreServices.h>
|
||||
|
||||
// https://github.com/andrewwiik/iOS-Blocks/blob/master/Widgets/Music/MediaRemote.h
|
||||
extern void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t dispatcher, void(^callback)(_Nullable CFDictionaryRef info)) __attribute__((weak_import));
|
||||
@@ -30,7 +31,21 @@ static const char* getMediaByMediaRemote(FFMediaResult* result)
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoTitle"), &result->song);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtist"), &result->artist);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoAlbum"), &result->album);
|
||||
ffCfDictGetDataAsString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtworkData"), &result->cover);
|
||||
NSData* artworkData = (__bridge NSData*) CFDictionaryGetValue(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtworkData"));
|
||||
if (artworkData)
|
||||
{
|
||||
CFStringRef mime = (CFStringRef) CFDictionaryGetValue(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtworkMIMEType"));
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
FF_CFTYPE_AUTO_RELEASE CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime, NULL);
|
||||
FF_CFTYPE_AUTO_RELEASE CFStringRef ext = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension);
|
||||
#pragma clang diagnostic pop
|
||||
NSString *tmpDir = NSTemporaryDirectory();
|
||||
NSString *uuid = [[NSUUID UUID] UUIDString];
|
||||
NSString *path = [tmpDir stringByAppendingPathComponent:[NSString stringWithFormat:@"ff_%@.%@", uuid, ext ? (__bridge NSString *) ext : @"img"]];
|
||||
if ([artworkData writeToFile:path atomically:NO])
|
||||
ffStrbufSetS(&result->cover, path.UTF8String);
|
||||
}
|
||||
}
|
||||
else
|
||||
error = "MRMediaRemoteGetNowPlayingInfo() failed";
|
||||
@@ -91,7 +106,7 @@ int ffPrintMediaByMediaRemote(void)
|
||||
ffStrbufPutTo(&media.album, stdout);
|
||||
ffStrbufPutTo(&media.playerId, stdout);
|
||||
ffStrbufPutTo(&media.player, stdout);
|
||||
ffStrbufWriteTo(&media.cover, stdout); // Raw data
|
||||
ffStrbufWriteTo(&media.cover, stdout);
|
||||
ffStrbufDestroy(&media.status);
|
||||
ffStrbufDestroy(&media.song);
|
||||
ffStrbufDestroy(&media.artist);
|
||||
@@ -118,15 +133,11 @@ static const char* getMediaByAuthorizedProcess(FFMediaResult* result)
|
||||
if (buffer.length == 0) return "No media found";
|
||||
|
||||
// status\ntitle\nartist\nalbum\nbundleName\nappName
|
||||
FFstrbuf* const varList[] = { &result->status, &result->song, &result->artist, &result->album, &result->playerId, &result->player };
|
||||
FFstrbuf* const varList[] = { &result->status, &result->song, &result->artist, &result->album, &result->playerId, &result->player, &result->cover };
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(varList) && ffStrbufGetline(&line, &len, &buffer); ++i)
|
||||
ffStrbufSetS(varList[i], line);
|
||||
ffStrbufGetlineRestore(&line, &len, &buffer);
|
||||
line++; // Skip the newline before the cover data
|
||||
if (line < buffer.chars + buffer.length)
|
||||
ffStrbufSetNS(&result->cover, buffer.length - (uint32_t) (line - buffer.chars), line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,8 +77,8 @@ static bool parseMprisMetadata(FFDBusData* data, DBusMessageIter* rootIterator,
|
||||
ffDBusGetString(data, &dictIterator, &path);
|
||||
if (ffStrbufStartsWithS(&path, "file:///"))
|
||||
{
|
||||
uint32_t j = 0;
|
||||
for (uint32_t i = (uint32_t) strlen("file:///") - 1; i < path.length; ++i, ++j)
|
||||
ffStrbufEnsureFree(&result->cover, path.length - (uint32_t) strlen("file://"));
|
||||
for (uint32_t i = (uint32_t) strlen("file://"); i < path.length; ++i)
|
||||
{
|
||||
if (path.chars[i] == '%')
|
||||
{
|
||||
@@ -86,17 +86,14 @@ static bool parseMprisMetadata(FFDBusData* data, DBusMessageIter* rootIterator,
|
||||
break;
|
||||
char str[] = { path.chars[i + 1], path.chars[i + 2], 0 };
|
||||
const char decodedChar = (char) strtoul(str, NULL, 16);
|
||||
path.chars[j] = decodedChar;
|
||||
i += 2;
|
||||
ffStrbufAppendC(&result->cover, decodedChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
path.chars[j] = path.chars[i];
|
||||
ffStrbufAppendC(&result->cover, path.chars[i]);
|
||||
}
|
||||
}
|
||||
path.chars[j] = '\0';
|
||||
path.length = j;
|
||||
ffReadFileBuffer(path.chars, &result->cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,8 @@ static const char* getMedia(FFMediaResult* media)
|
||||
ffStrbufSetWS(&media->song, result.song);
|
||||
ffStrbufSetWS(&media->artist, result.artist);
|
||||
ffStrbufSetWS(&media->album, result.album);
|
||||
ffStrbufSetWS(&media->cover, result.cover);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#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 <stdlib.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -16,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;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
|
||||
try
|
||||
@@ -69,20 +70,24 @@ const char* ffWinrtDetectMedia(FFWinrtMediaResult* result)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto stream = thumbRef.OpenReadAsync().get();
|
||||
uint64_t size = stream.Size();
|
||||
if (size > 0)
|
||||
if (auto stream = thumbRef.OpenReadAsync().get())
|
||||
{
|
||||
auto contentType = stream.ContentType();
|
||||
auto ibuffer = Buffer(static_cast<uint32_t>(size));
|
||||
auto readBuffer = stream.ReadAsync(ibuffer, static_cast<uint32_t>(size), InputStreamOptions::None).get();
|
||||
uint32_t length = readBuffer.Length();
|
||||
auto reader = DataReader::FromBuffer(readBuffer);
|
||||
if (stream.Size() > 0)
|
||||
{
|
||||
Buffer buffer(static_cast<uint32_t>(stream.Size()));
|
||||
stream.ReadAsync(buffer, buffer.Capacity(), InputStreamOptions::None).get();
|
||||
|
||||
result->coverImageSize = length;
|
||||
result->coverImageData = (uint8_t*) ::malloc(length + 1);
|
||||
reader.ReadBytes(winrt::array_view<uint8_t>(result->coverImageData, result->coverImageSize));
|
||||
result->coverImageData[length] = 0;
|
||||
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 (...)
|
||||
|
||||
@@ -9,11 +9,8 @@ typedef struct FFWinrtMediaResult
|
||||
wchar_t song[FF_MEDIA_WIN_RESULT_BUFLEN];
|
||||
wchar_t artist[FF_MEDIA_WIN_RESULT_BUFLEN];
|
||||
wchar_t album[FF_MEDIA_WIN_RESULT_BUFLEN];
|
||||
wchar_t cover[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__))
|
||||
|
||||
Reference in New Issue
Block a user