让Mac程序支持键盘iTunes控制和AppleRemote控制

对于iPod的话方法实在是太简单了,因为iOS都内置有完整的remote控制(耳机线控)API,直接使用
- (void)remoteControlReceivedWithEvent:(UIEvent *)event就可以了。
但是Mac上并没有给出这个API(NSEvent并没有这方面的说明,看起来是私有API),所以必须另外想办法。
为了这个咱查找了很多资料,非常恶心的是网上居然几乎都没有这方面的教程。
最后从Mac上比较强大的播放软件VLC的源代码入手,终于找到了remote控制的方法。

如果开启了ARC的话会报错,那么就在Xcode的project的Target里的Build Phases,在下面的Compile Sources里面找到提示ARC报错的文件,双击他们并填上-fno-objc-arc。然后重新编译即可~

AppleRemote也就是红外线遥控器部分比较简单,但是代码似乎是VLC针对自己而写的,虽然可以直接移植过去之后使用,但是需要修改过才可以,于是咱自行进行修改,屏蔽掉了VLC自有的部分(似乎是为了错误提示做的log,并没有太大用途)。于是文件下载在这里:戳我啊!来戳啊!
下载之后将2个文件导入到project,并#import “AppleRemote.h”。
接下来在头文件里创建AppleRemote *appleremote;
然后在m文件里进行初始化并且设置其开始监听:

appleremote = [[AppleRemote alloc] init];
[appleremote setClickCountEnabledButtons: kRemoteButtonPlay];
[appleremote setDelegate:self];
[appleremote startListening: self];

然后就到了重点:接收到按键操作之后

- (void) appleRemoteButton: (AppleRemoteEventIdentifier)buttonIdentifier
pressedDown: (BOOL) pressedDown
clickCount: (unsigned int) count
{
switch( buttonIdentifier )
{
case k2009RemoteButtonFullscreen:
//似乎是进入全屏模式
break;
case k2009RemoteButtonPlay:
//开始播放
break;
case kRemoteButtonPlay:
//开始播放
break;
case kRemoteButtonVolume_Plus:
//上按键,同音量+
break;
case kRemoteButtonVolume_Minus:
//下按键,同音量-
break;
case kRemoteButtonRight:
//右按键,同下一曲
break;
case kRemoteButtonLeft:
//左按键,同上一曲
break;
case kRemoteButtonRight_Hold:
//右按键一直按,同快进
break;
case kRemoteButtonLeft_Hold:
//左按键一直按,同快退
break;
case kRemoteButtonVolume_Plus_Hold:
//上按键一直按
break;
case kRemoteButtonVolume_Minus_Hold:
//下按键一直按,同静音
break;
case kRemoteButtonMenu:
//目录(menu)按键按下
break;
case kRemoteButtonPlay_Sleep:
//播放键一直按,同进入睡眠模式
break;
default:
/* Add here whatever you want other buttons to do */
break;
}
}

到这里AppleRemote已经可以正常工作了,剩下的就看自己的需要修改代码了。

而键盘上的iTunes播放控制键虽然同样没有API,但是却有公开的代码实现,可访问Media keys hook in Mac OS X来下载代码和例子。
使用方法和上面的remote差不多,同样是import之后设置为SPMediaKeyTap *keyTap;接着init:

[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:[SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers], kMediaKeyUsingBundleIdentifiersDefaultsKey,nil]];
keyTap = [[SPMediaKeyTap alloc] initWithDelegate:self];
if([SPMediaKeyTap usesGlobalMediaKeyTap])
[keyTap startWatchingMediaKeys];
else
NSLog(@"Media key monitoring disabled");

而方法官方也在例子中给出了:

-(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event;
{
NSAssert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys, @"Unexpected NSEvent in mediaKeyTap:receivedMediaKeyEvent:");
int keyCode = (([event data1] & 0xFFFF0000) >> 16);
int keyFlags = ([event data1] & 0x0000FFFF);
BOOL keyIsPressed = (((keyFlags & 0xFF00) >> 8)) == 0xA;
//int keyRepeat = (keyFlags & 0x1);
if (keyIsPressed) {
switch (keyCode) {
case NX_KEYTYPE_PLAY:
//播放键按下
break;
case NX_KEYTYPE_FAST:
//下一首按下
break;
case NX_KEYTYPE_REWIND:
//上一首按下
break;
default:
break;
}
}
}

如果对上面2个方法有问题的可以留言或者单独联系咱~