打造你完美的音乐播放器 - LRC歌词与音乐同步播放
作者:Rogiture 日期:2007-07-20
打造你完美的音乐播放器 - 从搜索引擎获取MP3地址
打造你完美的音乐播放器 - 从搜索引擎获取LRC歌词
打造你完美的音乐播放器 - LRC歌词与音乐同步播放
打造你完美的音乐播放器 - Flash收音机,聆听电台之声
原文出处: http://www.rogiture.com/blog/article.asp?id=3(转载请注明作者及出处)
作者:Rogiture
新建个flash文档,
在场景中放置一个按钮,实例名为 play_btn。
在主场景中第一帧上写上如下代码:
程序代码
附上原文件,望受用。
原文件下载
打造你完美的音乐播放器 - 从搜索引擎获取LRC歌词
打造你完美的音乐播放器 - LRC歌词与音乐同步播放
打造你完美的音乐播放器 - Flash收音机,聆听电台之声
原文出处: http://www.rogiture.com/blog/article.asp?id=3(转载请注明作者及出处)
作者:Rogiture
新建个flash文档,
在场景中放置一个按钮,实例名为 play_btn。
在主场景中第一帧上写上如下代码:

//按 Unicode 进行编码
System. useCodepage = true;
//
//临时记录lrc歌词信息字符串(用于解析时)
var sData: String;
//临时记录lrc歌词信息字符串(用于解析歌词时)
var sData2: String;
//临时记录时间字符串
var shiJian: String;
//临时记录与shiJian所对应的歌词字符串
var geCi: String;
//记录歌词的出现时间与对应的歌词
var geCi_ay: Array = new Array();
//定义声音对象
var s_sound: Sound = new Sound();
//创建个MC,做为歌词的容器
this. createEmptyMovieClip( "geCi_mc", this. getNextHighestDepth());
//记录geCi_mc的初始_y
var n_y: Number = Stage. height/2;
geCi_mc. _y = n_y;
//记录现在正在播放第几句歌词
var now: Number = 0;
//
//声明周期回调监听歌曲已播放时间函数的ID
var fun_id: Number;
/*
*/
//加载lrc歌词,参数(lrc歌词地址)
function jiaZai(sUrl: String): Void {
var my_lv: LoadVars = new LoadVars();
my_lv. load(sUrl);
my_lv. onLoad = function(success: Boolean): Void {
if (success) {
//转义十六进制序列字符串。
var s: String = unescape(my_lv. toString());
//trace(s);//去掉前面两斜杠可查看被加载到flash中的lrc歌词原始数据
//将加载的lrc歌词存入sData
sData = s;
//解析lrc歌词
jieXi();
}
};
}
/*
*/
//解析lrc歌词数据。(函数不理解的地方请按F1查看帮助文档,有详细解释)
function jieXi(): Void {
//拆出时间
var nK: Number = sData. indexOf( "[");
var sK: String = sData. substr(nK+1);
var nJ: Number = sK. indexOf( "]");
sData = sK. substr(nJ+1);
//记录到临时时间字符串中
shiJian = sK. substr(0, nJ);
//调用jieXiGeCi函数,拆出歌词
sData2 = sData;
jieXiGeCi();
}
/*
*/
//解析歌词所用函数,返回得到的歌词
function jieXiGeCi(): Void {
//如果这段歌词数据是这种形式([03:07.65][02:12.25]爱情还是要继续吧)记录的,递归,直到找到这句(爱情还是要继续吧)
if (sData2. indexOf( "[") == 0) {
var nJ: Number = sData2. indexOf( "]");
sData2 = sData2. substr(nJ+1);
jieXiGeCi();
//拆出歌词
} else {
var nJ: Number = sData2. indexOf( "/n");
geCi = sData2. substr(0, nJ);
//
//去除歌词中的回车符
geCi = geCi. split( String. fromCharCode(13)). join( "");
//
//调用suanHaoMiao函数,保存歌词信息到 geCi_ay 数组
suanHaoMiao(shiJian, geCi);
//
//如果还有歌词信息,递归,继续提取
if (sData. indexOf( "[")>-1) {
jieXi();
//没有歌词信息了,这时,将sj的值设为"load over",告诉suanHaoMiao函数,已经解析完了
} else {
suanHaoMiao( "load over");
}
}
}
/*
*/
//计算出歌词出现时的毫秒数([00:57.22]格式为[分:秒.毫秒],而我们需要将其全转为毫秒数)
//将得出的毫秒与对应的歌词存入 geCi_ay 数组
//参数(时间,对应的歌词)
function suanHaoMiao(sj: String, gc: String): Void {
//记录毫秒
var haoMiao: Number = 0;
//得出分钟
var ay1: Array = sj. split( ":");
/*因lrc歌词中有([ti:洛丽塔][ar:卓亚君][al:网络秀])之类的信息,
所以,得检测是否为数字,若为数字,即这句为要显示的歌词*/
if (! isNaN( parseInt(ay1[0]))) {
//
//将分钟转为毫秒,加到记录毫秒变量中
haoMiao += parseInt(ay1[0])*60000;
//
//得出秒
var ay2: Array = ay1[1]. split( ".");
//将秒转为毫秒,加到记录毫秒变量中
haoMiao += parseInt(ay2[0])*1000;
//
//将毫秒转为整数,加到记录毫秒变量中
haoMiao += parseInt(ay2[1]);
//
//
//trace(haoMiao+" 毫秒时,显示:"+gc);//去掉前面两斜杠可查看初步解析完的lrc歌词(未排序)
//
//在毫秒与所对应的歌词中间加入":",用于排序,存入 geCi_ay 数组
geCi_ay. push(haoMiao+ ":"+gc);
}
//歌词已经解析完毕
if (sj == "load over") {
//改变歌词数组的排序
geCi_ay. sort(order);
//循环提取,显示歌词信息
for ( var i: Number = 0; i<geCi_ay. length; i++) {
//提取歌词
var ay: Array = geCi_ay[i]. split( ":");
//在geCi_mc容器中,创建文本,显示提取的歌词,每句歌词相隔20像素
var txt: TextField = geCi_mc. createTextField(i+ "_txt", geCi_mc. getNextHighestDepth(), 0, 20*i, Stage. width, 20);
//设置文本居中对齐
txt. autoSize = "center";
//设置文本不可选
txt. selectable = false;
//显示歌词
txt. text = ay[1];
//高亮显示第一句歌词
if (i == 0) {
txt. textColor = 0x990000;
}
}
}
}
/*
*/
//设定数组的排序方法(关于数组的排列,请参阅帮助文档,有详细解释)
function order(a, b): Number {
var n1: Number = parseInt(a. split( ":")[0]);
var n2: Number = parseInt(b. split( ":")[0]);
if (n1<n2) {
return -1;
} else if (n1>n2) {
return 1;
} else {
return 0;
}
}
/*
*/
//监听歌曲已经播放的时间
function jianTingGeQu(): Void {
//如果歌曲已开始播放
if (s_sound. position != undefined) {
//得出下一句歌词的显示时间
var gc_next: Number = parseInt(geCi_ay[now+1]. split( ":")[0]);
//
//如果音乐播放时间已经超过下一句歌词的显示时间
if (s_sound. position>gc_next) {
//将现在这句歌词颜色改为默认色,黑色
geCi_mc[now+ "_txt"]. textColor = 0x000000;
//高亮显示下一句歌词
now++;
geCi_mc[now+ "_txt"]. textColor = 0x990000;
}
//获取这一句歌词的显示时间
var gc_now: Number = parseInt(geCi_ay[now]. split( ":")[0]);
//重新获取下一句歌词的显示时间
var gc_next: Number = parseInt(geCi_ay[now+1]. split( ":")[0]);
//如果下一句歌词不存在,即已是最后一句歌词
if ( isNaN(gc_next)) {
//获取歌曲的结束时间
gc_next = s_sound. duration;
}
//
//我们已经设定,歌词之间_y相隔20像素,算出两句歌词之间每毫秒应该移动多少
var mhm: Number = 20/(gc_next-gc_now);
//得出两句歌词之间已播放多少毫秒
var yhm: Number = Math. floor(gc_next-s_sound. position);
//得出歌词应该到的位置
geCi_mc. _y = n_y-(now*20)+ Math. floor(yhm*mhm);
}
}
/*
*/
//歌曲播放完毕时
s_sound. onSoundComplete = function() {
//清除回调滚动显示歌词函数的ID
clearInterval(fun_id);
trace( "歌曲播放完毕/n原文出处:http://www.rogiture.com/n作者:Rogiture");
};
/*
*/
//当按下播放音乐按钮时,播放音乐,加载lrc歌词
play_btn. onRelease = function(): Void {
//设置按钮不可见
this. _visible = false;
//加载音乐
s_sound. loadSound( "洛丽塔-卓亚君.mp3", true);
//加载lrc歌词
jiaZai( "洛丽塔-卓亚君.lrc");
//周期回调 监听歌曲已播放时间函数
fun_id = setInterval(jianTingGeQu, 1);
};
System. useCodepage = true;
//
//临时记录lrc歌词信息字符串(用于解析时)
var sData: String;
//临时记录lrc歌词信息字符串(用于解析歌词时)
var sData2: String;
//临时记录时间字符串
var shiJian: String;
//临时记录与shiJian所对应的歌词字符串
var geCi: String;
//记录歌词的出现时间与对应的歌词
var geCi_ay: Array = new Array();
//定义声音对象
var s_sound: Sound = new Sound();
//创建个MC,做为歌词的容器
this. createEmptyMovieClip( "geCi_mc", this. getNextHighestDepth());
//记录geCi_mc的初始_y
var n_y: Number = Stage. height/2;
geCi_mc. _y = n_y;
//记录现在正在播放第几句歌词
var now: Number = 0;
//
//声明周期回调监听歌曲已播放时间函数的ID
var fun_id: Number;
/*
*/
//加载lrc歌词,参数(lrc歌词地址)
function jiaZai(sUrl: String): Void {
var my_lv: LoadVars = new LoadVars();
my_lv. load(sUrl);
my_lv. onLoad = function(success: Boolean): Void {
if (success) {
//转义十六进制序列字符串。
var s: String = unescape(my_lv. toString());
//trace(s);//去掉前面两斜杠可查看被加载到flash中的lrc歌词原始数据
//将加载的lrc歌词存入sData
sData = s;
//解析lrc歌词
jieXi();
}
};
}
/*
*/
//解析lrc歌词数据。(函数不理解的地方请按F1查看帮助文档,有详细解释)
function jieXi(): Void {
//拆出时间
var nK: Number = sData. indexOf( "[");
var sK: String = sData. substr(nK+1);
var nJ: Number = sK. indexOf( "]");
sData = sK. substr(nJ+1);
//记录到临时时间字符串中
shiJian = sK. substr(0, nJ);
//调用jieXiGeCi函数,拆出歌词
sData2 = sData;
jieXiGeCi();
}
/*
*/
//解析歌词所用函数,返回得到的歌词
function jieXiGeCi(): Void {
//如果这段歌词数据是这种形式([03:07.65][02:12.25]爱情还是要继续吧)记录的,递归,直到找到这句(爱情还是要继续吧)
if (sData2. indexOf( "[") == 0) {
var nJ: Number = sData2. indexOf( "]");
sData2 = sData2. substr(nJ+1);
jieXiGeCi();
//拆出歌词
} else {
var nJ: Number = sData2. indexOf( "/n");
geCi = sData2. substr(0, nJ);
//
//去除歌词中的回车符
geCi = geCi. split( String. fromCharCode(13)). join( "");
//
//调用suanHaoMiao函数,保存歌词信息到 geCi_ay 数组
suanHaoMiao(shiJian, geCi);
//
//如果还有歌词信息,递归,继续提取
if (sData. indexOf( "[")>-1) {
jieXi();
//没有歌词信息了,这时,将sj的值设为"load over",告诉suanHaoMiao函数,已经解析完了
} else {
suanHaoMiao( "load over");
}
}
}
/*
*/
//计算出歌词出现时的毫秒数([00:57.22]格式为[分:秒.毫秒],而我们需要将其全转为毫秒数)
//将得出的毫秒与对应的歌词存入 geCi_ay 数组
//参数(时间,对应的歌词)
function suanHaoMiao(sj: String, gc: String): Void {
//记录毫秒
var haoMiao: Number = 0;
//得出分钟
var ay1: Array = sj. split( ":");
/*因lrc歌词中有([ti:洛丽塔][ar:卓亚君][al:网络秀])之类的信息,
所以,得检测是否为数字,若为数字,即这句为要显示的歌词*/
if (! isNaN( parseInt(ay1[0]))) {
//
//将分钟转为毫秒,加到记录毫秒变量中
haoMiao += parseInt(ay1[0])*60000;
//
//得出秒
var ay2: Array = ay1[1]. split( ".");
//将秒转为毫秒,加到记录毫秒变量中
haoMiao += parseInt(ay2[0])*1000;
//
//将毫秒转为整数,加到记录毫秒变量中
haoMiao += parseInt(ay2[1]);
//
//
//trace(haoMiao+" 毫秒时,显示:"+gc);//去掉前面两斜杠可查看初步解析完的lrc歌词(未排序)
//
//在毫秒与所对应的歌词中间加入":",用于排序,存入 geCi_ay 数组
geCi_ay. push(haoMiao+ ":"+gc);
}
//歌词已经解析完毕
if (sj == "load over") {
//改变歌词数组的排序
geCi_ay. sort(order);
//循环提取,显示歌词信息
for ( var i: Number = 0; i<geCi_ay. length; i++) {
//提取歌词
var ay: Array = geCi_ay[i]. split( ":");
//在geCi_mc容器中,创建文本,显示提取的歌词,每句歌词相隔20像素
var txt: TextField = geCi_mc. createTextField(i+ "_txt", geCi_mc. getNextHighestDepth(), 0, 20*i, Stage. width, 20);
//设置文本居中对齐
txt. autoSize = "center";
//设置文本不可选
txt. selectable = false;
//显示歌词
txt. text = ay[1];
//高亮显示第一句歌词
if (i == 0) {
txt. textColor = 0x990000;
}
}
}
}
/*
*/
//设定数组的排序方法(关于数组的排列,请参阅帮助文档,有详细解释)
function order(a, b): Number {
var n1: Number = parseInt(a. split( ":")[0]);
var n2: Number = parseInt(b. split( ":")[0]);
if (n1<n2) {
return -1;
} else if (n1>n2) {
return 1;
} else {
return 0;
}
}
/*
*/
//监听歌曲已经播放的时间
function jianTingGeQu(): Void {
//如果歌曲已开始播放
if (s_sound. position != undefined) {
//得出下一句歌词的显示时间
var gc_next: Number = parseInt(geCi_ay[now+1]. split( ":")[0]);
//
//如果音乐播放时间已经超过下一句歌词的显示时间
if (s_sound. position>gc_next) {
//将现在这句歌词颜色改为默认色,黑色
geCi_mc[now+ "_txt"]. textColor = 0x000000;
//高亮显示下一句歌词
now++;
geCi_mc[now+ "_txt"]. textColor = 0x990000;
}
//获取这一句歌词的显示时间
var gc_now: Number = parseInt(geCi_ay[now]. split( ":")[0]);
//重新获取下一句歌词的显示时间
var gc_next: Number = parseInt(geCi_ay[now+1]. split( ":")[0]);
//如果下一句歌词不存在,即已是最后一句歌词
if ( isNaN(gc_next)) {
//获取歌曲的结束时间
gc_next = s_sound. duration;
}
//
//我们已经设定,歌词之间_y相隔20像素,算出两句歌词之间每毫秒应该移动多少
var mhm: Number = 20/(gc_next-gc_now);
//得出两句歌词之间已播放多少毫秒
var yhm: Number = Math. floor(gc_next-s_sound. position);
//得出歌词应该到的位置
geCi_mc. _y = n_y-(now*20)+ Math. floor(yhm*mhm);
}
}
/*
*/
//歌曲播放完毕时
s_sound. onSoundComplete = function() {
//清除回调滚动显示歌词函数的ID
clearInterval(fun_id);
trace( "歌曲播放完毕/n原文出处:http://www.rogiture.com/n作者:Rogiture");
};
/*
*/
//当按下播放音乐按钮时,播放音乐,加载lrc歌词
play_btn. onRelease = function(): Void {
//设置按钮不可见
this. _visible = false;
//加载音乐
s_sound. loadSound( "洛丽塔-卓亚君.mp3", true);
//加载lrc歌词
jiaZai( "洛丽塔-卓亚君.lrc");
//周期回调 监听歌曲已播放时间函数
fun_id = setInterval(jianTingGeQu, 1);
};
附上原文件,望受用。
