最近作項目,遇到了須要播放網絡音頻的功能,因爲之前對於音頻方面的至少了解的不是不少,因而經過查閱資料對音頻方面作了一些學習,而後利用VLCKit仿照網易雲音樂的播放界面寫了個Demo,在此記錄一下,大神勿噴。git
關於VLCKit,它是一款功能強大的全平臺播放器,幾乎支持全部格式的音頻、視頻文件的播放
集成方式
一、 按照wiki的說明去本身編譯:[wiki.videolan.org/iOSCompile]
二、cocoapods方式
經過pos search MobileVLCKit去搜索相關的庫,會發現有好幾個庫,我最終選擇了MobileVLCKit-unstable(由於這個庫更新的多,並且還在不時的更新)github
pod 'MobileVLCKit-unstable', '~> 3.0.0a42'複製代碼
本Demo主要實現的有如下功能:正則表達式
* 播放網絡音頻、歌曲
* 唱片(播放時旋轉、左右滑動切換歌曲)
* 歌詞滾動、音量控制、歌曲切換
* 設置循環類型、上一曲、下一曲、喜歡歌曲等
* 鎖屏控制(播放、暫停、喜歡、上一曲、下一曲、播放條拖動)
* 耳機線控(播放、暫停、上一曲、下一曲、快進、快退)
* 通知監聽(插拔耳機、播放打斷)
* 支持AirPlay複製代碼
不足:數組
* 不能獲取緩衝進度(播放庫的問題)
* 不支持本地緩存(每次播放都須要網絡請求)複製代碼
demo中的音樂數據來自百度音樂,僅供學習使用,請勿在商業中使用緩存
demo中對VLCKit實現了二次封裝GKPlayer,主要實現的有播放、暫停、中止,以及播放狀態、進度、時間等的回調,這裏就不貼代碼了,具體可到Demo中查看GKPlayer。bash
歌曲播放是須要實現轉盤無限旋轉的效果,這裏用到了CADisplayLink定時器不斷的刷新,而後經過設置視圖的transform來實現
首先建立CADisplayLink網絡
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animation)];
// 加入到主循環中
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];複製代碼
監聽方法中改變視圖的transformide
self.diskView.transform = CGAffineTransformRotate(self.diskView.transform, M_PI_4 / 100);複製代碼
這樣就作到了視圖的無限旋轉,並且側滑返回的時候也不會中止,下面看看效果圖oop
轉盤左右滑動切換歌曲也比較簡單,用到了UIScrollView,而後再上面放了三個轉盤視圖,經過監聽UIScrollView的滾動來切換歌曲,看看效果圖吧。學習
對於歌詞首先固然是解析歌詞了,經過換行符\n來分離每行的歌詞,而後再經過正則表達式,分離歌詞的時間與內容。
/**
解析歌詞方法
@param lyricString 歌詞對應的字符串
@param isDelBlank 是否去掉空白行歌詞
@return 歌詞解析後的模型數組
*/
+ (NSArray *)lyricParaseWithLyricString:(NSString *)lyricString isDelBlank:(BOOL)isDelBlank {
// 1. 以\n分割歌詞
NSArray *linesArray = [lyricString componentsSeparatedByString:@"\n"];
// 2. 建立模型數組
NSMutableArray *modelArray = [NSMutableArray new];
// 3. 開始解析
// 因爲有形如
// [ti:若是沒有你]
// [00:00.64]歌詞
// [00:01.89][03:01.23][05:03.43]歌詞
// [00:00.8]
// 這樣的歌詞形式,因此最好的方法是用正則表達式匹配 [00:00.00] 來獲取時間
for (NSString *line in linesArray) {
// 正則表達式
NSString *pattern = @"\\[[0-9][0-9]:[0-9][0-9].[0-9]{1,}\\]";
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
// 進行匹配
NSArray *matchesArray = [regular matchesInString:line options:NSMatchingReportProgress range:NSMakeRange(0, line.length)];
// 獲取歌詞部分
// 方法一
// NSTextCheckingResult *match = matchesArray.lastObject;
//
// NSString *content = [line substringFromIndex:(match.range.location + match.range.length)];
// 方法二 [00:01.78]歌詞
NSString *content = [line componentsSeparatedByString:@"]"].lastObject;
// 獲取時間部分[00:00.00]
for (NSTextCheckingResult *match in matchesArray) {
NSString *timeStr = [line substringWithRange:match.range];
// 去掉開頭和結尾的[],獲得時間00:00.00
// 去掉[
timeStr = [timeStr substringFromIndex:1];
// 去掉]
timeStr = [timeStr substringToIndex:(timeStr.length - 1)];
// 分、秒、毫秒
NSString *minStr = [timeStr substringWithRange:NSMakeRange(0, 2)];
NSString *secStr = [timeStr substringWithRange:NSMakeRange(3, 2)];
// 因爲毫秒有一位或者兩位,因此應從小數點(第六位)後獲取
NSString *mseStr = [timeStr substringFromIndex:6];
// 轉換成以毫秒秒爲單位的時間 1秒 = 1000毫秒
NSTimeInterval time = [minStr floatValue] * 60 * 1000 + [secStr floatValue] * 1000 + [mseStr floatValue];
// 建立模型,賦值
GKLyricModel *lyricModel = [GKLyricModel new];
lyricModel.content = content;
lyricModel.msTime = time;
lyricModel.secTime = time / 1000;
lyricModel.timeString = [GKTool timeStrWithMsTime:time];
[modelArray addObject:lyricModel];
}
}
// 去掉空白行歌詞
if (isDelBlank) {
[modelArray enumerateObjectsUsingBlock:^(GKLyricModel *obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (!obj.content || [obj.content isEqualToString:@""]) {
[modelArray removeObject:obj];
}
}];
}
// 數組根據時間進行排序 時間(time)
// ascending: 是否升序
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"msTime" ascending:YES];
return [modelArray sortedArrayUsingDescriptors:@[descriptor]];
}複製代碼
而後就是歌曲播放是,滾動歌詞了,這裏經過在UITableView中先後都加上5行的空白行,讓歌詞可以顯示在中間,而後根據歌曲播放的時間,刷新tableview選中當前時間對應的歌詞並顯示在tableview的中間。
/**
根據當前時間及總時間滾動歌詞
@param currentTime 當前時間
@param totalTime 總時間
*/
- (void)scrollLyricWithCurrentTime:(NSTimeInterval)currentTime totalTime:(NSTimeInterval)totalTime {
if (self.lyrics.count == 0) self.lyricIndex = 0;
for (NSInteger i = 0; i < self.lyrics.count; i++) {
GKLyricModel *currentLyric = self.lyrics[i];
GKLyricModel *nextLyric = nil;
if (i < self.lyrics.count - 1) {
nextLyric = self.lyrics[i + 1];
}
if ((self.lyricIndex != i && currentTime > currentLyric.msTime) && (!nextLyric || currentTime < nextLyric.msTime)) {
self.lyricIndex = i;
//刷表
[self.lyricTable reloadData];
// 不是由拖拽產生的滾動,自動滾滾動歌詞
if (!self.isScrolling) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(self.lyricIndex + 5) inSection:0];
[self.lyricTable selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}
}
}
}複製代碼
看看效果圖吧
其餘效果圖
固然還有不少的細節處理,在這裏就不在贅述了。具體實現仍是去看Demo吧。
本demo中其實並無音視頻的底層的知識,只是作了對VLCKit的使用,界面也是徹底仿照網易雲音樂作的,這裏只是作一下分享,若是有寫的很差的地方還請見諒。
最後,若是您以爲還不錯,點個star吧!😁😁😁
github地址:GKAudioPlayerDemo