Tag/AIR

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/

第4回:AIRでメニューウィンドウ作成!を試してみる

昨日からテストログを見ている時に時間があるので、

Airをやってます。

で、アプリケーションを作りたいなぁーと妄想しているので、 サンプルとして何かないか?と困っていたら、

良いのがあったのでやってみた。

やったのは、こちら

第4回:AIRでメニューウィンドウ作成!を試してみる

実際に書かれている物を確認しつつ進めていった時に、

Application Descriptorの記述が変更されていたりで

動かなかった所を修正しつつ行っていく。

環境はMacBookで、

OS X 10.5.5

です。

行った場所は自分のホームディレクトリなどで実行。 例)Users/sticikes とかで。

下記は全てターミナルにて行いました。

まずはアプリケーション記述ファイルが必要になるので、同じ階層で、「stickies-app.xml」ファイルを作成・記述する。

$ cd /Users/stickies
$ touch stickies-app.xml
$ vim stickies-app.xml

記述は下記が記載されていた。

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.0.M4" appId="jp.masuidrive.thinkit.stickies" version="1.0">
    <name>オンライン付箋</name>
    <rootContent systemChrome="standard">menu.swf</rootContent>
</application>

次に「menu.mxml」を同じディレクトリにて、作成・記述する。

$ touch menu.mxml
$ vim menu.mxml

menu.mxmlへは下記を記述する。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="200">
  <mx:Button left="10" top="10" label="新規" id="new_btn" />
  <mx:Button right="60" top="10" label="読み込み" id="load_btn" />
  <mx:Button right="10" top="10" label="保存" id="save_btn" />
  <mx:TextArea right="10" top="40" left="10" bottom="10" id="messages" />
</mx:WindowedApplication>

これはそのまま書かれている通りでOK。

次にswfファイルを生成する。

$ amxmlc menu.mxml

上記コマンドでコンパイルすると、「menu.swf」が生成される。

下記コマンドでswfファイルを確認する。

$ ls
menu.mxml         menu.swf

これでファイルが出来たので、実際にadlコマンドで実行してみる。

$ adl stickies-app.xml
invalid application descriptor: application filename must have a non-empty value.

あーエラーになってしまった。。。

これは、冒頭に書いたとおりApplication Descriptorの記述が変わっているためなので、

「stickies-app.xml」を変更する必要がある。

$ vim stickies-app.xml

記述する内容は、下記。

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.5" appId="jp.masuidrive.thinkit.stickies" version="1.0">
    <id>kishi-r.com.stickies</id>
    <name>オンライン付箋</name>
    <version>1.0</version>
    <filename>stickies</filename>
    <description>Hello first application</description>
    <copyright>(c) 2008 </copyright>
    <initialWindow>
        <content>menu.swf</content>
        <title>Sticies Menu</title>
        <systemChrome>none</systemChrome>
        <transparent>true</transparent>
        <visible>true</visible>
    </initialWindow>
</application>

でもう一度実行してみる。

$ adl stickies-app.xml

そうすると下記のような画面が表示されるはず。

menu01
menu01 posted by (C)kishir

次に実際にボタンを押す時の動作部分を少しやってみる。

記述するファイルは、「menu.mxml」ファイル

$ vim menu.mxml

で、下記の通り記述する。

<mx:Button left="10" top="10" label="新規" id="new_btn" />

へ「click="create();"」を追加する。

<mx:Button left="10" top="10" label="新規" id="new_btn" click="create();" />

実際に「create関数」を定義する。

定義するのは、同じファイル「menu.mxml」で、記述すると下記のようになる。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="200">
    <mx:Script>
    <![CDATA[
        public var sticky:NativeWindow;
        public function create():void {
            var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
            sticky = new NativeWindow(true, initOptions);
            messages.text += ">> Created new sticky\n"; // debug display
        }
    ]]>
    </mx:Script>
    <mx:Button left="10" top="10" label="新規" id="new_btn" click="create();" />
    <mx:Button right="60" top="10" label="読み込み" id="load_btn" />
    <mx:Button right="10" top="10" label="保存" id="save_btn" />
    <mx:TextArea right="10" top="40" left="10" bottom="10" id="messages" />
</mx:WindowedApplication>

実際に実行して確認してみる。

$ adl stickies-app.xml

動かない。。。

何でなのかを調べたら、ここに書いてありました。

やっぱ解らない時はGoogleさんに聞くのって、問題かな?

まぁーそれは良いとして続きをやろうっと。

NativeWindow クラスのコンストラクタに変更があった模様

そうなのか。

