yangzailu

导航

科大讯飞极速音频转写demo

科大讯飞

<?php

namespace app\admin\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use GuzzleHttp\Client;

class SoundParse extends Command
{
    // 替换为你的实际 API Key 和 Secret Key
    protected $appid = "205f";
    protected $apiKey = "0e867***c8ad3";
    protected $apiSecret = "ZWM5NW***ZTM1";

    // 上传和查询地址
    protected $uploadHost = "https://upload-ost-api.xfyun.cn/file/upload";
    protected $createTaskHost = "https://ost-api.xfyun.cn/v2/ost/pro_create";
    protected $queryHost = "https://ost-api.xfyun.cn/v2/ost/query";

    /**
     * @Description: 配置命令
     * @Author: AaronYang
     * @Date: 2025/7/25 09:09
     * @return void
     */
    protected function configure()
    {
        $this->setName('SoundParse')
            ->setDescription('语音转写测试');
    }

    /**
     * @Description: 执行命令
     * @Author: AaronYang
     * @Date: 2025/7/25 09:09
     * @param Input $input
     * @param Output $output
     * @return void
     */
    protected function execute(Input $input, Output $output)
    {
        try {
            $output->info("开始执行任务...");
            $upload_file_path = ROOT_PATH . 'public/uploads/789.mp3';
            // 上传文件
//            $upload_result = $this->upload($this->uploadHost, $this->apiKey, $this->apiSecret, $upload_file_path);
//            var_dump($upload_result);
//            $output->info("上传响应: " . json_encode($upload_result, JSON_PRETTY_PRINT));
            //创建任务
//            $task_request_id = '929020202111102';
//            //首次录音上传返回的那个地址
//            $audio_url = 'https://xfyun-seve-dx/IBAUEX+ollA5b/18xtFQFR+TYlU1dp7UqPcyprLi+OlY2lR8fx8WmRjLfrOFOEiYCrjkdD+jCIcKM45Pkj2tdp6hl5cRDuSGx8bHfHOeGpA25GGtd9YKhOAB6bgHF3WglE3dCXCagrkS2wI5OFFFlpnu4AyBjG8BXS1lL5WSU87siTuWS5XJd0eNHaV1ypHOiLMIFiKBmxMYdWwol2KNjBwLYRn8PN2V9mxg3V0vGaM4lXW0CVBj94cybKUqKWzgV/vBQm+5IRUdzdxEB6unU5QFyhVka9w+ohpB+4rPNGNGvNpgkJtMB4t4K8rZBTB1DNM8sIJxyRimqm5WSDv5xlmwFHiv2kmpT2/KvDXaaoo=';
//            $create_task_result = $this->createTask($task_request_id,$audio_url);
//            var_dump($create_task_result);

            //查询任务
            //任务id,这个是创建任务返回的id
            $task_id = '250725164319473789817796';
            $query_task_result = $this->queryTask($task_id);
            var_dump($query_task_result);


        } catch (\Exception $e) {
            $output->error("发生错误: " . $e->getMessage());
        }

        $output->info("任务执行完成。");
    }

    /**
     * @Description: 文件上传接口(支持讯飞新鉴权方式)
     * @Author: AaronYang
     * @Date: 2025/7/25 09:10
     * @param string $upload_host 上传地址
     * @param string $api_key API Key
     * @param string $api_secret API Secret
     * @param string $file_path 文件路径
     * @return array|mixed
     * @throws \Exception
     */
    protected function upload($upload_host, $api_key, $api_secret, $file_path)
    {
        $file_name = basename($file_path);
        // 请求唯一标识 最后换成随机 编号
        $request_id = '202201111019';

        // 8. 构造 POST 数据(使用 CURLFile)
        $postData = [
            //文件上传数据
            'data' => new \CURLFile($file_path, 'audio/wav', $file_name),
            //应用唯一标识
            'app_id' => $this->appid,
            //请求唯一标识
            'request_id' => $request_id,
        ];

        // 9. 设置请求头(⚠️ 不要手动设置 Content-Type,让 cURL 自动处理)
        $contentType = 'multipart/form-data';
        $headers = $this->generateAuthHeaders($upload_host, "POST", $api_key, $api_secret, json_encode($postData),$contentType);

        $query_result = $this->curlPost($upload_host, $headers, $postData);


//        返回结果...
//        {
//            "code": 0,        //错误码,0标识成功
//            "sid": "fpt0001c5fe@dx198402155369d0e802", //会话唯一标识
//            "data": {
//                "url": "https:\/\/xfyun-seve-dx\/IBAUEX+ollA5b\/18xtFQFR+TYlU1dp7UqPcyprLi+OlY2lR8fx8WmRjLfrOFOEiYFfzXIo0HQCzH5yQM38LhMgNGpCCFsi8zTtZwmmxeTghCM8HI+zRgKWVrQa\/TjQbSV9ih6r6qeRyBvBeHkVzsc0+Y47vY7CjyIzsqrFKck2PA1KowEKKW4moiMfZJ8U2OmYzqcRQkTaoYuyht47PyTy66ZcECs57XiMEjmjkUDxRd0h7t0Dfc\/yFDfQZByCDhYhUUi5ff+1DlE8EdjJ6seDWjfJWXRNAdX7maHmSlKSmFVNL5\/atCjgGhHGtJWEdvMYwIGvbjuYe\/0vBTeZC8iVx7e45bA4Z7dZm8fNlZZdc="                  //文件下载地址
//            },
//            "message": "success" //错误描述
//        }

        return $query_result;
    }


