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 に転記する。

0021:     //Google API KEY
0022:     //https://developers.google.com/maps/web/
0023:     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形式である。

解説:同期音声認識

0077: /**
0078:  * Google Cloud Speech APIを用いて音声データからテキストを起こす
0079:  * @param string $file  音声ファイル名
0080:  * @return stringテキスト/FALSE:失敗
0081: */
0082: function speech_syncrecognize($file) {
0083:     $url = 'https://speech.googleapis.com/v1beta1/speech:syncrecognize?key=' . $this->GOOGLE_API_KEY;
0084:     $this->webapi = $url;
0085:     $n = 1;
0086: 
0087:     //音声データファイル読み込み
0088:     $data = @file_get_contents($file);
0089:     if ($data == FALSE) {
0090:         $this->error = TRUE;
0091:         $this->errmsg = $file . ' が読み込めない';
0092:         return FALSE;
0093:     }
0094:     $contents = base64_encode($data);
0095: 
0096: $json =<<< EOD
0097: {
0098:     "config": {
0099:         "encoding" : "LINEAR16",
0100:         "sample_rate" : 44100,
0101:         "language_code" : "ja-JP"
0102:     },
0103:     "audio": {
0104:         "content" : "{$contents}"
0105:     }
0106: }
0107: 
0108: EOD;
0109:     $header = array('Content-Type: application/json');
0110: 
0111:     //cURLを使ってリクエスト
0112:     $curl = curl_init() ;
0113:     curl_setopt($curl, CURLOPT_URL, $url);
0114:     curl_setopt($curl, CURLOPT_POST, TRUE); 
0115:     curl_setopt($curlCURLOPT_SSL_VERIFYPEERFALSE);       //証明書は無視
0116:     curl_setopt($curlCURLOPT_SSL_VERIFYHOSTFALSE);
0117:     curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
0118:     curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
0119:     curl_setopt($curlCURLOPT_AUTOREFERERTRUE);
0120:     curl_setopt($curlCURLOPT_RETURNTRANSFERTRUE);        //結果を文字列で
0121:     curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
0122:     curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
0123:     curl_setopt($curl, CURLOPT_TIMEOUT, 30);
0124: 
0125:     $res = curl_exec($curl);
0126:     curl_close($curl);
0127: 
0128:     if ($res == FALSE || $res == '') {
0129:         $this->error = TRUE;
0130:         $this->errmsg = $file . ' の音声解析に失敗';
0131:         return FALSE;
0132:     }
0133: 
0134:     //結果処理
0135:     $this->webapi = $url;
0136:     $this->responses = json_decode($res);
0137: 
0138:     if (isset($this->responses->error)) {
0139:         $this->error = TRUE;
0140:         $this->errmsg = $this->responses->error->status;
0141:         return FALSE;
0142:     } else if (! isset($this->responses->results[0]->alternatives[0]->transcript)) {
0143:         $this->error = TRUE;
0144:         $this->errmsg = $file . ' の音声解析に失敗';
0145:         return FALSE;
0146:     }
0147: 
0148:     return $this->responses->results[0]->alternatives[0]->transcript;
0149: }

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

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

参考サイト

(この項おわり)
header