锁屏界面音频控制

 1、在文件APPDelegate.m里,实现方法“- (void)remoteControlReceivedWithEvent:(UIEvent *)event”的重写,用来接收控制中心的事件。

 1 //  在APPDelegate.m中声明一个通知事件的key
 2 NSString *const AppDelegateReceiveRemoteEventsNotification = @"AppDelegateReceiveRemoteEventsNotification";
 3  4 /// 锁屏页面的控制事件(必须在这里重写该方法,在播放页面重写不起作用)
 5 - (void)remoteControlReceivedWithEvent:(UIEvent *)event {
 6   if (event.type == UIEventTypeRemoteControl) {
 7     // 发送通知给音频播放界面 进行某些处理
 8     [[NSNotificationCenter defaultCenter] postNotificationName:AppDelegateReceiveRemoteEventsNotification object:event];
 9   }
10 }

Appdelegate里就设置这些。

 

2、在音频播放界面

  1 // 设置控制中心交互需要导入
  2 #import <MediaPlayer/MediaPlayer.h>
  3  
  4 /// 注册通知
  5 - (void) registerAllNotifications {
  6     // 后台通知
  7     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(apllicationWillResignActiveNotification:) name:UIApplicationWillResignActiveNotification object:nil];
  8   9     // 进入前台通知
 10     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(apllicationWillEnterForegroundNotification:) name:UIApplicationWillEnterForegroundNotification object:nil];
 11     
 12     // 锁屏界面事件
 13     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(AppDelegateReceiveRemoteEventsNotification:) name:AppDelegateReceiveRemoteEventsNotification object:nil];
 14 }
 15  16  17 #pragma mark - 通知方法实现
 18 /// 进入后台
 19 - (void) apllicationWillResignActiveNotification:(NSNotification *)n {
 20     NSError *error = nil;
 21     // 后台播放代码
 22     AVAudioSession *session = [AVAudioSession sharedInstance];
 23     [session setActive:YES error:&error];
 24     if(error) {
 25         // NSLog(@"ListenPlayView background error0: %@", error.description);
 26     }
 27     [session setCategory:AVAudioSessionCategoryPlayback error:&error];
 28     if(error) {
 29         // NSLog(@"ListenPlayView background error1: %@", error.description);
 30     }
 31     
 32     /// 进后台 设置接收远程控制
 33     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
 34     
 35     // 上面代码实现后台播放 几分钟后会停止播放
 36     // 添加任务id 实现后台连续播放
 37     backTaskID = [self backgroundPlayerID:backTaskID];
 38 }
 39  40 // 实现一下backgroundPlayerID:这个方法:
 41 - (UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId {
 42     NSError *error = nil;
 43     // 设置并激活音频会话类别
 44     AVAudioSession *session = [AVAudioSession sharedInstance];
 45     [session setCategory:AVAudioSessionCategoryPlayback error:nil];
 46     if(error) {
 47         NSLog(@"ListenPlayView background error2: %@", error.description);
 48     }
 49     [session setActive:YES error:nil];
 50     if(error) {
 51         NSLog(@"ListenPlayView background error3: %@", error.description);
 52     }
 53     
 54     // 设置后台任务ID
 55     UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
 56     newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
 57     if(newTaskId != UIBackgroundTaskInvalid && backTaskId != UIBackgroundTaskInvalid) {
 58         [[UIApplication sharedApplication] endBackgroundTask:backTaskId];
 59     }
 60     
 61     return newTaskId;
 62 }
 63  64  65 /// 进入前台通知
 66 - (void) apllicationWillEnterForegroundNotification:(NSNotification *)n {
 67     // 进前台 设置不接受远程控制
 68     [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
 69 }
 70  71 /// 远程控制事件通知
 72 - (void)AppDelegateReceiveRemoteEventsNotification:(NSNotification*)noti {
 73     if (!noti) return;
 74     if (!noti.object) return;
 75     if (![noti.object isKindOfClass:[UIEvent class]]) return;
 76     
 77     UIEvent *event = (UIEvent *)noti.object;
 78     if (event.type == UIEventTypeRemoteControl) {
 79         // 根据远程控制事件类型,在播放界面设置播放、暂停、下一个、上一个
 80         switch (event.subtype) {
 81             case UIEventSubtypeRemoteControlPlay:
 82                 // play
 83                 break;
 84             case UIEventSubtypeRemoteControlPause:
 85                 // pause
 86                 break;
 87             case UIEventSubtypeRemoteControlNextTrack:
 88                 // next
 89                 break;
 90             case UIEventSubtypeRemoteControlPreviousTrack:
 91                 // last
 92                 break;
 93             default: break;
 94         }
 95     }
 96 }
 97  
 98 /// 移除所有通知
 99 - (void)removeAllNotifications {
100     [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
101 102     [[NSNotificationCenter defaultCenter] removeObserver:self name:AppDelegateReceiveRemoteEventsNotification object:nil];
103 104     [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
105 }

上面这些实现了控制中心和播放界面的交互。此时,控制中心还没有显示当前播放的音频信息(嗯,我还没有设置)。如下:

 1 /// 设置锁屏界面的播放音频的相关信息
 2 /// 可在适当时机调用该方法(开始播放时、将要进入后台、音频切换)
 3 - (void) setupNowPlayingAudioInfo {
 4     /** 设置信息的类型
 5      *  MPMediaItemPropertyAlbumTitle : 专辑名
 6      *  MPMediaItemPropertyAlbumTrackCount : 专辑个数
 7      *  MPMediaItemPropertyAlbumTrackNumber : 当前播放的专辑位置
 8      *  MPMediaItemPropertyArtist : 艺术家
 9      *  MPMediaItemPropertyArtwork : 封面
10      *  MPMediaItemPropertyComposer : 作曲家
11      *  MPMediaItemPropertyDiscCount  : 迪斯科 数量
12      *  MPMediaItemPropertyDiscNumber : 当前位置
13      *  MPMediaItemPropertyGenre : 流派
14      *  MPMediaItemPropertyPersistentID : ID
15      *  MPMediaItemPropertyPlaybackDuration : 后台播放时长
16      *  MPMediaItemPropertyTitle : 标题
17      */
18     
19     NSMutableDictionary *songDict = [NSMutableDictionary dictionary];
20     
21     // 音频名字
22     [songDict setObject:@"她来听我的演唱会"  forKey:MPMediaItemPropertyTitle];
23     
24     // 歌手
25     [songDict setObject:@"张学友"  forKey:MPMediaItemPropertyArtist];
26     
27     // 歌曲的总时间
28     [songDict setObject:@(200) forKeyedSubscript:MPMediaItemPropertyPlaybackDuration];
29     
30     // 当前时间
31     [songDict setObject:@(30) forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
32     
33     // 播放速率
34     [songDict setObject:@(1.0) forKey:MPNowPlayingInfoPropertyPlaybackRate];
35     
36     // 锁屏音频封面
37     MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"封面.png"]];
38     [songDict setObject:artwork forKey:MPMediaItemPropertyArtwork];
39     
40     // 设置控制中心歌曲信息
41     [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songDict];
42 }

这时,锁屏界面已经可以显示音频对应的信息了。

 

还有最后一步设置(动态设置控制中心的按钮状态),如:当前播放的音频是播放列表最后一条,设置控制中心的下一个按钮不可点击。。。

 1 /// 设置控制中心的按钮状态(保持与播放界面对应按钮状态一致)
 2 /// 调用时机(如切换音频时,设置锁屏界面音频信息时)
 3 - (void) setupRemoteControlButtonStatus {
 4     // 只有设置了target 才能设置控制中心(锁屏界面)的按钮状态
 5     
 6     // 设置控制中心下一个按钮 和播放页面的下一个按钮状态同步
 7     MPRemoteCommand *next = [MPRemoteCommandCenter sharedCommandCenter].nextTrackCommand;
 8     next.enabled = self.nextButton.enabled;
 9     [next addTarget:self action:@selector(remoteCommandAction:)];
10     
11     // 设置控制中心上一个按钮 和播放页面的上一个按钮状态同步
12     MPRemoteCommand *last = [MPRemoteCommandCenter sharedCommandCenter].previousTrackCommand;
13     last.enabled = self.theLastButton.enabled;
14     [last addTarget:self action:@selector(remoteCommandAction:)];
15     
16     // 设置控制中心播放|暂停按钮 和 播放页面的播放|暂停按钮状态同步
17     MPRemoteCommand *play = [MPRemoteCommandCenter sharedCommandCenter].playCommand;
18     play.enabled = self.playButton.enabled;
19     [play addTarget:self action:@selector(remoteCommandAction:)];
20     
21     MPRemoteCommand *pause = [MPRemoteCommandCenter sharedCommandCenter].pauseCommand;
22     pause.enabled = self.playButton.enabled;
23     [pause addTarget:self action:@selector(remoteCommandAction:)];
24 }
25 26 /// 实现target action
27 - (void)remoteCommandAction:(MPRemoteCommand *)com {
28     // 这里不用具体做些什么 do nothing..
29     // 控制中心的事件已经在通知AppDelegateReceiveRemoteEventsNotification里实现了
30 }
原文地址:https://www.cnblogs.com/mustard22/p/11091309.html