先上效果图:
在控制中心显示歌曲信息 在锁屏界面显示歌曲信息
接下来看看实现细节:
1.首先打开后台播放模式
设置后台模式在didFinishLaunchingWithOptions:方法中,开启接收远程控制,加入如下代码:
[[UIApplication sharedApplication]beginReceivingRemoteControlEvents];
2.在程序即将失去焦点applicationWillResignActive:时,开启后台播放:
<pre>
-(void)applicationWillResignActive:(UIApplication *)application
{
AVAudioSession *session=[AVAudioSession sharedInstance];
[session setActive:YES error:nil];
//后台播放
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
}</pre>
3.在AppDelegate中实现处理接收到远程控制的方法remoteControlReceivedWithEvent:并在发送接收到远程控制的通知。
<pre>
-(void)remoteControlReceivedWithEvent:(UIEvent *)event
{
if(event.type==UIEventTypeRemoteControl)
{
NSInteger order=-1;
switch (event.subtype) {
case UIEventSubtypeRemoteControlPause:
order=UIEventSubtypeRemoteControlPause;
break;
case UIEventSubtypeRemoteControlPlay:
order=UIEventSubtypeRemoteControlPlay;
break;
case UIEventSubtypeRemoteControlNextTrack:
order=UIEventSubtypeRemoteControlNextTrack;
break;
case UIEventSubtypeRemoteControlPreviousTrack:
order=UIEventSubtypeRemoteControlPreviousTrack;
break;
case UIEventSubtypeRemoteControlTogglePlayPause:
order=UIEventSubtypeRemoteControlTogglePlayPause;
break;
default:
order=-1;
break;
}
NSDictionary *orderDict=@{@"order":@(order)};
[[NSNotificationCenter defaultCenter] postNotificationName:kAppDidReceiveRemoteControlNotification object:nil userInfo:orderDict];
}
}</pre>
4.在音乐播放器所在的控制器中,做如下处理:
<pre>
-->在ViewDidLoad中注册接收到远程控制的通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(listeningRemoteControl:) name:kAppDidReceiveRemoteControlNotification object:nil];
-->并实现接收到通知的方法
-(void)listeningRemoteControl:(NSNotification *)sender
{
NSDictionary *dict=sender.userInfo;
NSInteger order=[[dict objectForKey:@"order"] integerValue];
switch (order) {
//暂停
case UIEventSubtypeRemoteControlPause:
{
UIButton * stateButton = (id)[self.view viewWithTag:STATE_BUTTON_TAG];
[self onClickChangeState:stateButton];
break;
}
//播放
case UIEventSubtypeRemoteControlPlay:
{
UIButton * stateButton = (id)[self.view viewWithTag:STATE_BUTTON_TAG];
[self onClickChangeState:stateButton];
break;
}
//暂停播放切换
case UIEventSubtypeRemoteControlTogglePlayPause:
{
UIButton * stateButton = (id)[self.view viewWithTag:STATE_BUTTON_TAG];
[self onClickChangeState:stateButton];
break;
}
//下一首
case UIEventSubtypeRemoteControlNextTrack:
{
[self next];
break;
}
//上一首
case UIEventSubtypeRemoteControlPreviousTrack:
{
[self previous];
break;
}
default:
break;
}
}
-->下面是关于播放、暂停、上一首、下一首的参考代码:
//播放状态改变
-(void)onClickChangeState:(UIButton *)button
{
if(self.model)
[self setNowPlayingInfo];
if (!_played)
{
[self.playView.player play];
button.selected = YES;
}
else
{
[self.playView.player pause];
button.selected = NO;
}
_played = !_played;
}
pragma mark - 下一首
//播放下一首
-(void)next
{
UIButton * stateButton = (id)[self.view viewWithTag:PLAYSTOP_BUTTON_TAG];
stateButton.enabled = NO;
stateButton.selected=NO;
_currentWordRow=0;
NSInteger songIndex=[self.songArray indexOfObject:self.model];
if(songIndex<self.songArray.count-1)
{
self.model=[self.songArray objectAtIndex:songIndex+1];
}
else
{
self.model=[self.songArray objectAtIndex:0];
}
[self refresh];
}
pragma mark - 上一首
-(void)previous
{
UIButton * stateButton = (id)[self.view viewWithTag:PLAYSTOP_BUTTON_TAG];
stateButton.enabled = NO;
stateButton.selected=NO;
_currentWordRow=0;
NSInteger songIndex=[self.songArray indexOfObject:self.model];
if(songIndex>0)
{
self.model=[self.songArray objectAtIndex:songIndex-1];
}
else
{
self.model=self.songArray.lastObject;
}
[self refresh];
}
//刷新
-(void)refresh
{
mvListModel * model=nil;
if ([self.model.mvListArray count])
{
model= [self.model.mvListArray firstObject];
}
NSURL *url=nil;
if(model.picUrl.length>0)
url=[NSURL URLWithString:model.picUrl];
if(url)
{
UIImageView *smiv=(UIImageView *)[self.view viewWithTag:kSingerImageTag];
[smiv sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"defaultNomusic.png"]];
}
UILabel *songNameLb=(UILabel *)[self.view viewWithTag:kSongNameTag];
UILabel *singerNameLb=(UILabel *)[self.view viewWithTag:kSingerNameTag];
songNameLb.text=self.model.name;
singerNameLb.text=self.model.singerName;
auditionListModel * auModel = [[auditionListModel alloc] init];
if(self.model.auditionArray.count>0)
auModel = self.model.auditionArray[0];
if (self.model.auditionArray.count >= 2) {
auModel = self.model.auditionArray[1];
}
self.sourceURLString=auModel.url;
//音乐播放部分
NSURL * videoUrl = [NSURL URLWithString:auModel.url];
//先移除observer
[self.playerItem removeObserver:self forKeyPath:@"status"];
[self.playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
self.playerItem = [AVPlayerItem playerItemWithURL:videoUrl];
//监听status属性
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
//监听loadedTimeRanges
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
self.playView.player = self.player;
//播放结束 通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
[self loadLyric];
}
-->开始播放,在播放中心设置歌曲的相关信息,如歌名歌手
pragma mark -设置控制中心正在播放的信息
-(void)setNowPlayingInfo
{
NSMutableDictionary *songDict=[NSMutableDictionary dictionary];
//歌名
[songDict setObject:self.model.name forKey:MPMediaItemPropertyTitle];
//歌手名
[songDict setObject:self.model.singerName forKey:MPMediaItemPropertyArtist];
//歌曲的总时间
[songDict setObject:[NSNumber numberWithDouble:CMTimeGetSeconds(self.playerItem.duration)] forKeyedSubscript:MPMediaItemPropertyPlaybackDuration];
//设置歌曲图片
MPMediaItemArtwork *imageItem=[[MPMediaItemArtwork alloc]initWithImage:_singerImageView.image];
[songDict setObject:imageItem forKey:MPMediaItemPropertyArtwork];
//设置控制中心歌曲信息
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songDict];
}
-->并在播放过程中,改变播放进度,播放时间的逻辑中加入如下代码,更新控制中心歌曲的当前时间:
NSDictionary *info=[[MPNowPlayingInfoCenter defaultCenter] nowPlayingInfo];
NSMutableDictionary *dict=[NSMutableDictionary dictionaryWithDictionary:info];
[dict setObject:@(currentSecond) forKeyedSubscript:MPNowPlayingInfoPropertyElapsedPlaybackTime];
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
</pre>
网友评论
你在通知里写的“ kAppDidReceiveRemoteControlNotification”是什么意思??定义的是宏吗??请帖一下这段代码,谢谢了