LRC歌词与音乐同步播放

打造你完美的音乐播放器 - LRC歌词与音乐同步播放

打造你完美的音乐播放器 - 从搜索引擎获取MP3地址
打造你完美的音乐播放器 - 从搜索引擎获取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);
};




附上原文件,望受用。
下载文件 原文件下载 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值