最近朋友想做个音乐App,让我帮忙参考下。其中歌词动态滚动的效果,正好我之前也没做过,顺便学习一下,先来个预览效果。

实现思路

歌词常见的就是lrc歌词了,我们这里也是通过解析lrc歌词文件来获取其播放参数,以实现和播放器协同。下面是我从百度音乐获取的歌词文件示例:

[ti:冰雨]
[ar:刘德华]
[al:笨小孩]
[00:0.05]冰雨
[00:0.94]作词:刘德华、李密 作曲:潘协庆
[00:01.23]演唱:刘德华[00:01.37]
[00:04.79](歌手独白)
[00:17.18]我是在等待 一个女孩
[00:25.18]还是在等待沉沦苦海
[00:32.91]一个人静静发呆 没有人去管花谢花开
[00:41.03]无法肯定的爱  左右摇摆
[00:45.43]只好把心酸往深心里塞
[00:49.61]我是在等待 你的回来
[00:57.73]难道只换回一句活该
[01:05.27]一个人静静发呆
[01:09.18]两个人却有不同无奈
[01:13.15]好好的一份爱 啊怎么会慢慢变坏
[01:18.43]
[01:20.44]冷冷的冰雨在脸上胡乱的拍
[01:24.31]暖暖的眼泪跟寒雨混成一块
[01:28.32]眼前的色彩忽然被掩盖
[01:32.28]你的影子无情在身边徘徊
[01:36.30]你就像一个刽子手把我出卖
[01:40.35]我的心彷佛被剌刀狠狠地宰
[01:44.36]在悬崖上的爱 谁会愿意接受最痛的意外
[01:51.09]
[02:26.59]我是在等待你的回来
[02:35.52]难道只换回一句活该
[02:42.99]一个人静静发呆
[02:46.99]两个人却有不同无奈
[02:51.08]好好的一份爱 啊怎么会慢慢变坏
[02:56.42]
[02:58.54]冷冷的冰雨在脸上胡乱的拍
[03:02.41]暖暖的眼泪跟寒雨混成一块
[03:06.39]眼前的色彩忽然被掩盖
[03:10.31]你的影子无情在身边徘徊
[03:14.23]你就像一个刽子手把我出卖
[03:18.34]我的心彷佛被剌刀狠狠地宰
[03:22.33]在悬崖上的爱  谁会愿意接受最痛的意外
[03:28.66]
[03:34.57]冷冷的冰雨在脸上胡乱的拍
[03:38.33]暖暖的眼泪跟寒雨混成一块
[03:42.31]眼前的色彩忽然被掩盖
[03:46.32]你的影子无情在身边徘徊
[03:50.27]你就像一个刽子手把我出卖
[03:54.34]我的心彷佛被剌刀狠狠地宰
[03:58.34]悬崖上的爱  谁会敢去采
[04:02.37]还是愿意接受最痛的意外 最爱的女孩
[04:08.85]
[04:19.72]悬崖上的爱  谁会敢去采
[04:31.84]还是愿意接受最痛的意外 最爱的女孩
[04:51.75]
[05:10.60]歌手独白
[06:16.76]

解析lrc歌词

这可能是最常见的格式了,每行为一句歌词,[]括号内为歌词对应的时间区间,所以我们首先要做的事情就是将他们提取分离出来,分别作为时间参数数组和歌词内容数组。这里我参考了一些博客的方法,解析lrc文件的代码如下:

#import <Foundation/Foundation.h>@interface LrcParser : NSObject//时间
@property (nonatomic,strong) NSMutableArray *timerArray;
//歌词
@property (nonatomic,strong) NSMutableArray *wordArray;//解析歌词
-(void) parseLrc;
//解析歌词
-(void) parseLrc:(NSString*)lrc;
@end

实现代码

