UC教室里有一节MTV的课程,用的是动态加载歌词,于是想到网上众多的LRC歌词,如果直接能从这种类型的歌词里提取需要的内容,一定会很方便,于是就写了这么个函数。
functin splitLRC(src:String):Object;
该函数的参数是LRC歌词的内容,返回值是一个对象,该对象具有以下的属性:
lrcObj.ar [ar:艺人名]
lrcObj.ti [ti:曲名]
lrcObj.al[al:专辑名]
lrcObj.by [by:编者(指编辑LRC歌词的人)]
lrcObj.offset [offset:时间补偿值] 单位是毫秒, 用来指定歌词整体推迟或提前显示。
lrcObj.dataArray
前五个属性分别对应LRC歌词中常用的五种标签。后面的数组属性中保存的是由时间和歌词构成的一个轻量级对象。调用的形式是 lrcObj.dataArray[i].t 和 lrcObj.dataArray[i].s 前者表示应该出现的时间,后者表示需要显示的内容。
LRC格式实际上仍旧是一个文本文件,只是扩展名不一样,可以用下面的代码将文件内容全部加载进来。
var mObj:Object = new Object();
var loadit_lv:LoadVars = new LoadVars();
loadit_lv.onData = function(src:String) {
if (src != undefined) {
mObj = splitLRC(src);
} else {
trace("Could not load text file.");
}
};
loadit_lv.load("moon.lrc");
在应用该对象时,可以用下面的语句,写在onEnterFrame事件处理函数中,或是自定义的interval 事件中。
if (myObj.dataArray[index].t + myObj.offset < the_sound.position) {
song_txt.text = myObj.dataArray[index].s;
index++;
}
完整示例如下:音乐从网站外加载,LRC歌词从本博客中加载。(本博客中不支持lrc格式上传,因此文件名改成txt来代替。)
源文件下载:
压缩包下载
函数代码:
function splitLRC(s:String) :Object{
s = trim(s);
//以回车符做为拆分的依据,每行尾还保留有一个换行符需要进一步处理
var m:Array = s.split("\n");
//trace(m[9]);
var lrcObj:Object = new Object();
lrcObj.ar = "";//[ar:艺人名]
lrcObj.ti = "";//[ti:曲名]
lrcObj.al = "";//[al:专辑名]
lrcObj.by = "";//[by:编者(指编辑LRC歌词的人)]
lrcObj.offset = 0;//[offset:时间补偿值] 单位是毫秒, 用来指定歌词整体推迟或提前显示。
lrcObj.dataArray = new Array();
//目前lrc格式的标签共有五种,可任选搭配,但不能重复使用
var index:Number = 5;
for (var i = 0; i < 5; i++) {
var t = m[i].indexOf(":");
var e = m[i].length;
var str = m[i].substring(1, t);
//String类 substring函数字符串首位索引号为0,终止位不包含在返回串中。
var val = m[i].substring(t + 1, e - 2);
//trace([str, val]);
if (str === "ar" || str === "ti" || str === "al" || str === "by" || str === "offset") {
lrcObj[str] = val;
//按照对象的属性名称引用对象的属性。
} else {
index = i;
break;
}
}
lrcObj.offset = Number(lrcObj.offset);
//将offset转换成数值型。
for (var i = index; i < m.length; i++) {
//对剩余行的内容进行精确处理。
//首先根据"]"将时间和歌词拆开,如果有多个时间的情况下,也将同时拆开。
var temp:Array = m[i].split("]");
//trace(temp);
//获取歌词内容,并将行尾的换行符剔除掉
var len:Number = temp.length;
var song:String = rtrim(temp[len - 1]);
//trace(song);
for (var j = 0; j < temp.length - 1; j++) {
//获取分钟数
var min = temp[j].substring(1, 3);
//trace(min);
//获取秒数
var sec = temp[j].substring(4);
//默认情况下,substring将从第四位截取到字串尾。
//trace( temp[j]);
//trace( sec );
//计算歌词出现的时间,单位为毫秒
var time = 1000 * (Number(min) * 60 + Number(sec));
//trace(time);
//将时间和歌词内容保存到lrc对象中去,为便于排序,对数据进行了处理
lrcObj.dataArray.push({t:10000000 + time, s:song});
}
}
//数组中使用sortOn方法排序时,是按字符串排序,解决办法加上一个大数字,排完序后再减去该数。
lrcObj.dataArray.sortOn("t");
for (var i = 0; i < lrcObj.dataArray.length; i++) {
lrcObj.dataArray[i].t -= 10000000;
trace([lrcObj.dataArray[i].t, lrcObj.dataArray[i].s]);
}
return lrcObj;
}
//ltrim 消除左边空格
function ltrim(str:String):String {
var size = str.length;
for (var i = 0; i < size; i++) {
if (str.charCodeAt(i) > 32) {
return str.substring(i);
}
}
return "";
}
//rtrim 消除右边空格
function rtrim(str:String):String {
var size = str.length;
for (var i = size; i > 0; i--) {
if (str.charCodeAt(i) > 32) {
return str.substring(0, i + 1);
}
}
return "";
}
//trim 消除两边空格
function trim(str:String):String {
return rtrim(ltrim(str));
}
最后三个字符串处理函数来自于黑羽天翔,在此向他致敬。