PHP实现讯飞语音转写demo

讯飞语音转写demo,模仿讯飞平台官网python代码

    • 经历的坑
    • 代码
    • 运行结果如下图

前前后后改了好久,做个记录,以及经历的一些坑。上传切片功能没有,也就是说我这里的切片为1,里面很多bug,异常处理都没有,后面再修改。

经历的坑

1.预处理处的签名处理,因为和python有些函数不一样,所有琢磨了好久。我的php版本是5.5。

python中的写法如下:

ts = str(int(time.time()))
m2 = hashlib.md5()
m2.update((appid + ts).encode('utf-8'))
md5 = m2.hexdigest()
md5 = bytes(md5, encoding='utf-8')
signa = hmac.new(secret_key.encode('utf-8'), md5, hashlib.sha1).digest()
signa = base64.b64encode(signa)
signa = str(signa, 'utf-8')

在php中的写法:其中hash_hmac(),借鉴了一篇博客(https://blog.csdn.net/Ligongxiang123/article/details/76590196),说了两者(php和python)怎么转换。

$ts=time();
$md5 = md5($appid.$ts);
$signa = hash_hmac('sha1',$md5,$secret_key,true);
$signa=base64_encode($signa);

其中在字节数组地方卡住了,查了一下,原因是php5.5中的 string 本来就是“字节串”。为了测试每一步的结果,调试的时候是获取的时间戳固定,两边逐步运行对比出来的。我觉得这可能是讯飞的一个小bug,如果我将传入的时间戳固定,签名也固定,是不是就可以直接过滤掉这一段了!
2.在upload时卡了好几个小时,因为老是报26600(转写业务通用错误)的错误,我当时读取文件用的代码是

$content = urlencode(base64_encode(file_get_contents($upload_file_path)));

但是怎么都不对,改编码也没改对!最后在一篇博客(https://blog.csdn.net/wb_json/article/details/95050959)上看到了解决办法,这个老哥实现了语音转写也提供了代码,但是需要在yii上运行。下面是我复制过来的。

 $mime = (new \finfo(FILEINFO_MIME_TYPE))->file($result->file);
 $curlFile = curl_file_create(
            $file,
            $mime,
            pathinfo(
                $file,
                PATHINFO_BASENAME
            )
);

我没有finfo这个类,最后百度百度,需要安装php_fileinfo扩展,然后用finfo_open().,最终解决问题。

$finfo   = finfo_open(FILEINFO_MIME_TYPE);
        $mime = finfo_file($finfo, $upload_file_path);
        finfo_close($finfo);
        $curlFile = curl_file_create(
            $upload_file_path,
            $mime,
            pathinfo(
                $upload_file_path,
                PATHINFO_BASENAME
            )
        );

剩下的就剩json数据格式的问题了,这个百度百度就有了。可以参考(https://www.cnblogs.com/totian/p/7498742.html),下面代码记得改完app_id,secret_key,file_path就可以用了。嗯,应该可以的,我试过。哈哈哈!

代码

<?php
header("Content-Type: text/html; charset=utf-8");
class Sliceidgenerator{
    private $__ch;
    public function __construct() {
            $this->__ch = 'aaaaaaaaa`';
        }
    public function getNextSliceId(){
        $ch = $this->__ch;
        $j = strlen($ch) - 1;
        while($j >= 0){
            $cj = $ch[$j];
            if ($cj != 'z'){
                $ch = substr($ch,0,$j) . chr((ord($cj) + 1)) . substr($ch,$j + 1);
                break;
            }   
            else{
                $ch = substr($ch,0,$j) . 'a' . substr($ch,$j + 1);
                $j = $j - 1;
            }
        }      
        $this->__ch = $ch;
        return $ch;
    }
        
}

class Fx_Api{
	private $lfasr_host = 'http://raasr.xfyun.cn/api';

    # 请求的接口名
    private $api_prepare = '/prepare';
    private $api_upload = '/upload';
    private $api_merge = '/merge';
    private $api_get_progress = '/getProgress';
    private $api_get_result = '/getResult';
    # 文件分片大小10M
    private $file_piece_sice = 10485760;
    # 转写类型
    private $lfasr_type = 0;
    # 是否开启分词
    private $has_participle = 'false';
    private $has_seperate = 'true';
    # 多候选词个数
    private $max_alternatives = 0;
    # 子用户标识
    private $suid = '';
    private $appid;
    private $secret_key;
    private $upload_file_path;
    private $obj;
    private $data;
    private $sig;
    public function __construct($file_path,$appid,$secret_key,$sig) {
        $this->upload_file_path = $file_path;
        $this->appid = $appid;
        $this->secret_key = $secret_key;
        $this->sig = $sig;
    }
 
 	#主要运行函数
    public function run() {
        if($this->upload_file_path!=''){
        	#预处理
            $pre_result = json_decode($this->prepare_request(),true);
            $taskid = $pre_result['data'];
            #上传文件
            $this->upload_request($taskid,$this->upload_file_path);
            $this->merge_request($taskid);

            while (true) {
                $progress = $this->get_progress_request($taskid);
                $progress_dic = json_decode($progress);
                if ($progress_dic->err_no != 0 && $progress_dic->err_no != 26605){
                    return;
                }else{
                    $data = $progress_dic->data;
                    $task_status = json_decode($data);
                    if ($task_status->status == 9){
                        echo('The task ' . $taskid . ' is in processing, task status: ' . $task_status->desc);
                        echo "
"
; break; } echo('The task ' . $taskid . ' is in processing, task status: ' . $task_status->desc); echo "
"
; sleep(0.5); } } $data_all=$this->get_result_request($taskid=$taskid); $data_all = json_decode($data_all)->data; $data_all=json_decode($data_all); $message=''; for ($i=0;$i<count($data_all);$i++){ $message.=$data_all[$i]->onebest; } $this->data=$message; } } public function get_data() { return $this->data; } public function gene_params($apiname,$taskid="",$slice_id=""){ $appid = $this->appid; $secret_key = $this->secret_key; $upload_file_path = $this->upload_file_path; $ts=time(); $md5 = md5($appid.$ts); $signa = hash_hmac('sha1',$md5,$secret_key,true); $signa=base64_encode($signa); $file_len = filesize($this->upload_file_path); $file_name = basename($this->upload_file_path); if($apiname== $this->api_prepare){ $slice_num = 1; $param_dict['app_id'] = $appid; $param_dict['signa'] = $signa; $param_dict['ts'] = $ts; $param_dict['file_len'] = (string)($file_len); $param_dict['file_name'] = $file_name; $param_dict['slice_num'] = (string)($slice_num); }elseif($apiname== $this->api_upload){ $param_dict['app_id'] = $appid; $param_dict['signa'] = $signa; $param_dict['ts'] = $ts; $param_dict['task_id'] = $taskid; $param_dict['slice_id'] = $slice_id; }elseif($apiname == $this->api_merge){ $param_dict['app_id'] = $appid; $param_dict['signa'] = $signa; $param_dict['ts'] = $ts; $param_dict['task_id'] = $taskid; $param_dict['file_name'] = $file_name; }elseif($apiname == $this->api_get_progress || $apiname == $this->api_get_result){ $param_dict['app_id'] = $appid; $param_dict['signa'] = $signa; $param_dict['ts'] = $ts; $param_dict['task_id'] = $taskid; } return $param_dict; } public function gene_request($apiname, $data, $files='', $headers=''){ if($files!=''){ $data['content'] =$files['content']; } $jsonStr =$data; if($apiname==$this->api_prepare||$apiname==$this->api_merge||$apiname==$this->api_get_progress||$apiname==$this->api_get_result){ $header= array( "Content-Type"=>"application/x-www-form-urlencoded;charset=UTF-8", ); } if($apiname==$this->api_upload){ $header = array( "Content-Type"=>"multipart/form-data;", ); } $url = $this->lfasr_host . $apiname; $rt=$this->http_post_json($url, $jsonStr, $header); $result = json_decode($rt[1],true); if ($result["ok"] == 0){ echo("success:".$apiname); echo "
"
; return $rt[1]; }else{ return $rt[1]; } } # 预处理gene_request public function prepare_request(){ return $this->gene_request($apiname=$this->api_prepare, $data=$this->gene_params($this->api_prepare)); } #上传 public function upload_request($taskid, $upload_file_path){ $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $upload_file_path); finfo_close($finfo); $curlFile = curl_file_create( $upload_file_path, $mime, pathinfo( $upload_file_path, PATHINFO_BASENAME ) ); $files["filename"] = $this->gene_params($this->api_upload)["slice_id"]; $files["content"] = $curlFile; $response = $this->gene_request($this->api_upload, $data=$this->gene_params($this->api_upload, $taskid=$taskid,$slice_id=$this->sig->getNextSliceId()),$files=$files); return $response; } public function merge_request($taskid){ return $this->gene_request($this->api_merge, $data=$this->gene_params($this->api_merge, $taskid=$taskid)); } # 获取进度 public function get_progress_request($taskid){ return $this->gene_request($this->api_get_progress, $data=$this->gene_params($this->api_get_progress, $taskid=$taskid)); } # 获取结果 public function get_result_request($taskid){ $result=$this->gene_request($this->api_get_result, $data=$this->gene_params($this->api_get_result, $taskid=$taskid)); return $result; } #请求 public function http_post_json($url, $jsonStr,$header) { $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return array($httpCode, $response); } } $sig = new Sliceidgenerator(); $app_id = 'xxxx'; $secret_key = 'xxxxx'; $file_path = 'D:\WWW\tp5\public\audio\10s.wav'; $api = new Fx_Api($file_path,$app_id,$secret_key,$sig); $api->run(); print_r("转写结果:"); print_r($api->get_data());

运行结果如下图

PHP实现讯飞语音转写demo_第1张图片

你可能感兴趣的:(php接口)