じゃー変更しないとなーって事で、「menu.mxml」を下記のように変更する。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="200">
    <mx:Script>
    <![CDATA[
        public var sticky:NativeWindow;
        public function create():void
        {
            var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
            sticky = new NativeWindow(initOptions);
            sticky.visible = true;
            messages.text += ">> Created new sticky\n"; // debug display
        }
    ]]>
    </mx:Script>
    <mx:Button left="10" top="10" label="新規" id="new_btn" click="create();" />
    <mx:Button right="60" top="10" label="読み込み" id="load_btn" />
    <mx:Button right="10" top="10" label="保存" id="save_btn" />
    <mx:TextArea right="10" top="40" left="10" bottom="10" id="messages" />
</mx:WindowedApplication>

修正しただけだとswfファイルに反映されないので、もう一度コンパイルする必要があるので下記を実行。

$ amxmlc menu.mxml

その後にもう一度ウィンドウを立ち上げて確認する。

$ adl stickies-app.xml

立ち上げたら「新規」ボタンをクリックすると、新たにウィンドウがもう一つ立ち上がりメッセージが表示される。

menu02
menu02 posted by (C)kishir

これで新規ボタンだけ動くウィンドウが出来た。

続きはまた後で、って事で。

Posted at: 
2008/11/22 16:00:46
0 Comments
0 TrackBacks
Tags: 
ActionScript
AIR
Flex
Trackback: 
http://kishi-r.com/2008/11/22/air_menu_window/trackback/

Adobe FlexSDKとAirを使ってみる

ずーっとやろうやろうで、なぁなぁになっていたASをやるために

・Flex SDK
・Air

をMacにインストールしてみた。

参考にしたのは、

UNIX(Mac OS X)におけるFlex 3 SDKによるAIRプログラミング 環境設定 - Memorizeです。

ちなみに自分Macの環境は、

・Mac OS X 10.5.5

です。

インストールした内容は下記の通りで、全てターミナルから実行した。

1.まずはFlexSDKのダウンロード

・FlexSDK 3.2.0.3794(Stable Builds)※試しでって事で。

下記リンクからダウンロード可能。

Flex 3 SDK Downloads

2.Airのインストール

Adobe AIR 1.5 インストーラ Macintosh OSX, 日本語 | 21.1 MB

からインストーラを取得してインストールする。

ディスクイメージをマウントしてそのままAdobe AIR Installer.appを実行すればインストールが始まるので、手順に従うのみ。

3.FlexSDKの設定

FlexSDK 3.2.0.3794をダウンロードすると、

flex_sdk_3.2.0.3794.zip

というファイルがダウンロード出来る。 それを展開すると、

flex_sdk_3.2.0.3794

というディレクトリになる。

4.FlexSDKの設置

今回は上記ファイル「flex_sdk_3.2.0.3794」をリネームして、

flex_sdk

とした。 ※本当はバージョン付けるべきなんだろうな。。。

そのディレクトリを

/usr/local/src/

などの下に設置するので、

/usr/local/src/flex_sdk

のようになる。

5.flex_sdkへのPathを通す。

.bashrcや.profileなどに

/usr/local/src/flex_sdk/bin

を追加して、

$ . .bashrc

もしくは、

$ . .profile

にてPathの追加を適応させる。

※これをやらないとPathを追加しただけでは適応されない。

Pathが通っているかの確認は、まずは「adl」のhelp

$ adl -help
$ usage:
 adl ( -runtime <runtime-dir> )? ( -pubid <pubid> )? -nodebug? <app-desc> <root-dir>? ( -- ... )?
 adl -help

次に「amxmlc」のhelpを確認する。

$ amxmlc -help
Adobe Flex Compiler (mxmlc)
Version 3.2.0 build 3794
Copyright (c) 2004-2007 Adobe Systems, Inc. All rights reserved.

-help [keyword] [...]
   コマンドラインシンタックスの情報および設定変数の説明については、検索ストリングまたは次のいずれかの特別なキーワードを指定します :
      syntax   - コマンドラインの一般的なシンタックスを説明します
      list     - すべての基本的な設定変数を一覧表示します
      advanced - 高度な設定変数を検索します
      aliases  - 変数の短いエイリアスを使用してソートします
      details  - 各アイテムの完全な詳細を常に表示します
   その他のヘルプキーワードは、完全または部分的に一致する設定変数、エイリアス、設定変数の説明内に含まれるテキストの検索に使用されます。

   例えば、'-help advanced aliases foo' と入力すると、'foo'
   というテキストを含むすべての設定オプション(基本および高度の両方)がエイリアス名順にソートされて表示されます。

   個別の設定変数の説明では、必須の値は山カッコで示され、オプション値は角カッコで示されます。[...]
   は、値が任意の長さのリストであることを示すために使われます。

のように実行出来ればOK。 これで準備は整ったので、実際に試してみることにする。

試した内容は、本当に初歩の初歩で、

