Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
using a C function
-
@mikael, Yes I have looked at the documentation, though the example only works for the stock application. Also the function I eluded to is not a class method, but a function. I’m looking into ctypes, but I dont know how to pass a dispatch queue or a completion block to it, As I’m not too familiar with ctypes.
-
Currently I was able to test the framework by calling "c.MRMediaRemoteSendComman(2, 0)" but the closest I got to calling "MRMediaRemoteGetNowPlayingInfo" was with this code:
from objc_util import * from ctypes import * import ctypes c = ctyles.CDLL(None) MRMediaRemoteGetNowPlayingInfo = c.MRMediaRemoteGetNowPlayingInfo MRMediaRemoteGetNowPlayingInfo .restype = c_void_p MRMediaRemoteGetNowPlayingInfo .argtypes = [c_void_p, c_void_p] queue = c.dispatch_get_current_queue info = c_void_p() MRMediaRemoteGetNowPlayingInfo(queue, byref(info)) print(objcCInstance(info))
But this just crashes the app, i'm pretty sure the problem is with the queue, but i'm not able to call "dispatch_get_main_queue" because its just says its unable to find the symbol.
Again, any help would be great!
-
Do you have the faulthandler by @dgelessus installed? Always handy when you see the ObjC exception and do not have to guess.
-
@arandomperson, have you tried loading the framework in a similar manner to this?
NSBundle.bundle(Path="/System/Library/Frameworks/MultipeerConnectivity.framework").load() MCPeerID = ObjCClass('MCPeerID') MCSession = ObjCClass('MCSession')
You could also check the rest of the Multipeer code for a reference on how to handle completion blocks. Unfortunately I cannot help you with details, as that part of the code was contributed whole cloth by @JonB.
-
Typo “ctyles” of any consequence here?
-
@MartinPacker I suppose he did manually recopy his code without copying/pasting it because this short code has directly an error "NameError: name 'ctyles' is not defined"
But, well seen anyway
-
Fauthandler gives Fatal Python error: Segmentation fault in line
MRMediaRemoteGetNowPlayingInfo(queue, byref(info))
-
You can't go guessing arguments. Look at the headers. That function takes a dispatch queue (which you forgot to call the function to get the queue) and an ObjCBlock, which takes ine argument, a dictionary that has the info you want.
Here is a simple bit to get the dictionary. note the values are usually objc types, so you may need to convert to more useful values. Explore the now_playing_dict.keys to see what you have accessible.
from objc_util import * from ctypes import * import ctypes MRMediaRemoteGetNowPlayingInfo = c.MRMediaRemoteGetNowPlayingInfo MRMediaRemoteGetNowPlayingInfo.restype = None MRMediaRemoteGetNowPlayingInfo.argtypes = [c_void_p, ObjCBlock] now_playing_dict={} from threading import Event e=Event() def info_cb(_blk,info): now_playing_dict.clear() if info: infodict=ObjCInstance(info) for k in infodict.allKeys(): now_playing_dict[str(k)]= infodict[k] e.set() cb=ObjCBlock(info_cb,argtypes=[c_void_p,c_void_p], restype=None) q=ObjCInstance(c.dispatch_get_current_queue()) MRMediaRemoteGetNowPlayingInfo(q, cb) #since the callback happens in another thread, we wait for the event to be set e.wait() print(now_playing_dict['kMRMediaRemoteNowPlayingInfoTitle'])
-
@JonB Thanks for the help, I did manage to get it working by studying a couple of examples, but your code looks so much nicer.
-
@mikael faulthandler seems really useful, Thanks!