您的位置:首页 > 移动开发 > IOS开发

iOS Remote Control

2016-03-04 18:00 453 查看


前言

RemoteControl,这里就翻译为远程控制吧。

远程控制是为用户提供操作App多媒体的。远程控制事件源于外部附件或由系统显示的传输控制,并通过媒体播放器框架的类传送到应用程序。播放音频或视频内容的应用程序使用这些事件来开始和停止播放,更改曲目,甚至速度的项目。所有的媒体应用程序应该支持这些事件。

除了支持远程控制事件,应用程序可以使用媒体播放器框架,以提供播放信息的曲目。该系统在适当的地方显示播放信息,如锁屏和控制中心。有关媒体播放器框架类的更多信息,见媒体播放器框架参考Media
Player Framework Reference.


Remote Control功能

RemoteControl可以用来在不打开app的情况下控制app中的多媒体播放,主要包括:

锁屏界面双击Home键后出现的播放操作区域

iOS7之后控制中心的播放操作区域

iOS7之前双击home键后出现的进程中向左滑动出现的播放操作区域

AppleTV,AirPlay中显示的播放操作区域

耳机线控

车载系统的设置


让App支持Remote Control

要接收远程控制事件,需要做到以下的几点:

接收者必须可以成为第一响应者;

接收者必须显示声明接收RemoteControl事件;

App必须是Now Playing App.

若应用程序还提供了正在播放的信息,使用
MPNowPlayingInfoCenter
对象在适当的时候更新信息。


效果图

类似网易云音乐锁屏状态下的Now Playing显示信息:




环境准备

要使App支持Remote Control,需要设置一下info.plist文件,添加required background modes,并添加一个值为:

1

2

3

App
plays
audio
or
streams
audio/video
using
AirPlay

接下来,播放音频之前先要设置AVAudioSession模式:

1

2

3

4

5

6

AVAudioSession
*session
=
[AVAudioSession
sharedInstance];

[session
setCategory:AVAudioSessionCategoryPlayAndRecord

withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker

error:nil];


扩展UIApplication作为第一响应者



在iOS上,响应者链如上图,由图可知,若其它视图没有处理,最终会传到UIApplication,因此使用UIApplication作为第一响应者是最合适的。

扩展头文件声明,我们在监听到对应的事件时,发送通知。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

//

// UIApplication+RemoteControl.h

// IOSAudioRemoteControl

//

// Created by huangyibiao
on 15/3/25.

// Copyright (c) 2015年
huangyibiao. All rights reserved.

//

#import <UIKit/UIKit.h>

// 播放

extern
NSString
*kRemoteControlPlayTapped;

// 暂停

extern
NSString
*kRemoteControlPauseTapped;

// 停止

extern
NSString
*kRemoteControlStopTapped;

// 前一首

extern
NSString
*kRemoteControlPreviousTapped;

// 后一首

extern
NSString
*kRemoteControlNextTapped;

// 其它

extern
NSString
*kRemoteControlOtherTapped;

@interface
UIApplication
(RemoteControl)

/**

* 注册对remote control事件的监听

*

* @param observer 监听者

* @param selector 回调

*/

-
(void)observeRemoteControl:(id)observer
selector:(SEL)selector;

@end

在实现文件中,我们需要处理监听:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

//

// UIApplication+RemoteControl.m

// IOSAudioRemoteControl

//

// Created by huangyibiao
on 15/3/25.

// Copyright (c) 2015年
huangyibiao. All rights reserved.

//

#import "UIApplication+RemoteControl.h"

const
NSString
*kRemoteControlPlayTapped
=
@"kRemoteControlPlayTapped";

const
NSString
*kRemoteControlPauseTapped
=
@"kRemoteControlPauseTapped";

const
NSString
*kRemoteControlStopTapped
=
@"kRemoteControlStopTapped";

const
NSString
*kRemoteControlPreviousTapped
=
@"kRemoteControlForwardTapped";

const
NSString
*kRemoteControlNextTapped
=
@"kRemoteControlBackwardTapped";

const
NSString
*kRemoteControlOtherTapped
=
@"kRemoteControlOtherTapped";

@implementation
UIApplication
(RemoteControl)

-
(BOOL)canBecomeFirstResponder
{

return
YES;

}

