Flex播放器同步显示歌词

播放歌曲时要同步显示歌词,首先必须要能解析出lrc格式的歌词文本,之前我还准备直接在网上匹配下载对应歌词,打开我机器的千千静音在线匹配歌词,然后用HTTPAnalyzerStdV监视所有的http请求,发现它是请求这个ttlrcct.qianqian.com网站下载歌词,本来还是直接套用千千静音服务器下载歌词,但是它的url参数全部加密了。后来又看了下酷狗音乐,它里面下载歌词我都监视不请求,考虑到就算我能在线找到下载歌词的url地址,flash里发送远程请求也会有安全杀箱问题,所以最终放弃直接在网络上下载歌词的办法,还是全部上传到我网站上去。lrc歌词其实就是一个文本格式的文件,在Flex里面我们可以使用URLLoader去加载,代码如下:

/加载歌词var lrcUrl : String = xml.item[currIndex].lrc;if ( lrcUrl!=null && lrcUrl!=""){    var lrc:URLLoader = new URLLoader();    //lrc.dataFormat = URLLoaderDataFormat.VARIABLES;    lrc.load(new URLRequest(lrcUrl));    lrc.addEventListener(Event.COMPLETE,LRC_Complete);    lrc.addEventListener(IOErrorEvent.IO_ERROR,LRC_IOError);}lrcArr = null;outPutLRCString = "";startIndexOf = 0;txtLrc.text = "";
然后在加载完成的事件里,我们能得到lrc文本字符串,这时候我们需要对字符串进行处理,把它转换成一个Array数组,函数方法如下:

public function getLRCArray(lrc:String):Array { var lrcArr:Array=new Array; lrc += "\r"; for (var i:int = 0; i < lrc.length; i++) { var time:Number = 0; if (lrc.charAt(i) == ":") { time = Number(lrc.slice(i - 2, i)) * 60 + Number(lrc.slice(i + 1, i + 3)); if (String(time) != "NaN") { var j:uint = 0; var startIndex:uint = 0; var endIndex:uint = 0; do { j++; if (lrc.charAt(i + j) == "]") { startIndex = i + j + 1; } }while (i + j < lrc.indexOf("\r", i)) endIndex = lrc.indexOf("\r", i); if(startIndex!=0&&endIndex!=0){ lrcArr.push([time,lrc.slice(startIndex, endIndex)]); } } } } return lrcArr;}
解析歌词返回的Array数组为多围数组,数组里的每一项是为一个二围数组,item[0]为当前秒数,item[1]为该秒显示的歌词(句),比如item[0]=歌曲名:你最近还好吗、item[5]=演唱:S.H.E,就是代表第0秒显示歌曲名:你最近还好吗,而从第5秒起则显示演唱:S.H.E,这样通过getLRCArray方法就能得到歌曲所有的时间段显示的歌词拉。本例中把所有歌词放在一个editable="false"不可修改的mx:TextArea文本域内。

歌词同步显示的问题

歌词能全部加载显示了,问题是怎么随着歌曲的播放而高亮显示当前行歌词呢?不过还好Flex提供一个TextRange能对TextArea内文本进行选择性的处理,你只需要设置beginIndex和endIndex就能自动匹配到TextArea中间区域的文本,我这里只是简单的改变了一下颜色,不过我们从TextArea中找某一个句歌词索引的时候需要注意歌词有很多是重复的,所以我们需要用一个变量保存当前歌词播放位置索引startIndexOf,以确保我们高亮选择到的歌词是正确的。同时将TextArea滚动条设置到对应的高度,主要的代码如下:

//同步显示歌词if( lrcArr!=null && lrcArr.length > 0){ var sec:Number=int(channel.position/1000); for(var j:int=0;j<lrcArr.length;j++){ if(lrcArr[j][0]==sec){ var currentLrc : String = lrcArr[j][1]; if( currentLrc != this.currLrc.text) { currLrc.text = currentLrc; //高亮显示,先清空之前高亮部分 var tr : TextRange = new TextRange(txtLrc); tr.color = this.getStyle("color"); var beginIndex : int = this.outPutLRCString.indexOf(currentLrc,startIndexOf); startIndexOf += currentLrc.length; var endIndex : int = beginIndex + currentLrc.length; tr.beginIndex = beginIndex; tr.endIndex = endIndex; if ( tr.text != "" ) { tr.color = "yellow"; } //设置滚动条位置 this.txtLrc.verticalScrollPosition=j*this.txtLrc.maxVerticalScrollPosition/lrcArr.length; if( lrcArr.length - j <= 5 ) this.txtLrc.verticalScrollPosition = this.txtLrc.maxVerticalScrollPosition; } break; } } }
上面sec是当前歌曲播放的时间秒数,然后循环换数组判断rcArr[j][0]跟当前sec比较,秒数一致才显示对应歌词,一段歌词可能在好几秒内都不会变的,同时根据当前歌词的数组索引位置设置TextArea滚动条位置,让当前正在播放的歌词在中间显示。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值