微信公眾平台開發模式 微信 語音識別 公眾平台 消息接口 語音識別
微信公眾平台開發 語音識別
作者:方倍工作室
地址:http://www.cnblogs.com/txw1958/archive/2013/02/06/weixin-if40-voice-recognition.html
一、申請微信認證
微信認證后將自動開通高級接口,獲得高級接口中所有接口權限,無需二次申請。
高級接口含有獲取用戶基本信息、客服接口、語音識別等高級接口權限。
二、獲取語音識別結果
開通語音識別功能,且該功能設置處於開啟狀態的公眾帳號,用戶每次發送語音給公眾號時,微信會在推送的語音消息XML數據包中,增加一個Recongnition字段。
開啟語音識別后的語音XML數據包如下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[voice]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <Format><![CDATA[Format]]></Format> <Recognition><![CDATA[深圳天氣怎么樣]]></Recognition> <MsgId>1234567890123456</MsgId> </xml>
參數說明:
參數 描述
ToUserName 開發者微信號
FromUserName 發送方帳號(一個OpenID)
CreateTime 消息創建時間 (整型)
MsgType 語音為voice
MediaID 語音消息媒體id,可以調用多媒體文件下載接口拉取該媒體
Format 語音格式:amr
Recognition 語音識別結果,UTF8編碼
MsgID 消息id,64位整型
三、使用中文分詞提取關鍵特征
中文分詞 (Chinese Word Segmentation) 指的是將一個漢字序列切分成一個一個單獨的詞。分詞就是將連續的字序列按照一定的規范重新組合成詞序列的過程。我們知道,在英文的行文中,單詞之間是以空格作為自然分界符的,而中文只是字、句和段能通過明顯的分界符來簡單划界,唯獨詞沒有一個形式上的分界符,雖然英文也同樣存在短語的划分問題,不過在詞這一層上,中文比之英文要復雜的多、困難的多。通過分詞可以提取其中關鍵詞語進行搜索。
打個比方:
例如,識別結果為”深圳天氣怎么樣”,可分詞為”深圳”,”怎么樣”,三個詞。我們提取出“天氣”作為名詞,“深圳”作為地點名詞,
以下是SAE上的分詞代碼示例:
<?php $str = "深圳天氣怎么樣"; $seg = new SaeSegment(); $ret = $seg->segment($str, 1); print_r($ret); //輸出 if ($ret === false) var_dump($seg->errno(), $seg->errmsg()); ?>
識別結果如下:
Array ( [0] => Array ( [word] => 深圳 [word_tag] => 102 [index] => 0 ) [1] => Array ( [word] => 天氣 [word_tag] => 95 [index] => 1 ) [2] => Array ( [word] => 怎么樣 [word_tag] => 40 [index] => 2 ) )
//詞性對應關系 POSTAG_ID_N = 95 (line 322) 名詞 POSTAG_ID_NS_Z = 102 (line 357) 地名(名處詞專指:“中國”) POSTAG_ID_D = 40 (line 207) 副詞
三、程序實現
判斷是否開啟語音識別
private function receiveVoice($object) { if (isset($object->Recognition) && !empty($object->Recognition)){ $contentStr = "你發送的是語音,內容為:".$object->Recognition; }else{ $contentStr = "未開啟語音識別功能或者識別內容為空"; } if (is_array($contentStr)){ $resultStr = $this->transmitNews($object, $contentStr); }else{ $resultStr = $this->transmitText($object, $contentStr); } return $resultStr; }
效果如下:
調用SAE分詞
var_dump(segment("明天長沙天氣怎么樣")); function segment($str) { $seg = new SaeSegment(); $ret = $seg->segment($str, 1); if ($ret === false){ return; } $category = ""; $keyword = ""; foreach ($ret as $key => $value) { if ($value["word_tag"] == 95){ $category = $value["word"]; } if ($value["word_tag"] == 102){ $keyword = $value["word"]; } } if (!empty($category) && !empty($keyword)){ return array('category'=>$category, 'keyword'=>$keyword); }else{ return; } }
返回結果如下:
array(2) { ["category"]=>string(6) "天氣" ["keyword"]=>string(6) "長沙" }
這樣就獲知曉了用戶要查詢的功能是天氣,城市名稱是長沙。
功能查詢
根據獲得的功能類別及關鍵字,我們可以查詢相應的城市天氣預報。
include("segment.php"); $result = sinasegment($content); if (is_array($result)){ switch ($result['category']) { case "天氣": $url = "http://api100.duapp.com/weather/?appkey=trialuser&city=".urlencode($result['keyword']); $output = file_get_contents($url); $contentStr = json_decode($output, true); break; case "空氣": $url = "http://api100.duapp.com/airquality/?appkey=trialuser&city=".urlencode($result['keyword']); $output = file_get_contents($url); $contentStr = json_decode($output, true); break; default: $contentStr = "還不支持這一功能:".$result['category']; break; } }else{ $contentStr = "不能理解你的內容:".$content; }
四、效果演示