iOS之基于FreeStreamer的简单音乐播放器示例

2020-01-21 02:24:13于海丽

beginReceivingRemoteControlEvents为允许传递远程控制事件,remoteControlReceivedWithEvent为接收一个远程控制事件,关于控制事件的类型,在代码中,已经注释过,这里就不再说了。

控制事件搞定了,剩下的就是界面的展示了,主要是歌曲信息的展示,通过如下的代码就能实现


    NSMutableDictionary *musicInfoDict = [[NSMutableDictionary alloc] init];
    //设置歌曲题目
    [musicInfoDict setObject:self.currentTitle forKey:MPMediaItemPropertyTitle];
    //设置歌手名
    [musicInfoDict setObject:@"" forKey:MPMediaItemPropertyArtist];
    //设置专辑名
    [musicInfoDict setObject:@"" forKey:MPMediaItemPropertyAlbumTitle];
    //设置歌曲时长
    [musicInfoDict setObject:[NSNumber numberWithFloat:totalTime]
             forKey:MPMediaItemPropertyPlaybackDuration];
    //设置已经播放时长
    [musicInfoDict setObject:[NSNumber numberWithFloat:currentTime]
             forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
    
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:musicInfoDict];

关于歌曲信息的设置,可以不按照我这样,定时器中时刻进行刷新,只需要在播放、暂停、快进快退这些时间有变化的地方传入当前歌曲的关键信息就可以,系统会自动去根据播放情况去更新锁屏界面上的进度条,而不需要我们时刻传入当前播放时间。这里我为了偷懒,就加在里面了。为了防止频繁操作,我采取了个方法,在其他地方看到的,就是监听锁屏情况


 //监听锁屏状态 lock=1则为锁屏状态
  uint64_t locked;
  __block int token = 0;
  notify_register_dispatch("com.apple.springboard.lockstate",&token,dispatch_get_main_queue(),^(int t){
  });
  notify_get_state(token, &locked);
  
  //监听屏幕点亮状态 screenLight = 1则为变暗关闭状态
  uint64_t screenLight;
  __block int lightToken = 0;
  notify_register_dispatch("com.apple.springboard.hasBlankedScreen",&lightToken,dispatch_get_main_queue(),^(int t){
  });
  notify_get_state(lightToken, &screenLight);

通过该情况来设置。

在上面锁屏播放的过程中,出现一个问题,就是当我切换歌曲的时候,不管是在锁屏情况下,还是在app内

通过各种查找,大概找到问题,首先在appdelegate中将[session setActive:YES error:nil]改成了[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil],然后再播放的地方加了一个[self stop],先停止播放


- (void)playFromURL:(NSURL *)url
{
  //根据地址 在本地找歌词
  NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"musiclist" ofType:@"plist"]];
  for (NSString *playStringKey in dic.allKeys) {
    if ([[dic valueForKey:playStringKey] isEqualToString:url.absoluteString]) {
      self.currentTitle = playStringKey;
      break;
    }
  }
  
  [self stop];
  if (![url.absoluteString isEqualToString:self.url.absoluteString]) {
    [super playFromURL:url];
  }else{
    [self play];
  }