    /**
     * @Description: 描述
     * @Author: AaronYang
     * @Date: 2025/7/25 14:35
     * @param $host
     * @param $headers
     * @param $body
     * @return void
     */
    protected function curlPost($host, $headers, $postData)
    {
        // 10. 初始化 cURL
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $host);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

        //临时禁用 SSL 验证(开发环境可用)
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array_map(function ($key, $value) {
            return "$key: $value";
        }, array_keys($headers), $headers));


        $response = curl_exec($ch);

        if (curl_errno($ch)) {
            throw new \Exception('cURL 错误: ' . curl_error($ch));
        }

        curl_close($ch);

        return json_decode($response, true);

    }


    /**
     * @Description: 描述
     * @Author: AaronYang
     * @Date: 2025/7/25 13:52
     * @param $url
     * @param string $method
     * @param $apiKey
     * @param $apiSecret
     * @param $bodyJson
     * @return array
     */
    private function generateAuthHeaders($url, string $method, $apiKey, $apiSecret, $bodyJson,$contentType)
    {
        // 1. 生成 host
        $parsedUrl = parse_url($url);
        $host = $parsedUrl['host'];
        $path = $parsedUrl['path'];

        // 2. 生成 date (GMT 时区, RFC1123 格式)
        $date = gmdate("D, d M Y H:i:s") . " GMT";

        // 3. 生成 digest
        $bodySha256 = hash('sha256', $bodyJson, true); // 结果为 raw binary
        $digestBase64 = base64_encode($bodySha256);
        $digestHeader = "SHA-256=" . $digestBase64;

        // 4. 生成签名原始字符串(注意换行、冒号后空格)
        $signatureOrigin = "host: $host\n" .
            "date: $date\n" .
            strtoupper($method) . " $path HTTP/1.1\n" .
            "digest: $digestHeader";

        // 5. 用 HMAC-SHA256 + APISecret 签名
        $signatureSha = hash_hmac('sha256', $signatureOrigin, $apiSecret, true); // raw binary
        $signature = base64_encode($signatureSha);

        // 6. 拼接 Authorization header
        $authorization = sprintf(
            'api_key="%s", algorithm="hmac-sha256", headers="host date request-line digest", signature="%s"',
            $apiKey,
            $signature
        );

        // 返回所有头部信息
        return [
            'Host' => $host,
            'Date' => $date,
            'Digest' => $digestHeader,
            'Authorization' => $authorization,
            'Content-Type' => $contentType,
        ];

    }


    /**
     * @Description: 创建任务
     * @Author: AaronYang
     * @Date: 2025/7/25 14:08
     * @return void
     */
    protected function createTask($task_request_id,$audio_url)
    {
        $postData = array(
            "common" => array(
                "app_id" => $this->appid
            ),
            "business" => array(
                "request_id" => $task_request_id,
                "language" => "zh_cn",
                "domain" => "pro_ost_ed",
                "accent" => "mandarin",
                "speaker_num" => 2,
//                "callback_url" => '' // 任务回调地址
            ),
            "data" => array(
                "audio_url" => $audio_url,
                "audio_src" => "http",
                "format" => "audio/L16;rate=16000",
//                "encoding" => "raw"
                "encoding" => "lame"
            )
        );

        $task_host  = $this->createTaskHost;
        $api_key = $this->apiKey;
        $api_secret = $this->apiSecret;


        // 9. 设置请求头(⚠️ 不要手动设置 Content-Type,让 cURL 自动处理)
        $contentType = 'application/json';
        $headers = $this->generateAuthHeaders($task_host, "POST", $api_key, $api_secret, json_encode($postData),$contentType);

        //"{"code":0,"data":{"task_id":"250725144637771429777471"},"message":"success","sid":"ost000dba33@dx19840556fca6f16902"}
        return $this->curlPost($task_host, $headers, json_encode($postData));
//        {
//            "code": 0,
//            "data": {
//                "task_id": "250725144637771429777471"
//            },
//            "message": "success",
//            "sid": "ost000dba33@dx19840556fca6f16902"
//        }
    }



    /**
     * @Description: 查询任务id
     * @Author: AaronYang
     * @Date: 2025/7/25 14:57
     * @param $task_id
     * @return void
     */
    protected function queryTask($task_id)
    {
        $postData = array(
            "common" => array(
                "app_id" => $this->appid
            ),
            "business" => array(
                "task_id" => $task_id
            )
        );

        $query_host  = $this->queryHost;
        $api_key = $this->apiKey;
        $api_secret = $this->apiSecret;


        // 9. 设置请求头(⚠️ 不要手动设置 Content-Type,让 cURL 自动处理)
        $contentType = 'application/json';
        $headers = $this->generateAuthHeaders($query_host, "POST", $api_key, $api_secret, json_encode($postData),$contentType);

        //"{"code":0,"data":{"$query_host":"250725144637771429777471"},"message":"success","sid":"ost000dba33@dx19840556fca6f16902"}
        return $this->curlPost($query_host, $headers, json_encode($postData));

    }
}


 

posted on 2025-08-02 09:22  飞离地平线  阅读(20)  评论(0)    收藏  举报