iOS-VLCKit实现仿网易云音乐播放音乐(一)

iOS仿网易云音乐

iOS-VLCKit实现仿网易云音乐播放音乐(一)

iOS-VLCKit实现仿网易云音乐播放音乐(二)

iOS-VLCKit实现仿网易云音乐播放音乐(三)

前言

最近做项目遇到需要播放音频的功能,通过查找资料,最终选择了VLCKit来实现。
VLC - 一款功能强大的全平台播放器,几乎支持所有格式的音频、视频文件的播放
集成方式
1、 按照wiki的说明去自己编译:[https://wiki.videolan.org/iOSCompile]
2、cocoapods方式
通过pos search MobileVLCKit去搜索相关的库,会发现有好几个库,我最终选择了MobileVLCKit-unstable(因为这个库更新的多,而且还在不时的更新)

pod 'MobileVLCKit-unstable', '~> 3.0.0a40'

说明

本Demo是根据VLCKit播放库写的仿网易云播放界面。

主要实现的功能有:

* 播放网络音频、歌曲
* 歌词滚动、音量控制、歌曲切换
* 设置循环类型、上一曲、下一曲、喜欢歌曲等
* 锁屏控制(播放、暂停、喜欢、上一曲、下一曲、播放条拖动)
* 耳机线控(播放、暂停、上一曲、下一曲、快进、快退)
* 通知监听(插拔耳机、播放打断)

不足:

* 不能获取缓冲进度(播放库的问题)
* 暂停后继续播放声音不准确(播放库的问题)
* airplay暂未支持

demo中的音乐文件来自百度音乐,仅供学习使用,请勿在商业中使用

部分功能的主要实现

1、歌词解析

+ (NSArray *)lyricParaseWithLyricString:(NSString *)lyricString {
    // 1. 以\n分割歌词
    NSArray *linesArray = [lyricString componentsSeparatedByString:@"\n"];

    // 2. 创建模型数组
    NSMutableArray *modelArray = [NSMutableArray new];

    // 3. 开始解析
    for (NSString *line in linesArray) {
        // 正则表达式 [00:01.78], \\ 转义,  @"\\[\\d{2}:\\d{2}.\\d{2}\\]"
        NSString *pattern = @"\\[[0-9][0-9]:[0-9][0-9].[0-9][0-9]\\]";

        NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
        // 进行匹配
        NSArray *matchesArray = [regular matchesInString:line options:NSMatchingReportProgress range:NSMakeRange(0, line.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 substringWithRange:NSMakeRange(1, 8)];
            // 分、秒、毫秒
            NSString *minStr = [timeStr substringWithRange:NSMakeRange(0, 2)];
            NSString *secStr = [timeStr substringWithRange:NSMakeRange(3, 2)];
            NSString *mseStr = [timeStr substringWithRange:NSMakeRange(6, 2)];

            // 转换成以毫秒秒为单位的时间 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];
        }
    }

    // 数组根据时间进行排序 时间(time)
    // ascending: 是否升序
    NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"msTime" ascending:YES];

    return [modelArray sortedArrayUsingDescriptors:@[descriptor]];
}

2、歌词滚动

- (void)scrollLyricWithCurrentTime:(NSTimeInterval)currentTime {
    if (self.lyricList.count == 0) self.lyricIndex = 0;

    for (NSInteger i = 0; i < self.lyricList.count; i++) {
        GKLyricModel *currentLyric = self.lyricList[i];
        GKLyricModel *nextLyric = nil;
        if (i < self.lyricList.count - 1) {
            nextLyric = self.lyricList[i + 1];
        }
        if ((self.lyricIndex != i && currentTime >= currentLyric.msTime) && (!nextLyric || currentTime < nextLyric.msTime)) {
            self.lyricIndex = i;

            [self.lyricTable reloadData];
            [self.lyricTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:(self.lyricIndex + 5) inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];
        }
    }
}

3、锁屏功能控制

// 喜欢、上一曲
// 喜欢按钮
MPFeedbackCommand *likeCommand = commandCenter.likeCommand;
likeCommand.enabled        = YES;
likeCommand.active         = self.model.isLike;
likeCommand.localizedTitle = self.model.isLike ? @"取消喜欢" : @"喜欢";
[likeCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
    // 喜欢
    return MPRemoteCommandHandlerStatusSuccess;
}];
// 上一首
MPFeedbackCommand *dislikeCommand = commandCenter.dislikeCommand;
dislikeCommand.enabled = YES;
dislikeCommand.localizedTitle = @"上一首";
[dislikeCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {

    NSLog(@"上一首");

    [self playPrevMusic];

    return MPRemoteCommandHandlerStatusSuccess;
}];

// 拖动进度条
if ([UIDevice currentDevice].systemVersion.doubleValue >= 9.0) {
    [commandCenter.changePlaybackPositionCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {

            MPChangePlaybackPositionCommandEvent *positionEvent = (MPChangePlaybackPositionCommandEvent *)event;

            if (positionEvent.positionTime != self.positionTime) {
                self.positionTime = positionEvent.positionTime;

                self.currentTime = self.positionTime * 1000;

                kPlayer.progress = (float)self.currentTime / self.duration;
            }

        return MPRemoteCommandHandlerStatusSuccess;
    }];
}

部分界面截图

我的音乐
播放界面
播放列表
锁屏图片
锁屏控制

github地址:GKAudioPlayerDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一种新的协议。它实...
    香橙柚子阅读 23,666评论 8 183
  • 实现这个功能需要注意两点: 1.设置文本框的高度 2.高度为行高的整数倍,显示两行,则高度为行高的2倍 需要用到的...
    orangesup阅读 922评论 0 3
  • 世间是否有完美的生活,也许有,也许没有,主要取决于我们对生活要求,如果我们的要求一味的超出力所能及的范围,那...
    夜已空阅读 312评论 0 3
  • 你遇到的每一个人都是自己 我要改变,我太不喜欢我目前的工作了,我也要像你一样自由。 不,亲爱的,如果你真的希望梦想...
    秋的彩虹阅读 239评论 0 0