flash歌词同步.doc_第1页
flash歌词同步.doc_第2页
flash歌词同步.doc_第3页
flash歌词同步.doc_第4页
flash歌词同步.doc_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

相关文章:Flash AS3用于读取LRC同步歌词的类。一、准备工作 既然要制作歌词同步程序,首先要准备一首歌,我们就以“周杰伦-青花瓷”为例。首先要下载这首“青花瓷.mp3”,保存为“C:My PlayerMusic青花瓷.mp3”。还要下载青花瓷的 LRC 文件,大家可以到网上下载(地址见附录),将文本内容保存为“C:My PlayerLRC青花瓷.lrc”。我们的程序(类和FLA)则保存在“C:My Player”文件夹下。青花瓷.lrc 文件:-ti:青花瓷ar:周杰伦al:我很忙by:张琪00:00.00发送短信18到291199下载该歌曲到手机00:01.11青花瓷03:36.4900:21.39素眉勾勒秋千话北风龙转丹00:26.08屏层鸟绘的牡丹一如你梳妆00:30.46黯然腾香透过窗心事我了然00:34.93宣纸上皱边直尺各一半00:39.49油色渲染侍女图因为被失藏00:43.83而你嫣然的一笑如含苞待放00:48.30你的美一缕飘散00:50.77去到我去不了的地方02:23.9700:55.7703:01.9202:25.6300:56.90天正在等烟雨03:03.5702:27.9100:58.99而我在等你03:05.9202:30.4401:00.93炊烟袅袅升起03:07.7602:32.2501:03.49隔江千万里03:10.3602:34.8501:05.84在平地书刻你房间上的飘影03:14.6702:38.7301:09.87就当我为遇见你伏笔03:18.8302:43.3501:14.34天正在等烟雨03:21.2002:45.6001:16.68而我在等你03:23.7102:48.0101:18.99月色被打捞起03:25.7402:50.1001:21.18掩盖了结局03:28.3302:52.5401:23.72如传世的青花瓷在独自美丽03:32.3002:56.6701:27.65你眼的笑意01:50.25色白花青的景已跃然于碗底01:54.69临摹宋体落款时却惦记着你01:59.22你隐藏在药效里一千年的秘密02:03.75急溪里犹如羞花沾落地02:08.32林外芭蕉惹咒语02:10.57梦幻的铜绿02:12.84而我路过那江南小镇的等你02:17.19在泼墨山水画里02:19.75你从墨色深处被隐去- 大家也可以把这个文本内容复制下来,然后在“C:My PlayerLRC”下创建一个文本文档,将内容粘贴上去,再将文档保存为“青花瓷.lrc”,注意扩展名是“.lrc”。二、LRC 内容分析 准备工作完成了,下面分析一下这个 LRC 文件。之所以叫 LRC ,是因为它是 Lyric (歌词) 的缩写。这种格式真是一目了然,前面“ ”中的数字表示其后歌词的开始时间。例如,“01:50.25色白花青的景已跃然于碗底”表示在1分50.25秒时,歌词内容是“色白花青的景已跃然于碗底”。 还有一种形式是“03:01.9202:25.6300:56.90天正在等烟雨”这种形式常用于赋格部分(俗称:歌曲的高潮部分),它表示在 03:01.92, 02:25.63, 00:56.90 时的歌词都是“天正在等烟雨”。由于这种形式的存在,使后面的编程稍显复杂,不过没关系,凭借各位的聪明智*四、LRC 的读取与存储转换(使用文档类设计)1.读取 LRC 文件,这一步非常简单与读取普通的文本文件是一样的; CODE:public function LRCPlayer() var loader:URLLoader=new URLLoader(); loader.load(new URLRequest(LRC/青花瓷.lrc); loader.addEventListener(Event.COMPLETE,LoadFinish); private function LoadFinish(evt:Event):void trace(evt.target.data); -2.将读取的 LRC 数据按行分割( n 为换行符),数组的每一个元素代表 LRC 的一行内容; CODE: function LoadFinish(evt:Event):void var list:String=evt.target.data; var listarray:Array=list.split(n); trace(listarray); -3.在数组中提取每一行的时间及歌词,解决单时间序列的问题;(注意!此段代码只作讲解,不以应用)LRC 内容如下: QUOTE:00:43.83而你嫣然的一笑如含苞待放00:48.30你的美一缕飘散00:50.77去到我去不了的地方03:01.92天正在等烟雨03:03.57而我在等你03:05.92炊烟袅袅升起03:07.76隔江千万里代码如下: CODE:function LoadFinish(evt:Event):void var list:String=evt.target.data; var listarray:Array=list.split(n); for (var i=0; ilistarray.length; i+) var info:String=listarrayi; /提取每行内容,用变量 info 保存 var lyric:String=info.substr(10); /将歌词内容提取到 lyric 变量中 var ctime:String =info.substr(0,10); /提取时间序列字串 var ntime:Number=Number(ctime.substr(1,2)*60+Number(ctime.substr(4,5); /将时间字串转换为计算机可读取的时间 var obj:Object=new Object(); obj.timer=ntime*1000; obj.lyric=lyric; LRCarray.push(obj); /将时间与歌词保存到一个 Object 中,并压入LRCarray 数组 trace(obj.timer,obj.lyric); 输出结果: QUOTE:43830 而你嫣然的一笑如含苞待放48300 你的美一缕飘散50770 去到我去不了的地方181920 天正在等烟雨183570 而我在等你185920 炊烟袅袅升起187760 隔江千万里-4.在LRC文件,还有多时间序列的存在,所以单时间序列算法不能满足实际需要,下面就来解决多时间序列问题;LRC 内容如下: QUOTE:00:43.83而你嫣然的一笑如含苞待放00:48.30你的美一缕飘散00:50.77去到我去不了的地方03:01.9202:25.6300:56.90天正在等烟雨03:03.5702:27.9100:58.99而我在等你03:05.9202:30.4401:00.93炊烟袅袅升起03:07.7602:32.2501:03.49隔江千万里代码如下: CODE: function LoadFinish(evt:Event):void var list:String=evt.target.data; var listarray:Array=list.split(n); var reg:RegExp=/0-50-9:0-50-9.0-90-9/g; /建立正则表达式,范围:00:00.0059:59.99 for (var i=0; ilistarray.length; i+) var info:String=listarrayi; /提取每行内容,用变量 info 保存 var len:int=info.match(reg).length; /该行拥有时间序列的个数 var timeAry:Array=info.match(reg); /将匹配的时间序列保存到 timeAry 数组中 var lyric:String=info.substr(len*10); /根据每个时间序列占10个字符,找出歌词内容的起点 /将歌词提取到 lyric 变量中 for (var k:int=0; kparaB.timer) return 1; if (paraA.timerparaB.timer) return -1; return 0; 结果如下: QUOTE:43830 而你嫣然的一笑如含苞待放48300 你的美一缕飘散50770 去到我去不了的地方56900 天正在等烟雨58990 而我在等你60930 炊烟袅袅升起63490 隔江千万里145630 天正在等烟雨147910 而我在等你150440 炊烟袅袅升起152250 隔江千万里181920 天正在等烟雨183570 而我在等你185920 炊烟袅袅升起187760 隔江千万里-6.最后,随着音乐的播放,读取播放时间段内的歌词。用当前播放时间与 LRCarray 中的时间相比较,如果当前时间小于 LRCarray.timer 的时间,那么就显示 LRCarrayi-1.lyric 的歌词。为什么要显示 i-1 的歌词呢?比如说当前播放到第 500 秒,读取的 LRCarray20.timer 时间是 400 秒,那么 i+ 。下一次读取的 LRCarray21.timer 时间是 700 秒,这时当前播放时间小于读取的这个时间,就说明当前的第 500 秒仍处于 LRCarray20.timer 的时间范围内。 CODE: var lrc_txt:TextField=new TextField(); var LRCarray:Array=new Array(); var sc:SoundChannel; public function LRCPlayer() lrc_txt.width=500; lrc_txt.selectable=false; addChild(lrc_txt); /歌词在文本 lrc_txt 中显示 var loader:URLLoader=new URLLoader(); loader.load(new URLRequest(LRC/青花瓷.lrc); loader.addEventListener(Event.COMPLETE,LoadFinish); var sound:Sound=new Sound(); sound.load(new URLRequest(Music/青花瓷.mp3); sc=sound.play(); /播放声音,并生成 sc 变量,SoundChannel 类的实例 stage.addEventListener(Event.ENTER_FRAME,SoundPlaying); /实时刷新歌词 function SoundPlaying(evt:Event):void for (var i=1; iLRCarray.length; i+) if (sc.positionLRCarrayi.timer) lrc_txt.text=LRCarrayi-1.lyric; break; /找到歌词,跳出循环体 lrc_txt.text=LRCarrayLRCarray.length-1.lyric; /找不到歌词,说明已超出了最后一句的时间,因此显示最后一句歌词 五、全部代码(文档类 LRCPlayer.as): CODE:package import flash.display.Sprite;import .URLRequest;import .URLLoader;import flash.media.Sound;import flash.media.SoundChannel;import flash.events.Event;import flash.text.TextField;import flash.system.System;public class LRCPlayer extends Sprite var lrc_txt:TextField=new TextField(); var LRCarray:Array=new Array(); var sc:SoundChannel; public function LRCPlayer() System.useCodePage=true; lrc_txt.width=500; lrc_txt.selectable=false; addChild(lrc_txt); var loader:URLLoader=new URLLoader(); loader.load(new URLRequest(LRC/青花瓷.lrc); loader.addEventListener(Event.COMPLETE,LoadFinish); var sound:Sound=new Sound(); sound.load(new URLRequest(Music/青花瓷.mp3); sc=sound.play(); stage.addEventListener(Event.ENTER_FRAME,SoundPlaying); function SoundPlaying(evt:Event):void for (var i=1; iLRCarray.length; i+) if (sc.positionLRCarrayi.timer) lrc_txt.text=LRCarrayi-1.lyric; break; lrc_txt.text=LRCarrayLRCarray.length-1.lyric; function LoadFinish(evt:Event):void var list:String=evt.target.data; var listarray:Array=list.split(n); var reg:RegExp=/0-50-9:0-50-9.0-90-9/g; for (var i=0; ilistarray.length; i+) var info:String=listarrayi; var len:int=info.match(reg).length; var timeAry:Array=info.match(reg); var lyric:String=info.substr(len*10); for (var k:int=0; kparaB.timer) return 1; if (paraA.timerparaB.timer) return -1; return 0; 六、*无处不在的优化 至此,该程序已经可以顺利执行了,此处只讨论一下优化问题,看不懂可以跳过。以这段代码为例: CODE:function SoundPlaying(evt:Event):void for (var i=1; iLRCarray.length; i+) if (sc.positionLRCarrayi.timer) lrc_txt.text=LRCarrayi-1.lyric; break; lrc_txt.text=LRCarrayLRCarray.length-1.lyric; 如果要进行优化,那么这个 for 循环,应该写成: CODE: for (var i=1,j=LRCarray.length; ij; i+) 这样在执行判断时,不必每次都进行 LRCarray.length 操作,该操用于读取数组长度,执行 Array 类的 length 方法,属于高级操作,花费的时间要比低级操作多。其实,只要读取一次长度,然后将结果保存在变量 j 中,每次判断时读取 j 的值即可。取值与赋值都属于低级别的操作,速度较快。同样的道理,在 CODE:if (sc.positionLRCarrayi.timer) 中的 sc.position 在每次判断时都要读取一遍,这时就应将它在循环之前保存到一个变量里,这段代码优化后应是这样: CODE:function SoundPlayin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论