最近作项目,遇到了须要播放网络音频的功能,因为之前对于音频方面的至少了解的不是不少,因而经过查阅资料对音频方面作了一些学习,而后利用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