阿里云的语音识别 - php环境下RESTful API执行,无须任何阿里云SDK支持。

最近使用语音识别接口,发现百度云的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);

 

你可能感兴趣的:(php,后端)