前言
最近在做項(xiàng)目的時候需要用到一個在線的音樂播放器, 但是這個音樂播放器只需要播放一首歌, 而且要求能快進(jìn)快退, 由于比較簡單, 適合初學(xué)者學(xué)習(xí), 所以我特意封裝了一下, 并寫了一個小小的demo, 代碼都在github上, 眾多iOS學(xué)習(xí)愛好者有興趣的話可以前往下載. github地址
特點(diǎn)
- 體量小
- 簡單易用
- 支持單首歌曲的播放,快進(jìn),快退
- 支持播放進(jìn)度條的拖動以及點(diǎn)擊
使用方法
- 下載并復(fù)制KHPlayer文件夾下的源代碼到你的工程目錄
- 注意:如果想使用原資源圖片, 一定要把Assets里的圖片一起復(fù)制過去
- 初始化KHPlayer, 賦值Frame, 并添加到當(dāng)前視圖中
KHPlayer *player = [[KHPlayer alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.view.frame) - 70, CGRectGetWidth(self.view.frame),70)];
[self.view addSubview:player];
- 設(shè)置相關(guān)的UI屬性
[player setSliderThumbImage:[UIImage imageNamed:@"yinpinThumb"]];
[player enableMasksToBoundsOfSlider];
[player setBgColor:[UIColor whiteColor]];
- 設(shè)置要播放的在線音頻URL的String值, 并調(diào)用
play
方法進(jìn)行播放
[player setURLString: kInterface1];
[player play];
完成以上操作后得到的效果如下:
后續(xù)工作
- 添加播放本地音頻的接口
- 添加連續(xù)播放多首歌的功能
核心代碼
其實(shí)最核心的代碼是給播放器添加KVO監(jiān)聽事件, 所以在這里只展示這部分代碼
//添加在線播放的音頻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監(jiān)聽播放狀態(tài)
*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"status"])
{
//準(zhǔn)備播放
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];
}
}
}
/*
設(shè)置定時器,更新播放狀態(tài)
*/
- (void)updatePlayerProgress{
__weak typeof(self) weakSelf = self;
[_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.5, NSEC_PER_SEC) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
//更新左右的時間Label, 修改進(jìn)度條進(jìn)度(這里要用weakSelf來防止循環(huán)引用)
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;
}];
}
寫在結(jié)尾的話
有興趣了解所有代碼和Demo的朋友, 還是那句話, 可以去我github地址下載. 覺得還不錯的話不妨給我點(diǎn)個星哈~最后, 如果覺得代碼哪里有問題,或者有新的的需求想添加上去粱侣,歡迎留下你的評論.