作成日

18 November 2010

必要条件

この記事に必要な予備知識

  • Adobe AIR インストーラー
  • Adobe AIR SDK
  • Flash Builder 4(Standard、 Premium どちらでも可)
  • マイク
  • スピーカーまたはイヤフォン

ユーザーレベル

すべて

2010年6月9日にAdobe AIR 2がリリースされました。約2年半振りのメジャーバージョンアップとなり、多くの新機能追加と機能強化が行われています。本連載(全9回予定)では、 それら機能について詳しく説明するとともに、サンプルアプリを用いながらその使い方を解説していきます。

 

第1回 Adobe AIR 2をはじめよう
第2回 サーバーソケット/ データグラムソケットなどのネットワーク系機能
第3回 Safari 4.0.3 と同等の WebKit を搭載
第4回 プリンタ情報の取得や印刷ダイアログの制御
第5回 OSネイティブな機能との連携
第6回 OSネイティブとの統合
第7回 グローバルエラーハンドラー/IMEテキスト入力の機能強化
第8回 外部デバイス(マイク)との連携

本記事では、Adobe AIR 2のデバイス連携機能について紹介します。デバイス連携機能を利用することによって、マイクやカメラなどの機能を使用することができます。

本記事のサンプル:AIR2master08sample.zip

Microphone API

Adobe AIR 2 以前、または Flash Player 10.1 以前のバージョンのアプリケーションやコンテンツ上でマイク入力をサウンドデータとして取り扱う場合、NetStream オブジェクトの attachAudio() メソッドを使用して、ストリームを介したオーディオのキャプチャ/送信を行い、Flash Media Server などのサーバー製品を利用してサーバーサイドで処理しなければなりませんでした。しかし、Adobe AIR 2/Flash Player 10.1 では、マイク入力のイベントを検知したときのイベントハンドラでサウンドデータを取得することができるようになりました。

マイクのサポートチェックとマイク入力検知

以下のコードでは、マイクのサポートチェックとマイク入力を検知しています。

