注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

FlyingWind

 
 
 

日志

 
 
 
 

卡拉OK式歌词同步显示类(ActionScript3.0)开发  

2008-08-29 20:55:48|  分类: Flash制作教程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
卡拉OK式歌词同步显示类(ActionScript3.0)开发

最近更新:2008/09/06  00:48
       在昨天晚上用此程序时发现此程序存在一处因语句执行顺序错误而引起歌词同步显示不正确的错误,现已改正,如果你已经使用过本程序,给你带来了不便,我在这正式向您道谦。同时也谢谢你对本博客的关注,我将会给你带来更多的精彩。期待你的再次来访。


最近更新:2008/09/06  22:22
       我原来的程序有一些不足之处里面有很多不必要的重复计算。在程序二中我对此处进行了优化,对一些数据进行了预处理,对同步显示有一定的好处。
        改进后的源代码:在此日志的后面(版本二)


在我以前的日志《传统歌词同步显示类Actionscript3.0开发中,我向大家介绍了一个关于歌词同步显示的类,现在我向大家介绍一个比上次那个更先进的类卡拉OK式歌词同步显示类

一、Flash软件环境配制,请参考本为日志Flash音量控件(actionscript 3.0)的步骤1-5;
       如果你是一个flash高手可以跳过这一步,(但这一步非常重要,如果不正确将无法运行类)

