googleの日本語音声認識を自由に呼び出して使う方法

google chrome とかにある、google音声認識を自由にプログラムから呼び出す方法を調べたので書いてみる。


Fiddler2 でごにごにしてぐるぐるした結果、こーなった。
音声データは、 16000hz 1channel の flac形式で送信している。

で、その結果を元に調べてみると、外人で何人か解析している人がいた。
だけど、日本語のやつがなかったんで作ってみた。
基本的には、lang=ja と lang=US の違いぐらいだけど。


まず、手元に 16000hz 1channel の test.flac を作る。
ffmpeg使うと簡単に作れる。

ffmpeg -i test.wma -vn -ac 1 -ar 16000 -acodec flac test.flac


あとは、HTTPS通信してデータを取得する。
chrome がやっているとおりに投げてみた。
なので、サーバからの結果は gz圧縮される。
PHPのgz系命令で適当に解凍すれば良い。

<?php
//POSTデータ
//こんな風にして作る!
//ffmpeg -i test.wma -vn -ac 1 -ar 16000 -acodec flac test.flac
$testfileflac = "test.flac";
$filesize = filesize($testfileflac);
$flacFile = fopen($testfileflac,"rb");
if ($flacFile === FALSE)
{
	echo "テスト音声データ {$testfileflac} がねーよ";
	fclose($flacFile);
	exit(1);
}


//SSL通信を行う
//  MEMO:ssl有効にしていないPHPだと動かないよ!
$sockFile = fsockopen('ssl://www.google.com', 443);
if ($sockFile === FALSE)
{
	echo "データを送信できませんでした";
	fclose($flacFile);
	exit(1);
}
//なるべく chromeっぽい通信をするw
fputs($sockFile,"POST /speech-api/v1/recognize?xjerr=1&client=chromium&lang=ja&maxresults=6&pfilter=2 HTTP/1.1\r\n");
fputs($sockFile,"HOST www.google.com\r\n");

fputs($sockFile,"Content-Type: audio/x-flac; rate=16000\r\n");
fputs($sockFile,"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11\r\n");
fputs($sockFile,"Accept-Encoding: gzip,deflate,sdch\r\n");
fputs($sockFile,"Accept-Language: ja,en-US;q=0.8,en;q=0.6\r\n");
fputs($sockFile,"Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.3\r\n");
fputs($sockFile,"Connection: close\r\n");
fputs($sockFile,"Content-Length: $filesize\r\n");
fputs($sockFile,"\r\n");

fwrite( $sockFile , fread($flacFile,$filesize) , $filesize);
fclose($flacFile);

//データ受信 (body は gz圧縮されている)
$respons = "";
while(!feof($sockFile))
{
    $respons .= fgets($sockFile, 4096);
}
fclose($sockFile);

//HTTP ヘッダーとbody の分離
$respons = substr($respons, strpos($respons,"\r\n\r\n") + 4);

//bodyはgz圧縮されているので解凍する 
$unzipRespons = gzinflate(substr($respons,10,-8)); //gzinflate

//結果の表示
var_dump($unzipRespons);


結果

string(737) "{"status":0,"id":"7aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-1","hypotheses":[{"utterance":"むかしむかし あるところにおじいさんとおばあさんが住んでいました","confidence":0.08036588},{"utterance":"むかしむかし あるところにおじいさんとおばあさんが住んでました"},{"utterance":"昔むかし あるところにおじいさんとおばあさんが住んでいました"},{"utterance":"昔むか し あるところにおじいさんとおばあさんが住んでました"},{"utterance":"むかしむかしあるところにおじいさんとおばあさんが住んでいました"},{"utterance":"むかしむかしあるところにおじいさ んとおばあさんが住んでました"}]}


だってお。


できるからといって、なんでもgoogleに、投げまくって鯖をいじめるプログラムは良くないと思います。
行儀の良いプログラムを書きましょう。