美文网首页音乐iOS个人修养IOS
iOS开发在控制中心及锁屏状态下,显示歌曲信息

iOS开发在控制中心及锁屏状态下,显示歌曲信息

作者: CGPointZero | 来源:发表于2015-12-14 16:21 被阅读2387次

    先上效果图:


    在控制中心显示歌曲信息 在锁屏界面显示歌曲信息

    接下来看看实现细节:

    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>

    相关文章

      网友评论

      • 冰三尺:请问下楼主,我在锁屏时,点击暂停,暂停播放,回到App 时再点击播放,音乐播放没有了声音,这个是什么情况?
      • CYC666:what is MPNowPlayingInfoCenter? Cann't find.
      • ZeroSmell: :smile: 遛遛
      • 我常常问自己我是谁:
        你在通知里写的“ kAppDidReceiveRemoteControlNotification”是什么意思??定义的是宏吗??请帖一下这段代码,谢谢了
        CGPointZero:@我常常问自己我是谁 那就是一个通知名而已
      • b4d2ee94b21f:我想请问下 为什么我同样的代码没有锁屏显示的效果,我看了好多网上代码下下来都没有锁屏显示的效果,是苹果改了锁屏的显示机制了吗? 你知道新的机制吗?
        CGPointZero:肯定是你哪里没写好,我这边好好的

      本文标题:iOS开发在控制中心及锁屏状态下,显示歌曲信息

      本文链接:https://www.haomeiwen.com/subject/blduhttx.html