2013-03-26

Flashで外部swfに埋め込んだサウンドをBGMにする

FlashでBGMを再生する方法をメモ。

外部MP3ファイルをswfで読み込んで再生するのは、mp3のライセンス料がかかる危険があるらしい。(「商用利用のときは」ライセンス料必要らしい) swfにmp3を埋め込んでおけば問題ないという。

しかし、ビルドごとにmp3を埋め込むのも何なので、mp3埋め込みswfを作っておき、それを実行時に読み込むことにする。

実際のFlash:
カーソルキーの ← → を押すと、曲を再生/別の曲を再生。
カーソルキーの ↑ ↓ を押すと、音量UP/DOWN。
スペースキーで曲をストップ。

https://sites.google.com/site/itouhiro/2013/20130326bgm.swf

音楽ファイルは http://www.ne.jp/asahi/music/myuu/ を使わせていただいた。

環境

  • Windows7 64bit
  • FlashPro CS6
  • FlashDevelop 4.0.4 + Flex SDK 4.6

ソース

Main.as

package 
{
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.ProgressEvent;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundTransform;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;
    import flash.text.TextField;
    
    /**
     * ...
     * @author itouhiro
     */
    [SWF(width="320",height="240",backgroundColor="0xfcfcfc",frameRate="30")]
    public class Main extends Sprite 
    {
        private var channel:SoundChannel;
        private var preloadText:TextField;
        private var songs:Array = [];
        private var songIndex:int;
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            //preloader
            preloadText = new TextField();
            preloadText.x = stage.stageWidth/3; preloadText.y = stage.stageHeight/3;
            preloadText.text = 'Loading: 0 %';
            addChild(preloadText);
            
            //load external swf
            var req:URLRequest = new URLRequest('https://sites.google.com/site/itouhiro/2013/20130326soundwavCS6.swf');
            var ld:Loader = new Loader();
            var context:LoaderContext = new LoaderContext();
            context.applicationDomain = ApplicationDomain.currentDomain;
            ld.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
            ld.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
            ld.load(req, context);            
        }
        
        private function loadProgressHandler(e:ProgressEvent):void 
        {
            var percentLoaded:int = Math.round(e.bytesLoaded / e.bytesTotal * 100);
            preloadText.text = 'Loading: ' + percentLoaded + ' %';
        }        
        
        private function loadCompleteHandler(e:Event):void 
        {
            //removeChild(preloadText);
            
            // register resources(music) in the external swf
            var wavfiles:Array = 'musicbox loop1 whistle'.split(' ');
            for (var i:int = 0; i < wavfiles.length; i++) {
                var classRef:Class = ApplicationDomain.currentDomain.getDefinition(wavfiles[i]) as Class;
                var snd:Sound = new classRef();
                songs[i] = snd;
            }
            
            // play sound
            channel = new SoundChannel();
            songIndex = 0;
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            
            // operate sound
            var infoText:TextField = new TextField();
            infoText.text = "^ VolUp\nv VolDown\n< PrevSong\n> NextSong";
            addChild(infoText);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        }
        
        private function keyDownHandler(e:KeyboardEvent):void 
        {
            var tran:SoundTransform;
            trace('keyCode:' + e.keyCode);
            if (e.keyCode == 40) {
                tran = channel.soundTransform;
                tran.volume = tran.volume / 2 + 0.01;
                channel.soundTransform = tran;
            }else if (e.keyCode == 38) {
                tran = channel.soundTransform;
                tran.volume = tran.volume * 2;
                channel.soundTransform = tran;
            }else if (e.keyCode == 37) {
                channel.stop();
                songIndex = songIndex - 1;
                if (songIndex < 0) { songIndex = songs.length - 1; }
                channel = songs[songIndex].play(0, 100);
            }else if (e.keyCode == 39) {
                channel.stop();
                songIndex = (songIndex + 1) % songs.length;
                channel = songs[songIndex].play(0, 100);
            }else if (e.keyCode == 32) {
                channel.stop();
            }
        }
        
        private function enterFrameHandler(e:Event):void 
        {
            preloadText.text = 'PlayingTime: ' + (channel.position/1000).toString().slice(0,4) + ' sec.';
        }
    }
}

Sound.play(0,100) の1番目の引数 0 は曲のはじめから演奏するということ。2番目の引数 100 は100回ループするということ。

SoundChannel.stop() で曲を止める。もし止めずに Sound.play()すると、複数の曲を重ねて演奏する。

サウンド埋め込みswfはFlash CS6にwavファイルを読み込ませ、sound stream設定で mp3 80KHz monoral で[パブリッシュ]。

0 件のコメント:

コメントを投稿

人気記事