博客> iOS-五脏俱全的在线音乐播放器Demo
iOS-五脏俱全的在线音乐播放器Demo
2019-10-16 14:56 评论:0 阅读:1152 Arron_Zhang
ios

前言

最近在做项目的时候需要用到一个在线的音乐播放器, 但是这个音乐播放器只需要播放一首歌, 而且要求能快进快退, 由于比较简单, 适合初学者学习, 所以我特意封装了一下, 并写了一个小小的demo, 代码都在github上, 众多iOS学习爱好者有兴趣的话可以前往下载. github地址

特点

  • 体量小
  • 简单易用
  • 支持单首歌曲的播放,快进,快退
  • 支持播放进度条的拖动以及点击

使用方法

  1. 下载并复制KHPlayer文件夹下的源代码到你的工程目录
    • 注意:如果想使用原资源图片, 一定要把Assets里的图片一起复制过去
  2. 初始化KHPlayer, 赋值Frame, 并添加到当前视图中
    KHPlayer *player = [[KHPlayer alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.view.frame) - 70, CGRectGetWidth(self.view.frame),70)];
    [self.view addSubview:player];
  3. 设置相关的UI属性

     [player setSliderThumbImage:[UIImage imageNamed:@"yinpinThumb"]];
      [player enableMasksToBoundsOfSlider];
      [player setBgColor:[UIColor whiteColor]];
  4. 设置要播放的在线音频URL的String值, 并调用play方法进行播放
    [player setURLString: kInterface1];
       [player play];

完成以上操作后得到的效果如下:

后续工作

  • 添加播放本地音频的接口
  • 添加连续播放多首歌的功能

核心代码

其实最核心的代码是给播放器添加KVO监听事件, 所以在这里只展示这部分代码

//添加在线播放的音频URL
- (void)setURLString:(NSString *)urlString{
    _urlString = urlString;
    
    if (self.currentItem) {
        [self.currentItem removeObserver:self forKeyPath:@"status"];
        [self.currentItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
        [self.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
        self.currentItem = nil;
    }
    if (self.player) {
        self.player = nil;
    }
    if (self.progressSlider) {
        self.progressSlider.value = 0;
    }
    
    //给playerItem添加KVO事件
    self.currentItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:urlString]];
    [self.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [self.currentItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
    [self.currentItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    
    self.player = [[AVPlayer alloc] initWithPlayerItem:self.currentItem];
}
/*
 使用KVO监听播放状态
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"status"])
    {
        //准备播放
        if ([change[NSKeyValueChangeNewKey] integerValue] == AVPlayerItemStatusReadyToPlay)
        {
            self.duration = CMTimeGetSeconds(self.currentItem.duration);
            self.rightTimeLabel.text = [self timeFormatWithTimtInterval:_duration];
            [self updatePlayerProgress];
            [self hideLoadingView];
            [self enableButtons];
        }
        else if ([change[NSKeyValueChangeNewKey] integerValue] == AVPlayerItemStatusFailed)
        {
            [self showLoadingView];
            [self disableButtons];
            NSLog(@"播放失败");
        }
        else if ([change[NSKeyValueChangeNewKey] integerValue] == AVPlayerItemStatusUnknown)
        {
            [self showLoadingView];
            [self disableButtons];
            NSLog(@"未知错误");
        }
        
    }
    else if ([keyPath isEqualToString:@"playbackBufferEmpty"])
    {
        if (self.currentItem.playbackBufferEmpty) {
            [self showLoadingView];
            self.progressSlider.value = 0;
            [self disableButtons];
        }
    }
    else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"])
    {
        [self showLoadingView];
        
        if (self.currentItem.playbackLikelyToKeepUp) {
            [self hideLoadingView];
            [self enableButtons];
        }
    }
}
/*
 设置定时器,更新播放状态
 */
- (void)updatePlayerProgress{
    __weak typeof(self) weakSelf = self;
    [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.5, NSEC_PER_SEC) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
    //更新左右的时间Label, 修改进度条进度(这里要用weakSelf来防止循环引用)
        CGFloat currentTime = CMTimeGetSeconds(weakSelf.currentItem.currentTime);
        weakSelf.currentTime = currentTime;
        weakSelf.leftTimeLabel.text = [weakSelf timeFormatWithTimtInterval:currentTime];
        
        CGFloat leftTime = weakSelf.duration - currentTime;
        weakSelf.rightTimeLabel.text = [weakSelf timeFormatWithTimtInterval:leftTime];
        weakSelf.progressSlider.value = currentTime / weakSelf.duration;
    }];
}

写在结尾的话

有兴趣了解所有代码和Demo的朋友, 还是那句话, 可以去我github地址下载. 觉得还不错的话不妨给我点个星哈~本人学iOS时间不长, 说白了也还是个初学者,如果觉得代码哪里有问题,或者有新的的需求想添加上去,欢迎留下你的评论.

收藏
0
sina weixin mail 回到顶部