AIRでMP3Playerを試してみる

とりあえず勢いで作ってみた。

参考にしたサイトは、Adobe AIRでクールなMP3プレーヤーを作ってみる

上記では、タイトル名を取得しているがどうしても取れなく断念している真っ最中orz

ソースは下記

<?xml version="1.0"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
   <mx:Script>
       <![CDATA[
       import flash.desktop.ClipboardFormats;
       import flash.events.NativeDragEvent;
       import flash.desktop.NativeDragManager;
       import flash.filesystem.File;
       import flash.media.Sound;
       import flash.media.SoundChannel;
       import flash.net.URLRequest;
       import flash.display.Sprite;
       import mx.core.UIComponent;

       [Bindable]
       private var sound:Sound;
       private var soundChannel:SoundChannel;
       private var playing:Boolean = false;
       private var file:File;
       private var pausePos:Number = 0;
       private var playBar:Sprite;
       private var spriteRight:Sprite;
       private var spriteLeft:Sprite;
       private var uic:UIComponent;

       private function initApp():void
       {
           soundChannel = new SoundChannel();
           spriteRight = new Sprite();
           spriteLeft = new Sprite();
           uic = new UIComponent;
           uic.x=122;
           uic.y=40;
           this.addChild(uic);
           spriteRight.graphics.beginFill(0x0000ff);
           spriteRight.graphics.drawRect(0, 0, 0.1, 20 );
           spriteRight.graphics.endFill();
           spriteLeft.graphics.beginFill(0x0000ff);
           spriteRight.graphics.endFill();
           spriteLeft.graphics.beginFill(0x0000ff);
           spriteLeft.graphics.drawRect(0, 22, 0.1, 20 );
           spriteLeft.graphics.endFill();
           uic.addChild(spriteRight);
           uic.addChild(spriteLeft);
           addEventListener(Event.ENTER_FRAME,enterHandler);

           addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, dragEnterHandler);
           addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, dragDropHandler);
       }

       private function dragEnterHandler(e:NativeDragEvent):void
       {
           var files:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
           if(files != null && File(files[0]).extension == "mp3")
           {
               NativeDragManager.acceptDragDrop(this);
           }
       }

       private function dragDropHandler(e:NativeDragEvent):void
       {
           var files:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;

           if (playing)
           {
               soundChannel.stop();
           }
           sound = new Sound();
           sound.load(new URLRequest(File(files[0]).url));
           soundChannel = sound.play();
           playing = true;
       }

       private function musicPlay():void
       {
           try{
               soundChannel = sound.play(pausePos);
               playing = true;
           }catch(e:Error){
           }
       }

       private function enterHandler(event:Event):void
       {
           spriteRight.width = soundChannel.rightPeak * 100;
           spriteLeft.width  = soundChannel.leftPeak  * 100;
       }

       private function musicPause():void
       {
           if(playing == true){
               pausePos = soundChannel.position;
               soundChannel.stop();
           }
           playing = false;
       }

       private function musicStop():void
       {
           if(playing == true){
               soundChannel.stop();
               pausePos = 0;
           }
           playing = false;
       }

       private function selectHandler(event:Event):void
       {
           sound = new Sound();
           sound.load(new URLRequest(File(file).url));
           soundChannel = sound.play();
           playing = true;
       }

       private function selectFile():void
       {
           musicStop();
           playing = false;
           file = new File();
           file.browse();
           file.addEventListener(Event.SELECT,selectHandler);
       }

       private function drawBar(col:uint):Sprite
       {
           var bar:Sprite = new Sprite();
           bar.graphics.lineStyle(0, col);
           bar.graphics.beginFill(col, 1);
           bar.graphics.drawRect(0, 0, 1, 10);
           bar.graphics.endFill();
           bar.x = 20;
           bar.y = 370;
           return bar;
       }
       ]]>
   </mx:Script>
   <mx:Button id="openBtn" label="OPEN" x="10" y="10" width="80" click="selectFile();"/>
   <mx:Button id="playBtn" label="PLAY" x="10" y="35" width="80" click="musicPlay();"/>
   <mx:Button id="stopBtn" label="STOP" x="10" y="60" width="80" click="musicStop();" />
   <mx:Button id="pauseBtn" label="PAUSE" x="10" y="85" width="80" click="musicPause();" />
   <mx:TextInput id="titleText" color="0xffff00" backgroundColor="0x000000"  x="100" y="10"/>
   <mx:Label text="R" x="100" y="40" width="20"/>
   <mx:Label text="L" x="100" y="62" width="20"/>