二、下面正式介绍卡拉OK式歌词显示类。(此类源代码在本日志后面,你可以直接复制保存为KaraokeLyricsDisplay.as文件,如果你对类的定义不太了解的话,请不要用其它的文件名
1.类的构造函数:
  public function KaraokeLyricsDisplay(lyrics:Array,size:int,loop1:Boolean)
此类的构造函数有三个参数
   a、lyrics:一个二维字符串数组,用于保存歌词数据;
   b、size:一个int型变量,用于设置歌词字体的大小。
   c、loop1:用于控制歌词上否循环显示;false只显示一次,true循环显示
上面三个参数size,loop1参数很好理解
而lyrics参数有一定格式要求:以及怎样制作这个二维数组,请看《传统歌词同步显示类Actionscript3.0开发中的说明。

此类非常简单,且还存在一些不足之处,但不会影响你的使用,能达到卡拉OK形式的歌词显示效果,如果你是一位高手,希望你能够改进这个类。


二、下面请看本人使用此类的一个例子。
      flash的设置此处略去。(请大家查看日志Flash音量控件(actionscript 3.0)
      将导入的歌曲《点一把火炬》的链接中类名命名为Music
      然后在第一帧中插入下面代码:

var str:Array=[
["00:02.47","点一把火炬"],
["00:03.73","林俊杰"],
["00:04.76","奥运歌曲"],
["00:12.70","有林俊杰就有爱与希望"],
["00:13.71","天上的星星"],
["00:16.87","有多少数不清"],
["00:20.55","承诺和许愿"],
["00:23.61","又多少能兑现"],
["00:27.41","雨后的彩虹"],
["00:30.62","是真实 还是梦"],
["00:34.17","悲伤和快乐"],
["00:37.28","可以自己选择"],
["00:41.08","忙忙碌碌转呀转"],
["00:43.38","盲盲目目从早到晚"],
["00:48.07","喧喧闹闹是与非"],
["00:49.68","伤痕累累学会谦卑"],
["00:53.48","听过自己哭泣才懂得 珍惜"],
["01:02.25","点一把火炬"],
["01:04.81","让爱和生命延续"],
["01:08.15","用心用呼吸感应"],
["01:11.63","在黑暗中照亮风雨"],
["01:15.38","脆弱的世界"],
["01:18.72","人变得坚强"],
["01:20.66","因为有梦想"],
["01:25.37","让爱翻越所有围墙"],
["01:28.86","点燃每一个心房"],
["01:32.48","照亮我们 共同的家"],
["01:41.33","林俊杰的音乐就是圣火"],
["01:44.20","林俊杰的音乐就是火炬"],
["01:49.65","天上的星星"],
["01:52.82","有多少数不清"],
["01:56.51","承诺和许愿"],
["01:59.63","又多少能兑现"],
["02:03.37","雨后的彩虹"],
["02:06.85","是真实 还是梦"],
["02:10.27","悲伤和快乐"],
["02:13.40","可以自己选择"],
["02:17.12","忙忙碌碌转呀转"],
["02:19.17","盲盲目目从早到晚"],
["02:23.94","喧喧闹闹是与非"],
["02:25.62","伤痕累累学会谦卑"],
["02:29.51","听过自己哭泣才会懂得珍惜"],
["02:36.69","点一把火炬"],
["02:38.95","让爱和生命延续"],
["02:42.53","用心用呼吸感应"],
["02:45.90","在黑暗中照亮风雨"],
["02:50.15","脆弱的世界"],
["02:52.87","人变得坚强"],
["02:55.40","因为有梦想"],
["02:59.74","让爱翻越所有围墙"],
["03:02.96","点燃每一个心房"],
["03:06.77","照亮我们 共同的家"],
["03:12.43","点一把火炬"],
["03:14.97","让爱和生命延续"],
["03:18.72","用心用呼吸感应"],
["03:21.84","在黑暗中照亮风雨"],
["03:26.05","脆弱的世界"],
["03:28.95","人变得坚强"],
["03:30.75","因为有梦想"],
["03:35.72","让爱翻越所有围墙"],
["03:39.25","点燃每个心房"],
["03:42.83","照亮我们"],
["03:44.68","共同的家"],
["03:49.74","照亮你我的家"],
["03:59.74",""]
];

上面与此行颜色相同的那一行非常重要(里面的时间即为上一句歌词的结束时间)

var size:int=30;
var TLD:KaraokeLyricsDisplay=new KaraokeLyricsDisplay(str,size,false);

TLD.x=0;
TLD.y=60;
addChild(TLD);

var snd:Sound=new Music();
var trans:SoundTransform = new SoundTransform(1, 0);
var channel:SoundChannel = snd.play(0, 1, trans);


现在一切OK了,按Ctrl+Enter看看效果吧!
看看我做的效果吧。
要歌词同步性,则二维数组中关于时间的那一列的时间要准
由于本人耐心不好用千千静听编辑歌词时,歌词并不同步,因而做的效果有一点不同步
由于网速的原因也可能你看到的效果是不同步的(原因没有设置等flash下载完后再开始播放),

希望大家能对此类进行改进,或你有其它方法开发的类与大家一起来分享一下。
谢谢大家光顾
 


源代码:2008/08/30  11:00更新
              2008/09/06  00:48更新
 /*
 * Karaoke Lyrics Display
 * ----------------------
 * Written by Dai yiyuan
 *
 *   My blog address
 *  http://colorfuldiary.blog.163.com
 *
 * Please mail me if you
 *- 've found bugs
 *- like this program
 *- don't like a particular feature
 *- would like something to be modified
 *
 * 
 *
*/

package {
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.text.TextFieldType;
    import flash.text.TextField;
    import flash.display.MovieClip;
    import flash.display.Shape;
    import flash.filters.BevelFilter;
    import flash.filters.GlowFilter;
    import flash.filters.BitmapFilterType;
    import flash.filters.BitmapFilterQuality;
    import fl.transitions.Tween;
    import fl.transitions.TweenEvent;
    import fl.transitions.easing.*;


    public class KaraokeLyricsDisplay extends MovieClip {
        var lyrics:Array;
        var txt1:TextField=new TextField();
        var txt2:TextField=new TextField();
        var myFormat1:TextFormat = new TextFormat();
        var maskShape1:Shape=new Shape();
        var maskShape2:Shape=new Shape();
        var myTimer:Timer=new Timer(80,0);
        var i:int=0;
        var loop1:Boolean=false;


        //constructor with two parameters
        //lyrics:Array   a array has the data of lyrics and display time
        //lyrics is a two-dimension array variable 
        //size:int    The fontsize
        //the first dimension store the time for the lyrics display
        //the second dimension store the lyrics
        public function KaraokeLyricsDisplay(lyrics:Array,size:int,loop1:Boolean) {
            this.lyrics=lyrics;
            this.loop1=loop1;
           

            myFormat1.color=0xffffff;
            myFormat1.size=size;
            myFormat1.align=TextFormatAlign.LEFT;
            //Create GlowFilter for txt
            var glow:GlowFilter=new GlowFilter();
            glow.alpha=1;
            glow.blurX=5;
            glow.blurY=5;
            glow.strength=1;
            glow.quality=BitmapFilterQuality.LOW;
            glow.color=0xff0000;

            var glow2:GlowFilter=new GlowFilter();
            glow2.alpha=1;
            glow2.blurX=5;
            glow2.blurY=5;
            glow2.strength=1;
            glow2.quality=BitmapFilterQuality.LOW;
            glow2.color=0x000000;

            txt1.defaultTextFormat=myFormat1;
            txt2.defaultTextFormat=myFormat1;
            txt1.autoSize=TextFieldAutoSize.LEFT;
            txt2.autoSize=TextFieldAutoSize.LEFT;
            txt1.filters=[glow,glow];
            txt2.filters=[glow2];
            txt1.x=0;
            txt1.y=0;
            txt2.x=0;
            txt2.y=0;
            txt1.appendText(" ");
            txt2.appendText(" ");


            maskShape1.graphics.beginFill(0xff5500);
            maskShape1.graphics.drawRect(0,0,1,txt1.height);
            maskShape1.graphics.endFill();
            maskShape1.x=0;
            maskShape1.y=0;
            maskShape2.graphics.beginFill(0xff5500);
            maskShape2.graphics.drawRect(0,0,1,txt1.height);
            maskShape2.graphics.endFill();
            maskShape2.x=0;
            maskShape2.y=0;

            this.addChild(maskShape1);
            this.addChild(maskShape2);
            this.addChildAt(txt2,1);
            this.addChildAt(txt1,2);

            txt1.mask=maskShape1;
            txt2.mask=maskShape2;

            myTimer.addEventListener("timer", showLyrics);
            myTimer.start();
        }
        private function showLyrics(evt:TimerEvent):void {
            var time:Number=myTimer.currentCount * 80;
            if (i<lyrics.length-1) {
                var temp1=Number(lyrics[i][0].substr(0,2))*60+Number(lyrics[i][0].substr(3,5));
                if (time >= 1000*temp1) {
                    var temp2=Number(lyrics[i+1][0].substr(0,2))*60+Number(lyrics[i+1][0].substr(3,5));
                    txt1.replaceText(0,txt1.length,lyrics[i][1]);
                    txt2.replaceText(0,txt2.length,lyrics[i][1]);
                    this.width=txt1.width;
                    maskShape2.width=txt2.width;
                    var myTween:Tween=new Tween(maskShape1,'scaleX',None.easeIn,5,txt1.width,temp2-temp1-0.3,true);

                    i++;
                 

                }
            } else {
               
                evt.target.reset();
                if(loop1){
                    evt.target.start();
                }
                i=0;
               
            }

        }
    }
}




-------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------
//程序版本二,
/*
 * Karaoke Lyrics Display
 * ----------------------
 * Written by Dai yiyuan
 *
 *   My blog address
 *  http://colorfuldiary.blog.163.com
 *
 * Please mail me if you
 *- 've found bugs
 *- like this program
 *- don't like a particular feature
 *- would like something to be modified
 *
 * 
 *
*/

package {
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.text.TextFieldType;
    import flash.text.TextField;
    import flash.display.MovieClip;
    import flash.display.Shape;
    import flash.filters.BevelFilter;
    import flash.filters.GlowFilter;
    import flash.filters.BitmapFilterType;
    import flash.filters.BitmapFilterQuality;
    import fl.transitions.Tween;
    import fl.transitions.TweenEvent;
    import fl.transitions.easing.*;


    public class KaraokeLyricsDisplay extends MovieClip {
        var lyrics:Array;
        var txt1:TextField=new TextField();
        var txt2:TextField=new TextField();
        var myFormat1:TextFormat = new TextFormat();
        var maskShape1:Shape=new Shape();
        var maskShape2:Shape=new Shape();
        var myTimer:Timer=new Timer(60,0);
        var i:int=0;
        var loop1:Boolean=false;


        //constructor with two parameters
        //lyrics:Array   a array has the data of lyrics and display time
        //lyrics is a two-dimension array variable 
        //size:int    The fontsize
        //the first dimension store the time for the lyrics display
        //the second dimension store the lyrics
        public function KaraokeLyricsDisplay(lyrics:Array,size:int,loop1:Boolean) {
            this.lyrics=lyrics;
            this.loop1=loop1;
           

            myFormat1.color=0xffffff;
            myFormat1.size=size;
            myFormat1.align=TextFormatAlign.LEFT;
            //Create GlowFilter for txt
            var glow:GlowFilter=new GlowFilter();
            glow.alpha=1;
            glow.blurX=5;
            glow.blurY=5;
            glow.strength=1;
            glow.quality=BitmapFilterQuality.LOW;
            glow.color=0xff0000;

            var glow2:GlowFilter=new GlowFilter();
            glow2.alpha=1;
            glow2.blurX=5;
            glow2.blurY=5;
            glow2.strength=1;
            glow2.quality=BitmapFilterQuality.LOW;
            glow2.color=0x000000;

            txt1.defaultTextFormat=myFormat1;
            txt2.defaultTextFormat=myFormat1;
            txt1.autoSize=TextFieldAutoSize.LEFT;
            txt2.autoSize=TextFieldAutoSize.LEFT;
            txt1.filters=[glow,glow];
            txt2.filters=[glow2];
            txt1.x=0;
            txt1.y=0;
            txt2.x=0;
            txt2.y=0;
            txt1.appendText(" ");
            txt2.appendText(" ");


            maskShape1.graphics.beginFill(0xff5500);
            maskShape1.graphics.drawRect(0,0,1,txt1.height);
            maskShape1.graphics.endFill();
            maskShape1.x=0;
            maskShape1.y=0;
            maskShape2.graphics.beginFill(0xff5500);
            maskShape2.graphics.drawRect(0,0,1,txt1.height);
            maskShape2.graphics.endFill();
            maskShape2.x=0;
            maskShape2.y=0;

            this.addChild(maskShape1);
            this.addChild(maskShape2);
            this.addChildAt(txt2,1);
            this.addChildAt(txt1,2);

            txt1.mask=maskShape1;
            txt2.mask=maskShape2;

            myTimer.addEventListener("timer", showLyrics);
            myTimer.start();
           
            for(var i=0;i<lyrics.length;++i){
                lyrics[i][0]=Number(lyrics[i][0].substr(0,2))*60+Number(lyrics[i][0].substr(3,5));
            }
        }
        private function showLyrics(evt:TimerEvent):void {
            var time:Number=myTimer.currentCount * 60;
            if (i<lyrics.length-1) {
                if (time >= 1000*Number(lyrics[i][0])) {
                    txt1.text=lyrics[i][1];
                    txt2.text=lyrics[i][1];
                    this.width=txt1.width;
                    maskShape2.width=txt2.width;
                    var myTween:Tween=new Tween(maskShape1,'scaleX',None.easeInOut,5,txt1.width,lyrics[i+1][0]-lyrics[i][0]-0.8,true);

                    i++;
                }
            } else {
               
                evt.target.reset();
                if(loop1){
                    evt.target.start();
                }
                i=0;
               
            }

        }
    }
}
  评论这张
 
阅读(638)| 评论(6)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018