1.AIRアプリケーション生成準備
2.AIR用にコンパイル
3.AIRアプリケーションの生成
4.パッケージを生成する

これはら全て

UNIX(Mac OS X)におけるFlex 3 SDKによるAIRプログラミング 環境設定 - Memorizeに記載されているものを行いました。

1.AIRアプリケーション生成準備

ということで適当な「MXMLファイル」を用意する。

MXMLファイルって何だろう?って調べたら、

・ユーザーインターフェイスを定義する
・プログラムのロジックを記述する

らしいです。

hello.mxmlというファイル名で実際に記述してみる。

<?xml version="1.0" encoding='utf-8'?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml">
       <mx:Text text="Hello." />
       <mx:Button label="Button1" id="button1" />
       <mx:Button label="Button2" id="button2" />
       <mx:Button label="Button3" id="button3" />
</mx:WindowedApplication>

2.AIR用にコンパイル

次に、このhello.mxmlをAIR用にコンパイルする。

コンパイルはターミナルから、

$ amxmlc hello.mxml

すると、同じ階層に「hello.swf」というファイルが出来上がる。

$ ls
hello.mxml     hello.swf

次にアプリケーションの情報を記述すADF(Application Descriptor File)とよばれるXMLファイルを用意する。

ファイル名は「hello-app.xml」とした。

ADFファイルの細かい説明は、

UNIX(Mac OS X)におけるFlex 3 SDKによるAIRプログラミング 環境設定 - Memorizeドキュメントを参照。
<?xml version="1.0" encoding="utf-8" ?>
<application xmlns="http://ns.adobe.com/air/application/1.5" minimumPatchLevel="1047">
       <id>net.memorize-being.flex-air.hello</id>
       <name>Hello</name>
       <version>1.0</version>
       <filename>hello</filename>
       <description>Hello first application</description>
       <copyright>(c) 2008 </copyright>
       <initialWindow>
               <content>hello.swf</content>
               <title>Hello</title>
               <systemChrome>none</systemChrome>
               <transparent>true</transparent>
               <visible>true</visible>
               <minimizable>true</minimizable>
               <maximizable>false</maximizable>
               <resizable>false</resizable>
               <x>150</x>
               <y>150</y>
       </initialWindow>
       <installFolder>memorize-being/Hello</installFolder>
       <programMenuFolder>memorize-being/Hello</programMenuFolder>
       <customUpdateUI>false</customUpdateUI>
         <allowBrowserInvocation>false</allowBrowserInvocation>
</application>

ここで気をつけるのが、

<application xmlns="http://ns.adobe.com/air/application/1.5" minimumPatchLevel="1047">

の部分にある「application/1.5」の部分。

これはAIRのバージョンにより変わるので注意する。

今回は「AIR1.5」を使用しているため「1.5」となっている。

3.AIRアプリケーションの生成

生成前でも実行することが可能らしいので、ターミナルから下記コマンドを実行する。

$ adl hello-app.xml

そうすると、

air_hello
air_hello posted by (C)kishir

とウィンドウが表示される。

4.パッケージを生成する

セキュリティの問題によりディジタル証明書を使ってディジタル署名をする必要があります。
公的なディジタル証明書を入手するのは大変ですが、
勝手に証明書を発行する事も出来ます。
ただし、この証明書はCAにより認証されていないためインストール時に警告が表示されます。

ほほう。では実際に試してみる事にする。

下記コマンドで、証明書"hello.pfx"を生成する。

$ adt -certificate -cn <証明書名> 1024-RSA hello.pfx <パスワード>

パスワードは次に入力する必要があるので、覚えておく。

$ adt -package -storetype pkcs12 -keystore hello.pfx hello.air hello-app.xml hello.swf
password:<パスワードを入力>

airファイルを確認する。

$ ls
hello-app.xml  hello.air      hello.mxml     hello.pfx      hello.swf

ファイルが出来ているのを確認して、実際に「air」ファイルから実行してみる。

「hello.air」をダブルクリックすると、

hello_install
hello_install posted by (C)kishir

と表示されるので、「インストール」をクリックする。

次に「インストール先」を聞かれるので、

hello_install2
hello_install2 posted by (C)kishir

「続行」をクリックすると先ほど表示されたウィンドウが立ち上がる。

air_hello
air_hello posted by (C)kishir

これで完了です。 また「hello.air」をダブルクリックすると、同じ場所に同じバージョンがあります。

と言われるので、そこからアンインストールする事も可能でした。

とりあえず一通り完了したので続きはまたって事で。

Posted at: 
2008/11/22 02:04:14
0 Comments
2 TrackBacks
Tags: 
ActionScript
AIR
Flex
Trackback: 
http://kishi-r.com/2008/11/22/flex_sdk_air/trackback/

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

Categories