-
(void)remoteControlReceivedWithEvent:(UIEvent
*)event
{

switch
(event.subtype)
{

case
UIEventSubtypeRemoteControlPlay:

[self
postNotification:kRemoteControlPlayTapped];

break;

case
UIEventSubtypeRemoteControlPause:

[self
postNotification:kRemoteControlPauseTapped];

break;

case
UIEventSubtypeRemoteControlStop:

[self
postNotification:kRemoteControlStopTapped];

break;

case
UIEventSubtypeRemoteControlNextTrack:

[self
postNotification:kRemoteControlNextTapped];

break;

case
UIEventSubtypeRemoteControlPreviousTrack:

[self
postNotification:kRemoteControlPreviousTapped];

break;

default:

[self
postNotification:kRemoteControlOtherTapped];

break;

}

}

-
(void)postNotification:(const
NSString
*)notificationName
{

[[NSNotificationCenter
defaultCenter]

postNotificationName:(NSString
*)notificationName
object:nil];

}

-
(void)observeRemoteControl:(id)observer
selector:(SEL)selector
{

NSNotificationCenter
*center
=
[NSNotificationCenter
defaultCenter];

[center
addObserver:observer
selector:selector
name:(NSString
*)kRemoteControlNextTapped
object:nil];

[center
addObserver:observer
selector:selector
name:(NSString
*)kRemoteControlPauseTapped
object:nil];

[center
addObserver:observer
selector:selector
name:(NSString
*)kRemoteControlStopTapped
object:nil];

[center
addObserver:observer
selector:selector
name:(NSString
*)kRemoteControlPreviousTapped
object:nil];

[center
addObserver:observer
selector:selector
name:(NSString
*)kRemoteControlPlayTapped
object:nil];

[center
addObserver:observer
selector:selector
name:(NSString
*)kRemoteControlOtherTapped
object:nil];

}

@end


在播放audio视图中监听通知

在播放音频的界面,可以是在UIViewController里,也只可以是某个UIView里,因此在对应的类在创建或者初始化时调用监听:

1

2

3

4

5

UIApplication
*app
=
[UIApplication
sharedApplication];

[app
observeRemoteControl:self

selector:@selector(onRemoteControleStateChanged:)];

然后处理一下事件回调:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#pragma mark - remote control

-
(void)onRemoteControleStateChanged:(NSNotification
*)notification
{

if
([notification.name
isEqualToString:kRemoteControlPlayTapped])
{

[self
play];

}
else
if
([notification.name
isEqualToString:kRemoteControlPauseTapped])
{

[self
pause];

}
else
if
([notification.name
isEqualToString:kRemoteControlNextTapped])
{

[self
playNext];

}
else
if
([notification.name
isEqualToString:kRemoteControlPreviousTapped])
{

}
else
if
([notification.name
isEqualToString:kRemoteControlStopTapped])
{

[self
_requestPauseAudioPlaying:nil];

}
else
if
([notification.name
isEqualToString:kRemoteControlOtherTapped])
{

}

}


配置NowPlaying显示数据

要想在当前播放中心中显示当前播放的音频的信息,需要通过
MPNowPlayingInfoCenter
类,它是一个单例。我们要显示什么就在它的
nowPlayingInfo
属性中设置相关配置数据。

要使用这个类及其相关属性定义,需要引入这两个头文件:

1

2

3

4

#import <MediaPlayer/MPNowPlayingInfoCenter.h>

#import <MediaPlayer/MPMediaItem.h>

这里只设置几项,更多设置,请到MPMediaItem.h头文件中查看:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

NSMutableDictionary
*dict
=
[[NSMutableDictionary
alloc]
init];

// 设置歌曲播放时长

if
(self.time
!=
nil
&&
self.time.length
!=
0)
{

[dict
setObject:@(self.time.doubleValue)
forKey:MPMediaItemPropertyPlaybackDuration];

}

// 设置歌曲名称

if
(self.title
!=
nil
&&
self.title.length
!=
0)
{

[dict
setObject:self.title
forKey:MPMediaItemPropertyTitle];

}

// 设置锁屏时的图片

if
(self.iconView.image
&&
[self.iconView.image
isKindOfClass:[UIImage
class]])
{

MPMediaItemArtwork
*artwork
=
[[MPMediaItemArtwork
alloc]
initWithImage:self.iconView.image];

[dict
setObject:artwork
forKey:MPMediaItemPropertyArtwork];

}

[MPNowPlayingInfoCenter
defaultCenter].nowPlayingInfo
=
dict;

到此就可以实现我们远程控制的功能。不过这里只考虑实现,并不考虑什么时候接收,什么时候不再接收,而这里的做法时什么时候都接收远程控制。这此事就留给大家去学习吧!


源代码

大家可以到我的GITHUB下载demo:https://github.com/CoderJackyHuang/IOSAudioRemoteControl
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: