最近使用语音识别接口,发现百度云的api比较建议明了,由于大部分业务在阿里云上使用。为了避免多账户的结算问题,所以打算切换使用。同时阿里云的费用更低,在同阿里云环境下网络延时更低,体验更好。不过有一说一,百度云语音识别项目初期很好使用。
在官方网站下,发现某些使用不太友好,sdk也过于庞大。有些没有注释导致不好辨别。后发现不管是什么代码,本质上都是在做web下的http请求,无关乎代码类别。所以本人将从token获取到一句话语音识别全部采用非sdk实现。这样的话无须配置与打包,直接调用即可。
一、token获取
1.随机字符串
//作用:产生随机字符串,不长于32位
function createNoncestr($length=32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++)
{
$str .= substr($chars,mt_rand(0,strlen($chars)-1),1);
}
return $str;
}
2.发送curl请求
//发送curl请求
function sendCurl($url, $method = "GET", $postfields = null, $headers = array(),$upfile = false)
{
$ci = curl_init();
/* Curl settings */
curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ci, CURLOPT_TIMEOUT, 30);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false); //不验证证书
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, false); //不验证证书
switch ($method)
{
case 'POST':
curl_setopt($ci, CURLOPT_POST, true);
if (!empty($postfields))
{
if($upfile)
{
if(class_exists('\CURLFile'))
{
curl_setopt($ci, CURLOPT_SAFE_UPLOAD, true);
}
else
{
if (defined('CURLOPT_SAFE_UPLOAD'))
{
curl_setopt($ci, CURLOPT_SAFE_UPLOAD, false);
}
}
foreach($postfields as $k=>$v)
{
if (class_exists('\CURLFile'))
{
$postfields[$k] = new \CURLFile(realpath($v));
}
else
{
$postfields[$k] = '@' . realpath($v);
}
}
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}
else
{
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}
}
break;
}
curl_setopt($ci, CURLOPT_URL, $url);
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ci, CURLINFO_HEADER_OUT, true);
$response = curl_exec($ci);
curl_close($ci);
$response = json_decode($response,true);
return $response;
}
3.生成uuid
//生成唯一标志-uuid
function createUuid()
{
$chars = md5(uniqid(mt_rand(), true));
$uuid = substr ( $chars, 0, 8 ) . '-'
. substr ( $chars, 8, 4 ) . '-'
. substr ( $chars, 12, 4 ) . '-'
. substr ( $chars, 16, 4 ) . '-'
. substr ( $chars, 20, 12 );
return $uuid ;
}
4.获取token
//获取阿里云服务需要的token
function getAliyunToken($AccessKeyId = 'your akID', $AccessKeySecret = 'your akSecret')
{
$re = array('code'=> -1,'expire_time' => 0,'token' => '');
//请求固定参数
$UtcTime = time() - (60*60*8);
$Action = 'CreateToken';
$Version = '2019-02-28';
$Format = 'JSON';
$RegionId = 'cn-shanghai';
$Timestamp = urlencode(date("Y-m-d",$UtcTime)."T".date("H:i:s",$UtcTime)."Z");
$SignatureMethod = 'HMAC-SHA1';
$SignatureVersion = '1.0';
$SignatureNonce = createUuid();
$Signature = '';
//get请求的参数拼接
$para = '';
$para .= "AccessKeyId={$AccessKeyId}&Action={$Action}&Format={$Format}&RegionId={$RegionId}";
$para .= "&SignatureMethod={$SignatureMethod}&SignatureNonce={$SignatureNonce}";
$para .= "&SignatureVersion={$SignatureVersion}&Timestamp={$Timestamp}&Version={$Version}";
//签名参数处理
$signature = 'GET&'.urlencode('/').'&'.urlencode($para);
$signature = urlencode(base64_encode(hash_hmac("sha1", $signature, $AccessKeySecret.'&', true)));
$signature = 'Signature='.$signature."&".$para;
//发送请求,携带处理后的签名参数
$url = 'http://nls-meta.cn-shanghai.aliyuncs.com/?'.$signature;
$result = sendCurl($url);
if(array_key_exists('Token', $result))
{
$re = array(
'code' => 0,
'expire_time' => $result['Token']['ExpireTime'],
'token' => $result['Token']['Id'],
);
}
return $re;
}
具体使用:可以将token放入缓存,这样减少请求次数。
$AccessKeyId = 'xxxxx';
$AccessKeySecret = 'xxxxx';
$result = getAliyunToken($AccessKeyId,$AccessKeySecret);
echo json_encode($result);
二.开始语音识别
这里额外说一句,大部分语音识别都有格式转化、采样率要求。如果有三方接口提供mp3直接转换的话,请优先使用避免麻烦。
本人使用的ffmpeg转化mp3格式文件。具体方法就请各位自行搜索了。
不过我可以展示一下自己的执行命令
//ffmpeg的执行命令
exec("/monchickey/ffmpeg/bin/ffmpeg -y -i $audioPath -acodec pcm_s16le -f s16le -ac 1 -ar 16000 $pcmPath",$error);
1.具体请求识别
//具体的识别过程
function process($token, $request, $audioFile)
{
$re = array('code' => -1, 'msg' => '', 'content' => '');
/**
* 读取音频文件
*/
$audioContent = file_get_contents($audioFile);
if ($audioContent == FALSE)
{
$re = array('code' => -1, 'msg' => '文件不存在', 'content' => '');
return $re;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);
/**
* 设置HTTP请求行
*/
curl_setopt($curl, CURLOPT_URL, $request);
curl_setopt($curl, CURLOPT_POST,TRUE);
/**
* 设置HTTP请求头部
*/
$contentType = "application/octet-stream";
$contentLength = strlen($audioContent);
$headers = array(
"X-NLS-Token:" . $token,
"Content-type:" . $contentType,
"Content-Length:" . strval($contentLength)
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
/**
* 设置HTTP请求数据
*/
curl_setopt($curl, CURLOPT_POSTFIELDS, $audioContent);
curl_setopt($curl, CURLOPT_NOBODY, FALSE);
/**
* 发送HTTP请求
*/
$returnData = curl_exec($curl);
curl_close($curl);
if ($returnData == FALSE)
{
$re = array('code' => -1, 'msg' => 'curl执行失败', 'content' => '');
return $re;
}
$resultArr = json_decode($returnData, true);
$status = $resultArr["status"];
if ($status == 20000000)
{
$re = array('code' => 0, 'msg' => '识别成功', 'content' => $resultArr["result"]);
}
else
{
$re = array('code' => -1, 'msg' => '识别失败', 'content' => '');
}
return $re;
}
2.封装识别请求
//获取语音识别内容,$appkey 是语音项目的key
function getContent($appkey = 'your key',$token = '', $audioFile = '')
{
$url = "http://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/asr";
$format = "pcm";
$sampleRate = 16000;
$enablePunctuationPrediction = TRUE;
$enableInverseTextNormalization = TRUE;
$enableVoiceDetection = FALSE;
/**
* 设置RESTful 请求参数
*/
$request = $url;
$request = $request . "?appkey=" . $appkey;
$request = $request . "&format=" . $format;
$request = $request . "&sample_rate=" . strval($sampleRate);
if ($enablePunctuationPrediction)
{
$request = $request . "&enable_punctuation_prediction=" . "true";
}
if ($enableInverseTextNormalization)
{
$request = $request . "&enable_inverse_text_normalization=" . "true";
}
if ($enableVoiceDetection)
{
$request = $request . "&enable_voice_detection=" . "true";
}
$result = process($token, $request, $audioFile);
return $result;
}
3.调用
$appkey = 'xxx';
$token = 'xxxxxxxx';
$audioFile = '16k.pcm';
$re = getContent($appkey,$token,$audioFile);
echo json_encode($re);