</mx:WindowedApplication>

こんな感じに書いてみた。

一応「一時停止」と「ドラッグアンドドロップ」を足してみた。

が、

・一時停止をクリックしてから、停止を押しても効かない

・演奏中にファイルを選択しようとすると演奏が止まってしまう

・複数のファイルを選択してリスト表示出来ない

・そもそもまだタイトル名が取れていない

・mp3にしか対応していないので、mp4やm4a、WAVにも対応する必要がある

など、 まだまだ改善する点もあるし、全然オブジェクト指向に作られていないので、別のasファイルにする必要もある。

他にもボタンなどは、直に書かずに何かしら生成出来るような仕組みでないと柔軟ではないな。

そこら辺も考慮する必要があるので、もうちょっと頑張ってみる。

とりあえず現状の画面は下記になる。

musicplayer
musicplayer posted by (C)kishir

ってかActionScriptにもFlexにもまだまだ慣れていないので、色々と勉強する事が盛りだくさんな今日この頃ですなぁー。

※09/02/17 追記

t-matsuda氏に助言をいただき、試してみました。

修正箇所は下記。

private function dragDropHandler(e:NativeDragEvent):void
{
    var files:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;

    if (playing)
    {
        soundChannel.stop();
    }
    sound = new Sound();
    sound.load(new URLRequest(File(files[0]).url));
    //soundChannel = sound.play();
    //playing = true;
    musicPlay();
}

は、musicPlayメソッドにて再生するように変更して、

同じくselectHandlerにても同じようにmusicPlayメソッドを使用する。

private function selectHandler(event:Event):void
{
    sound = new Sound();
    sound.load(new URLRequest(File(file).url));
    //soundChannel = sound.play();
    //var filename:FileReference = FileReference(event.target);
    //playing = true;
    musicPlay();
}

で次がキモ。

private function musicPlay():void
{
    try {
        soundChannel = sound.play(pausePos);
        soundChannel.addEventListener(Event.ID3, onID3Info, false, 0, true);
        playing = true;
    }catch(e:Error){
    }
}

musicPlayメソッドにて、リスナーをEvent.ID3イベントを監視するサウンドのインスタンスに追加する。

これにより送られてくるイベントオブジェクトからサウンドのid3プロパティを参照が可能になる。

それが下記。

private function onID3Info(evt:Event):void
{
    var id3Props:ID3Info = evt.target.id3;
    for (var propName:String in id3Props) {
        trace("ID3 Tag", propName, "=", id3Props[propName]);
    }
}

上記のtraceしている部分がそう。

このtrace部分をテキストにぶち込むようにすれば、OKなはずだが・・・そもそもid3情報が無いものばかりなのかやはりnullというかtraceしても何も出ない。

ん〜そもそもAdobe® Flex™ 3 リファレンスガイドを見た所、ID3Infoはランタイムバージョン : 1.0 9

ってなってる。 ランタイムバージョンが1.0 9って事は1.5ではダメってことか?

もう面倒だからファイル名から取って拡張子でも消すか?

var filename:FileReference = FileReference(event.target);

でファイル名も取れるしなぁー、悩ましい。。。

Posted at: 
2009/02/16 23:17:54
2 Comments
0 TrackBacks
Tags: 
ActionScript
AIR
Flex
Trackback: 
http://kishi-r.com/2009/02/16/air_mp3player/trackback/

TrackBacks

まだ登録されていません。

Comments

t-matsuda

Soundのタイトルは、
Sound.id3 (ID3Infoクラス) から取ると思うのですが、
ID3 メタデータが設定されていないMP3ファイルとかもあるので
それが原因で取れてないとか?

見当違いだったらすいません。

Created at: 
2009/02/17 11:29:25

kishir

コメントありがとーございます。
そうなんすよねぇー。
その方法でも取れなくて困ってるんすよ。
先ほど教えて貰ったのを試してみるので、
その結果をまた追記しておきますね。

Created at: 
2009/02/17 12:52:31

Add Comment

Add Comment
あわせて読みたい 人気ブログランキング - kishi-r.com track feed

Categories