android歌词同步

来源:互联网 发布:php ajax异步请求 编辑:程序博客网 时间:2024/04/29 22:27

http://blog.csdn.net/waterinet/article/details/7892834

最近做了一个android的音乐播放器,下面将介绍歌词同步显示的实现。网上关于这一块的参考实例,多数人推荐了Yoyoplayer。YOYOPlayer是一个用JAVA编写的,跨平台的音乐播放软件.集播放,歌词显示于一体,并且开放源代码,感兴趣的朋友可以自行google。

一、LRC歌词文件的解析

        先要了解LRC文件的格式,可以参考:http://baike.baidu.com/view/80650.htm。总体思路是这样的,按行读入歌词文本,忽略每行中的注释,即“[:]”后的内容;再解析标识标签(ID-tags);最后解析出时间标签及其对应的歌词语句。具体实现如下:

1、忽略注释

2、解析标识标签

3、解析时间标签 

    这里我用了map结构来存储歌词开始时间及歌词语句的配对关系,value为歌词语句,key值为该歌词开始时间。这里用了一个正则表达式来匹配时间标签,支持[ : ] 、[  : : ] 、[ : . ]三种格式的时间标签。getTimeOfLine()函数的作用是将时间标签转换成以毫秒为单位的时间量。

 

二、歌词语句分行

    LRC文件中的单句歌词可能过长,在android屏幕的给定区域中未必能单行显示,从而需要依据屏幕歌词显示区域的宽度进行断句分行。其中寻找分割点的实现如下:

分割过程如下,其中tp为android中TextPaint类型的对象,TextPaint用于在view中绘制文本,它提供了一个测定文本宽度的函数measureText():


三、歌词的同步显示

       要把歌词同步滚动地显示在手机屏幕上,需要自定义view,这里我选择继承自TextView。主要是重写TextView中的onDrow()函数。主要实现思路是先绘制当前正在播放的歌词,然后绘制当前歌词之上的歌词和当前歌词之下的歌词(指在屏幕上显示的位置)。根据歌曲的播放进度,不断重绘歌词以达到同步滚动效果。

其中,函数getLineFromTime()根据当前播放进度获取应该显示的歌词,calOffsetOfCurrentLine()返回当前歌词距离初始显示位置的偏移量,因为一句歌词从进入高亮显示到结束高亮显示有一段时间,这段时间里高亮歌词也是在滚动的,如下图所示:

    

“敌动我不动 你动我不动”这句开始高亮显示                             “敌动我不动 你动我不动”结束高亮显示

其中,calOffsetOfCurrentLine()函数为:


 

四、拖动歌词控制播放进度

      这里首先要明确,上下滑动歌词只是一种动作,控制音乐播放进度。往上滑动表示进度往前,往下滑动表示进度往后。自己设定一个合适的滑动距离与时间的转换关系即可。


        这里的MoveTo就是我设定的一个滑动距离与时间的转换关系。分三个步骤:手指按下时记录起始滑动点;活动过程中持续更新歌词进度(即歌词的上下滑动效果);手指放开时修改歌曲播放进度。

 

原创粉丝点击