/** 初期化処理 */ function applicationCompleteHandler():void { if( !Microphone.isSupported ) { //マイクのサポートチェック //Microphone クラスは非サポート return; } var mic:Microphone = Microphone.getMicrophone(); // Microphone オブジェクトの取得 if(mic != null) { mic.addEventListener(ActivityEvent.ACTIVITY, activityHandler); mic.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler); } } /** マイクセッションの開始または終了したときに実行*/ function activityHandler(event:ActivityEvent):void { logTextArea.appendText( ( event.type + "\n" ) ); } /** マイクのバッファにサウンドデータがあるときに実行*/ function sampleDataHandler(event:SampleDataEvent):void { logTextArea.appendText( ( event.type + "\n" ) ); }

Microphone.isSupported プロパティは、Adobe AIR 2/Flash Player 10.1 専用の読み取り専用プロパティです。アプリケーションの実行環境にて Microphone クラスがサポートされている場合は true を、サポートされていない場合は false を返します。基本的にデスクトップ環境はMicrophone クラスをサポートしていますが、モバイル環境の中にはサポートしていないことがあるので、AIR for Android(Adobe AIR 2.5 以降)を利用したモバイルアプリ開発ではこのプロパティが特に役立ちます。

※Camera クラスにも Camera.isSupported という Adobe AIR 2/ Flash Player 10.1専用の読み取り専用プロパティが用意されており、Microphone.isSupported プロパティと同じように、このプロパティを使ってCamera クラスがサポートされているかどうかを調べることができます。

Microphone.isSupported プロパティで Microphone クラスがサポートされていることを確認できたら、マイクを使用して音声を入力します。サンプルでは、マイクセッションの開始または終了したときに送出されるActivityEvent.ACTIVITY(“activity”) イベントと、マイクのバッファにサウンドデータがあるときに送出されるSampleDataEvent.SAMPLE_DATA(“sampleData”) イベントが検知され、テキストエリアに送出されたイベント形式が出力されます。

SampleDataEvent.SAMPLE_DATA イベントハンドラの引数である SampleDataEvent オブジェクトには、サウンドデータのバイト配列 (ByteArray 型)である data プロパティが含まれています。このバイト配列に格納されるサウンドサンプルは、浮動小数点値(Number 型の値)のモノラルサウンドサンプルです。

マイク入力サウンドデータの保存と再生

次に、サウンドデータを録音して再生するサンプルを紹介します。コードの量が若干多くなるので、機能単位で説明していきます。

以下のコードは、マイク入力サウンドデータの録音開始と停止の部分です。

/** 録音データ */ var recBytes:ByteArray; /** 録画開始 */ function rec():void { recBytes = new ByteArray();//録音データの初期化 mic.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler); } /** マイクが音声を拾ったら、データを書き足す */ function sampleDataHandler(event:SampleDataEvent):void { recBytes.writeBytes(event.data); //録音 } /** 録画停止処理 */ function stop():void { mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler); recBytes.position = 0; //録音データのファイルポインタの位置を戻す }

マイクの入力検知(録音)の開始と終了は、SampleDataEvent.SAMPLE_DATA イベントを addEventListener() メソッドと removeEventListener() メソッドを利用して制御します。サウンドデータの蓄積は、ByteArray オブジェクトの writeBytes() メソッドで処理します。

以下のコードは、録音データの再生と停止の部分です。

/** 録音データを再生するためのサウンドオブジェクト */ var sound :Sound; /** 再生中のサウンドの停止や、サウンドの再生の終了を検知するためのオブジェクト */ var sc :SoundChannel; /** サウンド再生処理 */ protected function playSound():void { sound = new Sound(); sound.addEventListener(SampleDataEvent.SAMPLE_DATA, soundSampleDataHandler); sc = sound.play(); sc.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler); } /** 再生データの供給処理 ( 録音データを再生データに書き込む ) */ protected function soundSampleDataHandler(event:SampleDataEvent):void { var i :int; var bytes :ByteArray = event.data; var sample :Number; for (i = 0; i < 8192 && recBytes.bytesAvailable > 0; i++) { sample = recBytes.readFloat(); bytes.writeFloat(sample); bytes.writeFloat(sample); } } /** サウンド再生完了処理 */ protected function soundCompleteHandler(event:Event):void { sc.removeEventListener(event.type, arguments.callee); } /** 再生中のサウンドを停止する処理 */ protected function stopSound():void { sc.stop(); }

Sound オブジェクトの play() メソッドを呼び出すと、SoundChannel オブジェクトが新しく作成されて、アプリケーションが SampleDataEvent.SAMPLE_DATA イベントハンドラの呼び出しを開始します。

SoundChannel オブジェクトは、再生中のサウンドを停止したり、サウンド再生の終了を検知したりするためのオブジェクトです。SoundChannel オブジェクトの stop() メソッドでサウンドを停止することができ、Event.SOUND_COMPLETE("soundComplete") イベントハンドラを定義することでサウンドの停止(再生の終了)を検知することができます。

Sound クラスの SampleDataEvent.SAMPLE_DATA イベントハンドラは、Sound クラスが再生サウンドデータを要求してくるときに呼び出されるので、録音データを SampleDataEvent オブジェクトの data プロパティに書き込みます。このとき、data プロパティの writeFloat() メソッドを2回実行しています。なぜなら、Sound オブジェクトではステレオサウンドが使用されているのに対して、Microphone オブジェクトでキャプチャされるサウンドサンプルは先述の通りモノラルサウンドであるため、Sound オブジェクトに2回ずつ書き込む必要があるのです。

モバイルプロジェクト(AIR for Android)上での注意点

AIR for Android では、一部の環境で Microphone API を使用することができます。以下は、AIR for Android 上でマイクの使用を可能にする際のアプリケーション定義ファイルです。

<android> <manifestAdditions> <![CDATA[ <manifest android:installLocation="auto"> <!-- RECORD_AUDIO の定義 ( この定義がないとマイクが使用できない ) --> <uses-permission android:name="android.permission.RECORD_AUDIO"/> … </manifest> ]]> </manifestAdditions> </android>

おわりに

今までローカル環境のみで完結(実現)できなかったマイク入力の録音や再生などの処理が、Adobe AIR 2を利用することによって、数行のコードで実現できてしまうことが分かっていただけたと思います。これらのチュートリアル、サンプルコードを試すことによって、AIR アプリケーションがより身近に感じることができるでしょう。