まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

2016/03

JavaScript(HTML5) の機能だけで、PC に付属したマイクから音声を入力(つまり PC の前で喋った音声データを取り込む)してみました。なお、この機能を使うには UserMedia に対応したブラウザが必要です。以下のコードは Windows 版の FireFox で動作確認をしています。

サンプルのコードはこんな感じになります:
<html>
<head>
<title>HTML5 Audio</title>
<script type="text/javascript"> 
//. ブラウザによる差異を吸収
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
 
//. バッファサイズ等
var audioContext = new AudioContext();
var bufferSize = 4096;
var cnt = 0;
 
//. 音声処理
function onAudioProcess( e ){
  //. 取得した音声データ
  var input = e.inputBuffer.getChannelData(0);

//. ↑この input に音声データが入っているので、これをストリーミングなどで処理すればよい。
//. 以下は実際にデータが入っていることを確認するためのサンプル処理
//. 音声データの最大・最小値を求める var mx = 0, mn = 0; for( var i = 0; i < bufferSize; i ++ ){ if( mx < input[i] ){ mx = input[i]; } if( mn > input[i] ){ mn = input[i]; } } //. 一度に取得した音声データの最大・最小値を求める(特に意味は無いが、データが取得できている確認) cnt ++; console.log( "[" + cnt + "] min = " + mn + ", max = " + mx ); } //. 音声処理開始 function initialize(){ navigator.getUserMedia( { audio: true }, function( stream ){ //. 音声処理 var javascriptnode = audioContext.createScriptProcessor( bufferSize, 1, 1 ); var mediastreamsource = audioContext.createMediaStreamSource( stream ); window.dotnsf_hack_for_mozzila = mediastreamsource; //. https://support.mozilla.org/en-US/questions/984179 mediastreamsource.connect( javascriptnode ); javascriptnode.onaudioprocess = onAudioProcess; javascriptnode.connect( audioContext.destination ); },function( e ){ console.log( e ); } ); } </script> </head> <body onload="initialize()"> </body> </html>

余談ですが、上記コードの赤字部分は今回一番迷った所。どうも FireFox のバグらしく、取得したメディアストリームがいつの間にか消えて(音声入力処理が止まって)しまう、という現象に遭遇しました。そのバグを回避するため、無理やり取得した値をグローバル変数化して消えないようにしています。バグの詳細についてはこちら:
https://support.mozilla.org/en-US/questions/984179


この HTML をマイク入力を ON にした状態で対象ブラウザで開くと、「PC のマイクをこのアプリと共有しますか?」という確認メッセージが表示されます。ここで「共有」を選択してください:
2016030301

共有すると画面に FireFox がマイクを利用中であること(知らないうちに音声を取得しているわけではないこと)を知らせるマークが表示されます。このマークが出ている間は PC のマイクで拾った音声をこのウェブページで共有していることを表しています:
2016030302


ここで F12 キーを押すとデバッグ画面が表示され、コンソールタブを見ると取得した音声データ1まとまり(4Kbyte)単位での最大値と最小値(簡単にいうと音の大きさ)を表示し続ける、というアプリになっています。
2016030303


実際には取得した音声データを保存(録音)して再生できるようにするとか、ストリーミングで処理してテキスト化するとか、・・・ という使い方になると思いますが、その入力を HTML で行う方法の紹介でした。

IBM Bluemix はオープンソース PaaS である Cloud Foundry をベースに作られています。ということは Cloud  Foundry の API を Bluemix に対して使う、ということもできるわけです。

実際に試してみた様子を以下に記載します。なお、実行にあたっては Bluemix のアカウントと、実行環境として curl を利用します。以下の例では CentOS 6 上の curl を使っていますが、他のプラットフォームでもほぼ同様に使えるはずです。また以下の例では北米データセンターを対象に API を実行しますが、他のデータセンターを使う場合は、"ng" の部分を "eu-gb"(英国)か "au-syd"(オーストラリア)といった具合に書き換えて実行してください:


(1) アクセストークンの取得

具体的な API の利用の前に OAuth のアクセストークンを取得しておく必要があります(このアクセストークンを使って個別の API を実行します)。

以下の curl コマンドを実行します(青字部分がレスポンスです):
# curl -XPOST -H"Application/json" -u "cf:" --data "username=username@xxxx.com&password=P@ssw0rd&grant_type=password&scope=" https://login.ng.bluemix.net/UAALoginServerWAR/oauth/token

{
 "access_token":"(accessToken)", 
"token_type":"bearer",
"refresh_token":"*******", "expires_in":43199, "scope":"cloud_controller.read password.write cloud_controller.write openid", "jti":"********" }

"--data" に続く部分にログイン情報を含めています。username は Bluemix のログインIDです(上の例では username@xxxx.com を指定しています)。また password にパスワードを指定しています(上の例では P@ssw0rd を指定します)。それぞれ自分の情報に書き換えて実行してください。すると青字のような JSON テキストが返ってきます。この中の access_token の値(青太字の部分)がアクセストークンです。実際にはかなり長い文字列になっているはずですが、これを使って (2) 以降で API を実行します。


(2) API の実行

アクセストークンが取得できたら、その情報を使って Cloud Foundry API を実行します。Cloud Foundry API そのもののリファレンスはこちらを参照ください:
https://apidocs.cloudfoundry.org/231/

例えば「現在利用中のアプリケーションランタイムの一覧を取得」するには、この API を使います:
https://apidocs.cloudfoundry.org/231/apps/list_all_apps.html

具体的には以下の様な curl コマンドを実行します。ヘッダ情報(Authorization ヘッダ)に上記で取得したアクセストークンを指定しています:
# curl -H"Authorization: bearer (accessToken)" https://api.ng.bluemix.net/v2/apps

{
 "total_results": 15,
 "total_pages": 1,
   :
   :
 "resources":[
  {
   "metadata": {
    "guid": "(appGuid1)",
    "url": "/v2/apps/(appGuid1)",
    "created_at": "2015-03-09T02:49:49Z",
    "updated_at": "2016-02-20T06:23:39Z"
   },
    :
    :
  },
  {
   "meatadata": {
    "guid": "(appGuid2)",
     :
     :
  },
     :
     :
  }
] }

"resources" 内に配列形式でランタイムアプリケーションの情報が含まれているはずです。各ランタイムアプリケーションにはアプリケーション GUID と呼ばれる ID が割り振られており、その値は各ランタイムアプリケーション内の metadata.guid として確認できます。

では、今度はこのアプリケーション GUID を使って、このランタイムアプリケーションの環境変数情報を API で確認してみましょう。具体的にはこちらの API を利用します:
https://apidocs.cloudfoundry.org/231/apps/get_the_env_for_an_app.html
# curl -H"Authorization: bearer (accessToken)" https://api.ng.bluemix.net/v2/apps/(appGuid1)/env

{
 "staging_env_json": {
  "BLUEMIX_REGION": "ibm:yp:us-south"
 },
 "running_env_json": {
  "BLUEMIX_REGION": "ibm:yp:us-south"
 },
 "environment_json": {
 },
 "system_env_json": {
  "VCAP_SERVICES": {
   "relationship_extraction": [
    {
     "name": "Relationship Extraction-dc",
     "label": "relationship_extraction",
     "tags": [
      "ibm_beta",
      "watson",
      "ibm_created",
      "ibm_dedicated_public"
     ],
     "plan": "relationship_extraction_free_plan",
     "credentials": {
      "url": "https://gateway.watsonplatform.net/relationship-extraction-beta/api",
      "sids": [
       {
        "sid": "ie-es-news",
        "description": "information extraction from Spanish news"
       },
       {
        "sid": "ie-en-news",
        "description": "information extraction from English news"
       }
      ],
      "username": "(username)",
      "password": "(password)"
     }
    }
   ],
    :
    :
    :
   ]
  }
 },
 "application_env_json": {
   :
   :
 }
}

(appGuid1) に上記で確認したアプリケーション GUID を指定して実行します。すると上記のようなフォーマットで、このランタイムアプリケーションの環境変数情報が(VCAP_SERVICES もそれ以外も)まとめて取得できます。特に VCAP_SERVICES の credentials(上記の青太字部分)にはバインドしているサービスの接続情報が含まれており、その値を外部から API で確認できたことになります。


curl(HTTP) だけで Cloud Foundry API を Bluemix に対して使うことができる、ということが確認できました。これで複数のランタイムアプリケーションのステータスを確認する、といった管理用のアプリケーションも作れそうです。もちろん管理用途だけでなく、Bluemix のダッシュボードで実現しているようなアプリケーションを独自に作る、といったことも含めてできそうです。

 

このページのトップヘ