1+ #include < Foundation/NSObjCRuntime.h>
12#ifdef __APPLE__
23#include < AppKit/AppKit.h>
34#include < Cocoa/Cocoa.h>
45#include < Foundation/Foundation.h>
56#include < dispatch/dispatch.h>
67#include < filesystem>
8+ #include < nlohmann-json/single_include/nlohmann/json.hpp>
79#include < fstream>
810
9- #include " ../MediaRemote.hpp"
1011#include " ../backend.hpp"
1112
1213void hideDockIcon (bool shouldHide) {
@@ -16,64 +17,55 @@ void hideDockIcon(bool shouldHide) {
1617 [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
1718}
1819
19- std::shared_ptr<MediaInfo> backend::getMediaInformation () {
20- __block NSString *appName = nil ;
21- __block NSDictionary *playingInfo = nil ;
22-
23- dispatch_group_t group = dispatch_group_create ();
24-
25- dispatch_group_enter (group);
26- MRMediaRemoteGetNowPlayingApplicationPID (dispatch_get_main_queue (), ^(pid_t pid) {
27- if (pid > 0 ) {
28- NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier: pid];
29- if (app)
30- appName = [[app.bundleIdentifier copy ] retain ];
31- }
32- dispatch_group_leave (group);
33- });
34-
35- dispatch_group_enter (group);
36- MRMediaRemoteGetNowPlayingInfo (dispatch_get_main_queue (), ^(CFDictionaryRef result) {
37- if (result)
38- playingInfo = [[(__bridge NSDictionary *)result copy ] retain ];
39- dispatch_group_leave (group);
40- });
41-
42- dispatch_group_wait (group, DISPATCH_TIME_FOREVER);
43- dispatch_release (group);
44- if (appName == nil || playingInfo == nil )
45- return nullptr ;
20+ NSString * getFilePathFromBundle (NSString * fileName, NSString * fileType) {
21+ NSString *filePath = [[NSBundle mainBundle ] pathForResource: fileName ofType: fileType];
22+ return filePath;
23+ }
4624
47- bool paused = [playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoPlaybackRate ] intValue ] == 0 ;
25+ NSString * executeCommand (NSString * command, NSArray * arguments) {
26+ NSTask *task = [[NSTask alloc ] init ];
27+ task.launchPath = command;
28+ task.arguments = arguments;
4829
49- NSString *title = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoTitle ];
50- std::string songTitle = title ? [title UTF8String ] : " " ;
30+ NSPipe *pipe = [NSPipe pipe ];
31+ task.standardOutput = pipe;
32+ [task launch ];
5133
52- NSString *album = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoAlbum ];
53- std::string songAlbum = album ? [album UTF8String ] : " " ;
34+ NSData *data = [[pipe fileHandleForReading ] readDataToEndOfFile ];
35+ NSString *output = [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
36+ [task waitUntilExit ];
37+
38+ return output;
39+ }
5440
55- NSString *artist = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtist ];
56- std::string songArtist = artist ? [artist UTF8String ] : " " ;
41+ std::shared_ptr<MediaInfo> backend::getMediaInformation () {
42+ static NSString * script = getFilePathFromBundle (@" MediaRemote" , @" scptd" );
43+ NSString * output = executeCommand (@" /usr/bin/osascript" , @[script]);
44+ nlohmann::json j = nlohmann::json::parse ([output UTF8String ]);
5745
58- NSData *artworkData = playingInfo[(__bridge NSString *)kMRMediaRemoteNowPlayingInfoArtworkData ];
46+ std::string appName = j[" player" ].get <std::string>();
47+ if (appName == " none" )
48+ return nullptr ;
5949
60- std::string thumbnailData;
61- if (artworkData)
62- thumbnailData = std::string ((const char *)[artworkData bytes ], [artworkData length ]);
50+ bool paused = j[" playbackStatus" ].get <std::string>() == " 0" ;
6351
64- NSNumber *elapsedTimeNumber = playingInfo[(__bridge NSString *) kMRMediaRemoteNowPlayingInfoElapsedTime ] ;
52+ std::string songTitle = j[ " title " ]. get <std::string>() ;
6553
66- NSNumber *durationNumber = playingInfo[(__bridge NSString *) kMRMediaRemoteNowPlayingInfoDuration ] ;
54+ std::string songAlbum = j[ " album " ]. get <std::string>() ;
6755
68- int64_t elapsedTimeMs = elapsedTimeNumber ? static_cast < int64_t >([elapsedTimeNumber doubleValue ] * 1000 ) : 0 ;
56+ std::string songArtist = j[ " artist " ]. get <std::string>() ;
6957
70- int64_t durationMs = durationNumber ? static_cast <int64_t >([durationNumber doubleValue ] * 1000 ) : 0 ;
58+ int64_t elapsedTimeMs = 0 ;
59+ int64_t durationMs = 0 ;
60+ try {
61+ double durationNumber = std::stod (j[" duration" ].get <std::string>());
62+ durationMs = static_cast <int64_t >(durationNumber * 1000 );
7163
72- std::string appNameString = appName.UTF8String ;
64+ double elapsedTimeNumber = std::stod (j[" elapsed" ].get <std::string>());
65+ elapsedTimeMs = static_cast <int64_t >(elapsedTimeNumber * 1000 );
66+ } catch (...) {}
7367
74- [appName release ];
75- [playingInfo release ];
76- return std::make_shared<MediaInfo>(paused, songTitle, songArtist, songAlbum, appNameString, thumbnailData,
68+ return std::make_shared<MediaInfo>(paused, songTitle, songArtist, songAlbum, appName, " " ,
7769 durationMs, elapsedTimeMs);
7870}
7971
0 commit comments