科大讯飞极速音频转写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)); } }