Media (macOS): support macOS 15.4

Fix #1737
This commit is contained in:
李通洲
2025-05-06 16:04:12 +08:00
parent ef7f61309f
commit 1557f0c556
4 changed files with 64 additions and 3 deletions
+5
View File
@@ -326,6 +326,11 @@ endif()
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
if(APPLE)
# See src/detection/media/media_apple.m
fastfetch_load_text(src/data/nowPlaying.scptd DATATEXT_NOWPLAYING)
endif()
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
if(APPLE)
+24
View File
@@ -0,0 +1,24 @@
use scripting additions
use framework "/System/Library/PrivateFrameworks/MediaRemote.framework"
set MRNowPlayingRequest to current application's NSClassFromString("MRNowPlayingRequest")
if MRNowPlayingRequest's localNowPlayingItem() is missing value then
return
end if
if MRNowPlayingRequest's localIsPlaying() then
set status to "Playing"
else
set status to "Paused"
end if
set infoDict to MRNowPlayingRequest's localNowPlayingItem()'s nowPlayingInfo()
set bundleObj to MRNowPlayingRequest's localNowPlayingPlayerPath()'s client()
return status & "
" & (infoDict's valueForKey:"kMRMediaRemoteNowPlayingInfoTitle" as text) & "
" & (infoDict's valueForKey:"kMRMediaRemoteNowPlayingInfoArtist" as text) & "
" & (infoDict's valueForKey:"kMRMediaRemoteNowPlayingInfoAlbum" as text) & "
" & (bundleObj's bundleIdentifier() as text) & "
" & (bundleObj's displayName() as text)
+31 -3
View File
@@ -1,8 +1,10 @@
#include "fastfetch.h"
#include "detection/media/media.h"
#include "common/library.h"
#include "common/processing.h"
#include "util/apple/cf_helpers.h"
#include "util/apple/osascript.h"
#include "fastfetch_datatext.h"
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
@@ -13,7 +15,7 @@ extern CFStringRef MRNowPlayingClientGetBundleIdentifier(id clientObj) __attribu
extern CFStringRef MRNowPlayingClientGetParentAppBundleIdentifier(id clientObj) __attribute__((weak_import));
void MRMediaRemoteGetNowPlayingApplicationIsPlaying(dispatch_queue_t queue, void (^callback)(BOOL playing)) __attribute__((weak_import));
static const char* getMedia(FFMediaResult* result)
static const char* getMediaByMediaRemote(FFMediaResult* result)
{
#define FF_TEST_FN_EXISTANCE(fn) if (!fn) return "MediaRemote function " #fn " is not available"
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingInfo);
@@ -79,8 +81,34 @@ static const char* getMedia(FFMediaResult* result)
return error;
}
static const char* getMediaByOsascript(FFMediaResult* result)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
// The script must be executed by `/usr/bin/osascript`. `ffOsascript` doesn't work here
const char* error = ffProcessAppendStdOut(&buffer, (char* const[]) {
"/usr/bin/osascript",
"-e",
FASTFETCH_DATATEXT_NOWPLAYING,
nil
});
if (error) return error;
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 };
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);
return NULL;
}
void ffDetectMediaImpl(FFMediaResult* media)
{
const char* error = getMedia(media);
ffStrbufAppendS(&media->error, error);
const char* error;
if (@available(macOS 15.4, *))
error = getMediaByOsascript(media);
else
error = getMediaByMediaRemote(media);
if (error) ffStrbufAppendS(&media->error, error);
}
+4
View File
@@ -2,3 +2,7 @@
#define FASTFETCH_DATATEXT_JSON_HELP @DATATEXT_JSON_HELP@
#define FASTFETCH_DATATEXT_STRUCTURE @DATATEXT_STRUCTURE@
#ifdef __APPLE__
#define FASTFETCH_DATATEXT_NOWPLAYING @DATATEXT_NOWPLAYING@
#endif