@implementation LrcParser-(instancetype) init{self=[super init];if(self!=nil){self.timerArray=[[NSMutableArray alloc] init];self.wordArray=[[NSMutableArray alloc] init];}return  self;
}-(NSString *)getLrcFile:(NSString *)lrc{NSString* filePath=[[NSBundle mainBundle] pathForResource:lrc ofType:@"lrc"];return  [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
}
//测试示例
-(void)parseLrc{[self parseLrc:[self getLrcFile:@"冰雨"]];
}-(void)parseLrc:(NSString *)lrc{NSLog(@"%@",lrc);if(![lrc isEqual:nil]){NSArray *sepArray=[lrc componentsSeparatedByString:@"["];NSArray *lineArray=[[NSArray alloc] init];for(int i=0;i<sepArray.count;i++){if([sepArray[i] length]>0){lineArray=[sepArray[i] componentsSeparatedByString:@"]"];if(![lineArray[0] isEqualToString:@"\n"]){[self.timerArray addObject:lineArray[0]];[self.wordArray addObject:lineArray.count>1?lineArray[1]:@""];}}}}
}
@end

经过测试,可以将歌词顺利解析出来,下面我们要将获得歌词数据应用于控制器。

实现动态歌词页面

看了QQ音乐的滚动歌词页面后,可以知道是借助UITableView或者UIScrollView来实现的,这里我们采用UITableView来实现动态歌词界面。

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.//歌词TableView代理self.lrcTable.delegate=self;self.lrcTable.dataSource=self;//解析歌词self.lrcContent=[[LrcParser alloc] init];[self.lrcContent parseLrc];[self.lrcTable reloadData];//初始化播放器
    [self initPlayer];//监听播放器状态[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];//载入歌词背景UIImage *img=[UIImage imageNamed:@"wall1.jpg"];UIImageView *bgView=[[UIImageView alloc] initWithImage:[self getBlurredImage:img]];self.lrcTable.backgroundView=bgView;}
//cell委托
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{UITableViewCell *cell=[self.lrcTable dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];cell.textLabel.text=self.lrcContent.wordArray[indexPath.row];if(indexPath.row==_currentRow)cell.textLabel.textColor = [UIColor redColor];elsecell.textLabel.textColor = [UIColor whiteColor];cell.textLabel.textAlignment = NSTextAlignmentCenter;cell.textLabel.font = [UIFont systemFontOfSize:15];cell.backgroundColor=[UIColor clearColor];return cell;}

这里歌词列表的背景我采用了高斯模糊的图片,高斯模糊的方法如下:

//实现高斯模糊
-(UIImage *)getBlurredImage:(UIImage *)image{CIContext *context = [CIContext contextWithOptions:nil];CIImage *ciImage=[CIImage imageWithCGImage:image.CGImage];CIFilter *filter=[CIFilter filterWithName:@"CIGaussianBlur"];[filter setValue:ciImage forKey:kCIInputImageKey];[filter setValue:@5.0f forKey:@"inputRadius"];CIImage *result=[filter valueForKey:kCIOutputImageKey];CGImageRef ref=[context createCGImage:result fromRect:[result extent]];return [UIImage imageWithCGImage:ref];
}

播放器则采用AVPlayer,其定义和初始化设置如下:

@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>@property (nonatomic,strong) AVAudioPlayer *player;@end

-(void) initPlayer{AVAudioSession *session=[AVAudioSession sharedInstance];[session setActive:YES error:nil];[session setCategory:AVAudioSessionCategoryPlayback error:nil];[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];self.player=[[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle]  URLForResource:@"冰雨" withExtension:@"mp3"] error:nil];//单曲循环self.player.numberOfLoops=10;[self.player prepareToPlay];[self.player play];}

这样就为应用定义了一个音乐播放器,下面要监听播放器的时间参数,来载入对应的歌词,如下:

[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];

根据时间更新UI

-(void) updateTime{CGFloat currentTime=self.player.currentTime;NSLog(@"%d:%d",(int)currentTime / 60, (int)currentTime % 60);for (int i=0; i<self.lrcContent.timerArray.count; i++) {NSArray *timeArray=[self.lrcContent.timerArray[i] componentsSeparatedByString:@":"];float lrcTime=[timeArray[0] intValue]*60+[timeArray[1] floatValue];if(currentTime>lrcTime){_currentRow=i;}elsebreak;}[self.lrcTable reloadData];[self.lrcTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_currentRow inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}

最后编译运行,就会发现一个滚动歌词播放器就实现啦。

完整Demo项目地址:https://github.com/ChangweiZhang/AudioPlayerDemo

转载于:https://www.cnblogs.com/mantgh/p/5208034.html

iOS开发手记-仿QQ音乐播放器动态歌词的实现相关推荐

  1. 20230621----重返学习-仿QQ音乐播放器-静态页面的免费部署-vue2

    day-096-ninety-six-20230621-仿QQ音乐播放器-静态页面的免费部署-vue2 仿QQ音乐播放器 audio音频标签 audio标签 <audio src="i ...

  2. 基于jQuery仿QQ音乐播放器网页版代码

    基于jQuery仿QQ音乐播放器网页版代码是一款黑色样式风格的网页QQ音乐播放器样式代码.效果图如下: 在线预览    源码下载 实现的代码. html代码: <div class=" ...

  3. jQuery仿QQ音乐播放器

    本文通过Html+CSS+jQuery开发仿QQ版的音乐播放器,是前端技术的综合应用,所用素材来源于网络,仅供学习分享使用,如有不足之处,还请指正. 涉及知识点 在本例中用到的知识点如下,按jQuer ...

  4. 截获网易云、酷狗、QQ音乐播放器桌面歌词画面心德

    在直播项目中 需要捕获某个窗口的画面并共享 总结了如下几种场景中窗口的捕获方法 1.dc拷贝(BitBlt.PrintWindow) 这是最基本的方法 直接拿到窗口dc 然后从dc中拷贝窗口画面 可优 ...

  5. 【QQ音乐】QQ音乐播放器超酷使用技巧逐个揭秘

    [编者按]QQ音乐播放器凭借QQ强大的人气,目前已经成为许多朋友听歌的首选了,它带给我们无与伦比的快乐音乐体验.QQ音乐播放器的功能是如此的丰富,用户不仅仅是简单的在线听歌,还可以观看MV.收听在线广 ...

  6. 从零玩转jQuery之项目开发(QQ音乐播放器)

    QQ音乐播放器项目 大体效果如下: HTML结构分析: 一.页面布局 1.首先来看下HTML大体结构: <div class="header"></div> ...

  7. 从零开发一个定制版音乐播放器,女朋友不就有了吗?

    极客江南: 一个对开发技术特别执着的程序员,对移动开发有着独到的见解和深入的研究,有着多年的iOS.Android.HTML5开发经验,对NativeApp.HybridApp.WebApp开发有着独 ...

  8. 《移动应用开发》实验报告——音乐播放器

    代码仓库: https://gitee.com/shentuzhigang/demo-project/tree/master/vue-music-player Blog: https://shentu ...

  9. Android应用开发--MP3音乐播放器滚动歌词实现

    Android应用开发--MP3音乐播放器滚动歌词实现 2013年6月2日  简.美音乐播放器开发记录 -----前话 有网友给我博客评论说,让我借鉴好的Android代码,代码贴出来的时候最好整体先 ...

最新文章

  1. Python 笔试面试合集
  2. 云原生应用的10大关键属性
  3. java日记(2)------定时任务quartz浅析
  4. Py之xlutils:xlutils的简介、安装、使用方法之详细攻略
  5. linux终端中如何对目录压缩,软网推荐:Linux中使用命令行查看压缩文档
  6. Java注解研究之@Required
  7. POSIX风格正则表达式
  8. mysql slave 1062_MySQL主从不同步,出现1062错误解决方案
  9. 【读书笔记】-串指令备注
  10. StackPanel与Grid交叉使用
  11. 最新JAVA+Python+大数据资料分享
  12. Android图片添加水印
  13. Linux获取外网IP
  14. 神经网络拓扑图怎么画,神经网络和图神经网络
  15. 烽火2640路由器命令行手册-04-网络协议配置命令
  16. 未明学院:学员来稿 | 2019年中国电影分析报告
  17. [英语阅读]你的英文名特别吗
  18. robotframework-ride.py:在python2切换至python3时,ride.py变成了文本格式,不能使用python3打开,此时右键属性,更改……
  19. uniapp切换中英文
  20. 硬件工程师成长之路(0)----认识元件

热门文章

  1. 梳子刻字刻什么好_石阶上被刻了1700多个汉字,网友狂赞!
  2. php yield 个人小解_PHP中的性能优化利器:生成器 yield 理解
  3. 利用Python进行数据分析--数据加载、存储与文件格式
  4. 正态分布的前世今生:正态分布的进一步发展
  5. linux 调整shmmax,科学网—Ubuntu 9.10 中更改 linux kernal 中的shmmax大小 - 孙鹏的博文...
  6. 评分卡模型开发(九)--上线监测
  7. python3.8-运行jupyter 报raise NotImplementedError
  8. MySQL主从同步的概述_MySQL主从同步原理介绍
  9. stm32单片机屏幕一直闪_STM32物联网实战项目 - 项目需求
  10. vs2008 清理后再编译后卡顿_更新后,竟有这么“严重”的后果?