【版权】
最近访问本帖者列表:flashroad
访问时间:2020-11-17 15:01 | |||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
一、准备工作既然要制作歌词同步程序,首先要准备一首歌,我们就以“周杰伦-青花瓷”为例。首先要下载这首“青花瓷.mp3”,保存为“C:\My Player\Music\青花瓷.mp3”。
还要下载青花瓷的 LRC 文件,大家可以到网上下载,也可以把下面的文本内容复制下来,然后在“C:\My Player\LRC\”下创建一个文本文档,将内容粘贴上去,再将文档保存为“青花瓷.lrc”,注意扩展名是“.lrc”。我们的程序(类和FLA)则保存在“C:\My Player\”文件夹下。 青花瓷.lrc 文件:
| |
二、LRC 内容分析准备工作完成了,下面分析一下这个 LRC 文件。之所以叫 LRC ,是因为它是 Lyric (歌词) 的缩写。
这种格式真是一目了然,前面“[ ]”中的数字表示其后歌词的开始时间。 例如,“[01:50.25]色白花青的景已跃然于碗底” 表示在1分50.25秒时,歌词内容是“色白花青的景已跃然于碗底”。 还有一种形式是“[03:01.92][02:25.63][00:56.90]天正在等烟雨” 这种形式常用于赋格部分(俗称:歌曲的高潮部分),它表示在 03:01.92, 02:25.63, 00:56.90 时的歌词都是“天正在等烟雨”。 由于这种形式的存在,使后面的编程稍显复杂,不过没关系,凭借各位的聪明智慧一定没问题。 | |
三、预备知识1. ActionScript 3 中默认使用 Unicode 来解码外部文件
如果读取的文本不是 Unicode 编码,而是按照操作系统代码页编写的,比如 GB2312, 那么需要先导入 flash.system.System 类,并在加载外部文本的语句前将 System.useCodePage 设为 true,默认情况下为 false,即默认不使用操作系统页解码。 如果 System.useCodePage = false 且外部 LRC 文件编码格式是 ANSI 的话,那么显示的中文歌词会是乱码。 解决办法有两个:一是,将外部 LRC 文件编码格式改为 Unicode; 二是,不改变外部文件编码格式,只在文档类中加入一句
由于后一种方法使用简便,我们就采用第二种方法。 2.读取声音:
4.读取外部文件:
1>获取匹配次数:
| |
四、LRC 的读取与存储转换(使用文档类设计)1.读取 LRC 文件,这一步非常简单与读取普通的文本文件是一样的;
3.在数组中提取每一行的时间及歌词,解决单时间序列的问题; (注意!此段代码只作讲解,不以应用) LRC 内容如下:
代码如下:
输出结果: 43830 而你嫣然的一笑如含苞待放 48300 你的美一缕飘散 50770 去到我去不了的地方 181920 天正在等烟雨 183570 而我在等你 185920 炊烟袅袅升起 187760 隔江千万里4.在LRC文件,还有多时间序列的存在,所以单时间序列算法不能满足实际需要,下面就来解决多时间序列问题; LRC 内容如下:
代码如下:
输出结果: 43830 而你嫣然的一笑如含苞待放 48300 你的美一缕飘散 50770 去到我去不了的地方 181920 天正在等烟雨 145630 天正在等烟雨 56900 天正在等烟雨 183570 而我在等你 147910 而我在等你 58990 而我在等你 185920 炊烟袅袅升起 150440 炊烟袅袅升起 60930 炊烟袅袅升起 187760 隔江千万里 152250 隔江千万里 63490 隔江千万里5.将获得的 LRCarray 数组按起始时间排序,这对于按序读取歌词有重要意义;
结果如下: 43830 而你嫣然的一笑如含苞待放 48300 你的美一缕飘散 50770 去到我去不了的地方 56900 天正在等烟雨 58990 而我在等你 60930 炊烟袅袅升起 63490 隔江千万里 145630 天正在等烟雨 147910 而我在等你 150440 炊烟袅袅升起 152250 隔江千万里 181920 天正在等烟雨 183570 而我在等你 185920 炊烟袅袅升起 187760 隔江千万里 6.最后,随着音乐的播放,读取播放时间段内的歌词。用当前播放时间与 LRCarray 中的时间相比较,如果当前时间小于 LRCarray.timer 的时间,那么就显示 LRCarray[i-1].lyric 的歌词。为什么要显示 [i-1] 的歌词呢?比如说当前播放到第 500 秒,读取的 LRCarray[20].timer 时间是 400 秒,那么 i++ 。下一次读取的 LRCarray[21].timer 时间是 700 秒,这时当前播放时间小于读取的这个时间,就说明当前的第 500 秒仍处于 LRCarray[20].timer 的时间范围内。
| |
五、全部代码(文档类 LRCPlayer.as):
| |
六、*无处不在的优化至此,该程序已经可以顺利执行了,此处只讨论一下优化问题,看不懂可以跳过。
以这段代码为例:
| |