PHPでクラウド音声認識

(1/1)
今回は、PHPで「Google Cloud Speech API」を利用し、音声ファイルを自動解析し、テキストを表示するプログラムをつくる。

サンプル・プログラム:実行例

PHPで音声認識
音声ファイルを選択し、解析ボタンをクリックすると、最下段のテキストボックスにメッセージをし、送信ボタンを押すると、Google Cloud Speech API に音声データを送信し、解析して返ってくるテキストを表示する。

実行例では、アニメ『機動戦士ガンダムUC』最終回、ミネバ・ザビの長い演説から音声だけ切り出し、WAVファイルに変換したものを入力してみた。一部誤認識はあるものの、固有名詞や難読語も、ほぼ間違いなく変換している。大したものである。
声質の違いや抑揚の違い、話すスピードが違っても、認識可能である。ただし、同じファイル中に異なる人物の音声がある場合は、最初の人物の音声のみを変換するようだ。

サンプル・プログラム

準備

まず、Google Cloud Speech API を利用できるよう準備を整える。

手持ちのGoogleアカウントを使って、Google APIs コンソールにログインする。
Google APIs コンソール
ライブラリから、Speech API を選択する。
Google APIs コンソール
有効にする を選択する。
このAPIは、月間60分までは無料だが、それを超えると15秒ごとに処理料金が加算される。このため、クレジットカードなどで有料課金可能なアカウントを登録しておく必要がある。
Google APIs コンソール
有料課金可能なアカウントを作るには、Google Cloud Platform にアクセスし、お支払いを選択。クレジットカード情報を入力する。
Google APIs コンソール
次に、Speech API を利用するためのAPIキーを用意する。
画面「認証情報」で「認証情報を作成」すると、あらたなAPIキーが生成される。このキーを、クラス "pahooGoogleCloud.php" の変数 $GOOGLE_API_KEY に転記する。

  21:     //Google API KEY
  22:     //https://developers.google.com/maps/web/
  23:     var $GOOGLE_API_KEY = '**************************';

これで、Google Cloud Speech API の利用準備が整った。

Google Cloud Speech API

Google Cloud Speech API には、同期音声認識、非同期音声認識、ストリーミング音声認識の3種類のサービスが用意されているが、今回は、あらかじめ用意した音声ファイルを認識するということで、「同期音声認識」を利用する。

 

同期音声認 (POST)
URL
https://speech.googleapis.com/v1beta1/speech:syncrecognize?key=[APIキー]
入力データ(json) config encoding 音声エンコード:LINEAR16 | FLAC など sampleRate サンプリングレート:8000~48000Hz languageCode 言語:ja-JP など audio content BASE64エンコード
音声エンコードだが、WAV形式ファイル(量子化16ビット)の場合は LINEAR16 を指定する。サンプリングレートは8000~48000Hzの間で自由に選べるが、チャンネル数は1(モノラル)固定である。

音声データは、バイナリファイルを BASE64 エンコードして渡す必要がある。
ただし、Google Cloud Storage に保存された音声ファイルを認識することが可能で、その場合は
"audio": {
  "uri": "gs://YOUR_BUCKET_NAME/YOUR_FILE_NAME"
}
のように指定する。
出力データ(json) results alternatives transcript 認識テキスト confidence 信頼度
出力データもJSON形式である。

解説:同期音声認識

  77: /**
  78:  * Google Cloud Speech API を用いて音声データからテキストを起こす
  79:  * @param   string $file  音声ファイル名
  80:  * @return  string テキスト/FALSE:失敗
  81: */
  82: function speech_syncrecognize($file) {
  83:     $url = 'https://speech.googleapis.com/v1beta1/speech:syncrecognize?key=' . $this->GOOGLE_API_KEY;
  84:     $this->webapi = $url;
  85:     $n = 1;
  86: 
  87:     //音声データファイル読み込み
  88:     $data = @file_get_contents($file);
  89:     if ($data == FALSE) {
  90:         $this->error = TRUE;
  91:         $this->errmsg = $file . ' が読み込めない';
  92:         return FALSE;
  93:     }
  94:     $contents = base64_encode($data);
  95: 
  96:     $json =<<< EOD
  97: {
  98:     "config": {
  99:         "encoding" : "LINEAR16",
 100:         "sample_rate" : 44100,
 101:         "language_code" : "ja-JP"
 102:     },
 103:     "audio": {
 104:         "content" : "{$contents}"
 105:     }
 106: }
 107: 
 108: EOD;
 109:     $header = array('Content-Type: application/json');
 110: 
 111:     //cURLを使ってリクエスト
 112:     $curl = curl_init() ;
 113:     curl_setopt($curl, CURLOPT_URL, $url);
 114:     curl_setopt($curl, CURLOPT_POST, TRUE); 
 115:     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);      //証明書は無視
 116:     curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
 117:     curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
 118:     curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
 119:     curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE);
 120:     curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);       //結果を文字列で
 121:     curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
 122:     curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
 123:     curl_setopt($curl, CURLOPT_TIMEOUT, 30);
 124: 
 125:     $res = curl_exec($curl);
 126:     curl_close($curl);
 127: 
 128:     if ($res == FALSE || $res == '') {
 129:         $this->error = TRUE;
 130:         $this->errmsg = $file . ' の音声解析に失敗';
 131:         return FALSE;
 132:     }
 133: 
 134:     //結果処理
 135:     $this->webapi = $url;
 136:     $this->responses = json_decode($res);
 137: 
 138:     if (isset($this->responses->error)) {
 139:         $this->error = TRUE;
 140:         $this->errmsg = $this->responses->error->status;
 141:         return FALSE;
 142:     } else if (! isset($this->responses->results[0]->alternatives[0]->transcript)) {
 143:         $this->error = TRUE;
 144:         $this->errmsg = $file . ' の音声解析に失敗';
 145:         return FALSE;
 146:     }
 147: 
 148:     return $this->responses->results[0]->alternatives[0]->transcript;
 149: }

仕様通りに同期音声認識APIを呼び出すのが、メソッド speech_syncrecognize である。

WebAPIにJSON形式の入力データを渡すのに、cURL関数を利用した。
CURLOPT_HTTPHEADER として "Content-Type: application/json" を指定しておくと、CURLOPT_POSTFIELDS にJSON形式テキストを入力するだけで処理してくれるので便利だ。

参考サイト

(この項おわり)
header