mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Merge pull request #242 from CarterLi/master
Media: support song detection on macOS
This commit is contained in:
+3
-1
@@ -189,7 +189,6 @@ set(LIBFASTFETCH_SRC
|
||||
src/detection/gtk.c
|
||||
src/detection/terminalShell.c
|
||||
src/detection/vulkan.c
|
||||
src/detection/media.c
|
||||
src/detection/datetime.c
|
||||
src/detection/temps.c
|
||||
src/detection/title.c
|
||||
@@ -253,6 +252,7 @@ if(APPLE)
|
||||
src/detection/terminalfont/terminalfont_apple.c
|
||||
src/util/apple/cfdict_helpers.c
|
||||
src/util/apple/osascript.m
|
||||
src/detection/media/media_apple.m
|
||||
)
|
||||
elseif(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -264,6 +264,7 @@ elseif(ANDROID)
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/displayserver/displayserver_android.c
|
||||
src/detection/terminalfont/terminalfont_android.c
|
||||
src/detection/media/media_linux.c
|
||||
)
|
||||
else()
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -279,6 +280,7 @@ else()
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/media/media_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ typedef struct FFMediaResult
|
||||
FFstrbuf artist;
|
||||
FFstrbuf album;
|
||||
FFstrbuf url;
|
||||
const char* error;
|
||||
} FFMediaResult;
|
||||
|
||||
const FFMediaResult* ffDetectMedia(FFinstance* instance);
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/media/media.h"
|
||||
#include "common/library.h"
|
||||
#include "util/apple/cfdict_helpers.h"
|
||||
|
||||
#import <pthread.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t dispatcher, void(^callback)(_Nullable CFDictionaryRef info));
|
||||
|
||||
const char* getMedia(FFMediaResult* result)
|
||||
{
|
||||
ffStrbufInit(&result->busNameShort);
|
||||
ffStrbufInit(&result->player);
|
||||
ffStrbufInit(&result->song);
|
||||
ffStrbufInit(&result->artist);
|
||||
ffStrbufInit(&result->album);
|
||||
ffStrbufInit(&result->url);
|
||||
|
||||
FFstrbuf fake;
|
||||
ffStrbufInitA(&fake, 0);//MediaRemote is a macOS builtin framework thus its path should not change
|
||||
|
||||
FF_LIBRARY_LOAD(
|
||||
MediaRemote,
|
||||
fake,
|
||||
"dlopen MediaRemote failed",
|
||||
"/System/Library/PrivateFrameworks/MediaRemote.framework/MediaRemote",
|
||||
1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(MediaRemote, MRMediaRemoteGetNowPlayingInfo);
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
ffMRMediaRemoteGetNowPlayingInfo(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(_Nullable CFDictionaryRef info) {
|
||||
if(info != nil) {
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoTitle"), &result->song);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtist"), &result->artist);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoAlbum"), &result->album);
|
||||
}
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
});
|
||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const FFMediaResult* ffDetectMedia(FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance)
|
||||
static FFMediaResult result;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static bool init = false;
|
||||
|
||||
if(!init)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
if(!init)
|
||||
{
|
||||
result.error = getMedia(&result);
|
||||
init = true;
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
return &result;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/media.h"
|
||||
#include "detection/media/media.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/printing.h"
|
||||
#include "detection/media.h"
|
||||
#include "detection/media/media.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/printing.h"
|
||||
#include "detection/media.h"
|
||||
#include "detection/media/media.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "cfdict_helpers.h"
|
||||
|
||||
bool ffCfDictGetString(CFMutableDictionaryRef dict, CFStringRef key, FFstrbuf* result)
|
||||
bool ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result)
|
||||
{
|
||||
CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
|
||||
if(cf == NULL)
|
||||
@@ -10,12 +10,13 @@ bool ffCfDictGetString(CFMutableDictionaryRef dict, CFStringRef key, FFstrbuf* r
|
||||
{
|
||||
CFStringRef cfStr = (CFStringRef)cf;
|
||||
uint32_t length = (uint32_t)CFStringGetLength(cfStr);
|
||||
ffStrbufEnsureFree(result, length + 1);
|
||||
if(CFStringGetCString(cfStr, result->chars, length + 1, kCFStringEncodingASCII))
|
||||
//CFString stores UTF16 characters, therefore may require larger buffer to convert to UTF8 string
|
||||
ffStrbufEnsureFree(result, length * 2);
|
||||
if(CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8))
|
||||
{
|
||||
result->length = length;
|
||||
// CFStringGetCString ensures the buffer is NUL terminated
|
||||
// https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring
|
||||
result->length = strnlen(result->chars, (uint32_t)result->allocated);
|
||||
}
|
||||
}
|
||||
else if(CFGetTypeID(cf) == CFDataGetTypeID())
|
||||
@@ -34,7 +35,7 @@ bool ffCfDictGetString(CFMutableDictionaryRef dict, CFStringRef key, FFstrbuf* r
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCfDictGetBool(CFMutableDictionaryRef dict, CFStringRef key, bool* result)
|
||||
bool ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result)
|
||||
{
|
||||
CFBooleanRef cf = (CFBooleanRef)CFDictionaryGetValue(dict, key);
|
||||
if(cf == NULL || CFGetTypeID(cf) != CFBooleanGetTypeID())
|
||||
@@ -44,7 +45,7 @@ bool ffCfDictGetBool(CFMutableDictionaryRef dict, CFStringRef key, bool* result)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCfDictGetInt(CFMutableDictionaryRef dict, CFStringRef key, int* result)
|
||||
bool ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result)
|
||||
{
|
||||
CFNumberRef cf = (CFNumberRef)CFDictionaryGetValue(dict, key);
|
||||
if (cf == NULL || CFGetTypeID(cf) != CFNumberGetTypeID())
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "fastfetch.h"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
bool ffCfDictGetString(CFMutableDictionaryRef dict, CFStringRef key, FFstrbuf* result);
|
||||
bool ffCfDictGetBool(CFMutableDictionaryRef dict, CFStringRef key, bool* result);
|
||||
bool ffCfDictGetInt(CFMutableDictionaryRef dict, CFStringRef key, int* result);
|
||||
bool ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result);
|
||||
bool ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result);
|
||||
bool ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user