fix mac os 15.4 support because apple restricted the mediaremote to processes that hold internal entitlements
This commit is contained in:
parent
8fb4af3a49
commit
9821b6a294
|
@ -1,11 +1,11 @@
|
|||
cmake_minimum_required (VERSION 3.8)
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
include("cmake/create_resources.cmake")
|
||||
|
||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
|
||||
#enable objective c support on mac os, needed for wxwidgets and compile for both intel macs and apple sillicon macs
|
||||
if(APPLE)
|
||||
list(APPEND SOURCES "src/backends/darwin.mm" ${CMAKE_SOURCE_DIR}/osx/icon.icns)
|
||||
list(APPEND SOURCES "src/backends/darwin.mm" ${CMAKE_SOURCE_DIR}/osx/icon.icns ${CMAKE_SOURCE_DIR}/osx/MediaRemote.scptd)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "" FORCE)
|
||||
project ("PlayerLink" LANGUAGES C CXX OBJCXX)
|
||||
|
@ -30,16 +30,9 @@ if(WIN32)
|
|||
list(APPEND LIBRARIES WindowsApp)
|
||||
target_link_options(PlayerLink PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
|
||||
elseif(APPLE)
|
||||
set(MEDIAREMOTE_FRAMEWORK_PATH "/System/Library/PrivateFrameworks")
|
||||
find_library(MEDIAREMOTE_LIBRARY MediaRemote PATHS ${MEDIAREMOTE_FRAMEWORK_PATH})
|
||||
if (MEDIAREMOTE_LIBRARY)
|
||||
message(STATUS "Found MediaRemote: ${MEDIAREMOTE_LIBRARY}")
|
||||
list(APPEND LIBRARIES ${MEDIAREMOTE_LIBRARY})
|
||||
else()
|
||||
message(FATAL_ERROR "MediaRemote framework not found.")
|
||||
endif()
|
||||
set_target_properties(PlayerLink PROPERTIES MACOSX_BUNDLE TRUE)
|
||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/osx/icon.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/osx/MediaRemote.scptd PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
set_target_properties(PlayerLink PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/osx/Info.plist)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
list(APPEND LIBRARIES dbus)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
use framework "Foundation"
|
||||
try
|
||||
set MediaRemote to current application's NSBundle's bundleWithPath:"/System/Library/PrivateFrameworks/MediaRemote.framework/"
|
||||
MediaRemote's load()
|
||||
|
||||
set MRNowPlayingRequest to current application's NSClassFromString("MRNowPlayingRequest")
|
||||
set bundleID to MRNowPlayingRequest's localNowPlayingPlayerPath()'s client()'s bundleIdentifier()
|
||||
set info to MRNowPlayingRequest's localNowPlayingItem()'s nowPlayingInfo()
|
||||
set title to info's valueForKey:"kMRMediaRemoteNowPlayingInfoTitle"
|
||||
set album to info's valueForKey:"kMRMediaRemoteNowPlayingInfoAlbum"
|
||||
set artist to info's valueForKey:"kMRMediaRemoteNowPlayingInfoArtist"
|
||||
set duration to info's valueForKey:"kMRMediaRemoteNowPlayingInfoDuration"
|
||||
set playbackStatus to info's valueForKey:"kMRMediaRemoteNowPlayingInfoPlaybackRate"
|
||||
set elapsed to info's valueForKey:"kMRMediaRemoteNowPlayingInfoElapsedTime"
|
||||
|
||||
set jsonString to "{"
|
||||
set jsonString to jsonString & "\"title\": \"" & title & "\", "
|
||||
set jsonString to jsonString & "\"album\": \"" & album & "\", "
|
||||
set jsonString to jsonString & "\"artist\": \"" & artist & "\", "
|
||||
set jsonString to jsonString & "\"duration\": \"" & duration & "\", "
|
||||
set jsonString to jsonString & "\"playbackStatus\": \"" & playbackStatus & "\", "
|
||||
set jsonString to jsonString & "\"elapsed\": \"" & elapsed & "\","
|
||||
set jsonString to jsonString & "\"player\": \"" & bundleID & "\""
|
||||
set jsonString to jsonString & "}"
|
||||
return jsonString
|
||||
on error
|
||||
set jsonString to "{\"player\": \"none\"}"
|
||||
return jsonString
|
||||
end try
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#ifdef __APPLE__
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
FOUNDATION_EXPORT CFStringRef _Nullable kMRMediaRemoteNowPlayingInfoTitle;
|
||||
FOUNDATION_EXPORT CFStringRef _Nullable kMRMediaRemoteNowPlayingInfoAlbum;
|
||||
FOUNDATION_EXPORT CFStringRef _Nullable kMRMediaRemoteNowPlayingInfoArtist;
|
||||
FOUNDATION_EXPORT CFStringRef _Nullable kMRMediaRemoteNowPlayingInfoDuration;
|
||||
FOUNDATION_EXPORT CFStringRef _Nullable kMRMediaRemoteNowPlayingInfoElapsedTime;
|
||||
FOUNDATION_EXPORT CFStringRef _Nullable kMRMediaRemoteNowPlayingInfoArtworkData;
|
||||
FOUNDATION_EXPORT CFStringRef _Nullable kMRMediaRemoteNowPlayingInfoPlaybackRate;
|
||||
|
||||
typedef void (^ MRMediaRemoteGetNowPlayingInfoCompletion)(CFDictionaryRef _Nullable information);
|
||||
typedef void (^ MRMediaRemoteGetNowPlayingApplicationPIDCompletion)(int PID);
|
||||
|
||||
FOUNDATION_EXPORT void MRMediaRemoteGetNowPlayingApplicationPID(dispatch_queue_t _Nullable queue, MRMediaRemoteGetNowPlayingApplicationPIDCompletion _Nullable completion);
|
||||
FOUNDATION_EXPORT void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t _Nullable queue, MRMediaRemoteGetNowPlayingInfoCompletion _Nullable completion);
|
||||
#endif
|
|
@ -1,12 +1,13 @@
|
|||
#include <Foundation/NSObjCRuntime.h>
|
||||
#ifdef __APPLE__
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <filesystem>
|
||||
#include <nlohmann-json/single_include/nlohmann/json.hpp>
|
||||
#include <fstream>
|
||||
|
||||
#include "../MediaRemote.hpp"
|
||||
#include "../backend.hpp"
|
||||
|
||||
void hideDockIcon(bool shouldHide) {
|
||||
|
@ -16,64 +17,55 @@ void hideDockIcon(bool shouldHide) {
|
|||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
}
|
||||
|
||||
NSString* getFilePathFromBundle(NSString* fileName, NSString* fileType) {
|
||||
NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:fileType];
|
||||
return filePath;
|
||||
}
|
||||
|
||||
NSString* executeCommand(NSString* command, NSArray* arguments) {
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
task.launchPath = command;
|
||||
task.arguments = arguments;
|
||||
|
||||
NSPipe *pipe = [NSPipe pipe];
|
||||
task.standardOutput = pipe;
|
||||
[task launch];
|
||||
|
||||
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
|
||||
NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
[task waitUntilExit];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
std::shared_ptr<MediaInfo> backend::getMediaInformation() {
|
||||
__block NSString *appName = nil;
|
||||
__block NSDictionary *playingInfo = nil;
|
||||
static NSString* script = getFilePathFromBundle(@"MediaRemote", @"scptd");
|
||||
NSString* output = executeCommand(@"/usr/bin/osascript", @[script]);
|
||||
nlohmann::json j = nlohmann::json::parse([output UTF8String]);
|
||||
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingApplicationPID(dispatch_get_main_queue(), ^(pid_t pid) {
|
||||
if (pid > 0) {
|
||||
NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
|
||||
if (app)
|
||||
appName = [[app.bundleIdentifier copy] retain];
|
||||
}
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingInfo(dispatch_get_main_queue(), ^(CFDictionaryRef result) {
|
||||
if (result)
|
||||
playingInfo = [[(__bridge NSDictionary *)result copy] retain];
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
||||
dispatch_release(group);
|
||||
if (appName == nil || playingInfo == nil)
|
||||
std::string appName = j["player"].get<std::string>();
|
||||
if (appName == "none")
|
||||
return nullptr;
|
||||
|
||||
bool paused = [playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoPlaybackRate] intValue] == 0;
|
||||
bool paused = j["playbackStatus"].get<std::string>() == "0";
|
||||
|
||||
NSString *title = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoTitle];
|
||||
std::string songTitle = title ? [title UTF8String] : "";
|
||||
std::string songTitle = j["title"].get<std::string>();
|
||||
|
||||
NSString *album = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoAlbum];
|
||||
std::string songAlbum = album ? [album UTF8String] : "";
|
||||
std::string songAlbum = j["album"].get<std::string>();
|
||||
|
||||
NSString *artist = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtist];
|
||||
std::string songArtist = artist ? [artist UTF8String] : "";
|
||||
std::string songArtist = j["artist"].get<std::string>();
|
||||
|
||||
NSData *artworkData = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtworkData];
|
||||
int64_t elapsedTimeMs = 0;
|
||||
int64_t durationMs = 0;
|
||||
try {
|
||||
double durationNumber = std::stod(j["duration"].get<std::string>());
|
||||
durationMs = static_cast<int64_t>(durationNumber * 1000);
|
||||
|
||||
std::string thumbnailData;
|
||||
if (artworkData)
|
||||
thumbnailData = std::string((const char *)[artworkData bytes], [artworkData length]);
|
||||
double elapsedTimeNumber = std::stod(j["elapsed"].get<std::string>());
|
||||
elapsedTimeMs = static_cast<int64_t>(elapsedTimeNumber * 1000);
|
||||
} catch (...) {}
|
||||
|
||||
NSNumber *elapsedTimeNumber = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoElapsedTime];
|
||||
|
||||
NSNumber *durationNumber = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoDuration];
|
||||
|
||||
int64_t elapsedTimeMs = elapsedTimeNumber ? static_cast<int64_t>([elapsedTimeNumber doubleValue] * 1000) : 0;
|
||||
|
||||
int64_t durationMs = durationNumber ? static_cast<int64_t>([durationNumber doubleValue] * 1000) : 0;
|
||||
|
||||
std::string appNameString = appName.UTF8String;
|
||||
|
||||
[appName release];
|
||||
[playingInfo release];
|
||||
return std::make_shared<MediaInfo>(paused, songTitle, songArtist, songAlbum, appNameString, thumbnailData,
|
||||
return std::make_shared<MediaInfo>(paused, songTitle, songArtist, songAlbum, appName, "",
|
||||
durationMs, elapsedTimeMs);
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e86d7a81de7a33323e2038182ab53a26c69f7880
|
||||
Subproject commit ca0091c80054e640cbc772160ec594d2ca361db3
|
Loading…
Reference in New Issue