TaskSystem/app/api/controller/XunFeiController.php
2023-10-09 20:00:58 +08:00

285 lines
9.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\api\controller;
use IFlytek\Xfyun\Speech\ChatClient;
use WebSocket\Client;
/**
* 讯飞
* Class WechatController
*/
class XunFeiController extends BaseApiController
{
public array $notNeedLogin = ['chat', 'iat'];
private $app_id='2eda6c2e';
private $api_key='12ec1f9d113932575fc4b114a2f60ffd';
private $api_secret='MDEyMzE5YTc5YmQ5NjMwOTU1MWY4N2Y2';
public function chat()
{
header('X-Accel-Buffering: no');
$parmas=$this->request->param('content');
if(empty($parmas)){
return $this->success('success');
}
$chat=new ChatClient($this->app_id,$this->api_key,$this->api_secret);
$client = new Client($chat->assembleAuthUrl('wss://spark-api.xf-yun.com/v2.1/chat'));
// 连接到 WebSocket 服务器
if ($client) {
// 发送数据到 WebSocket 服务器
$data = $this->getBody($this->app_id,$parmas);
$client->send($data);
// 从 WebSocket 服务器接收数据
$answer = "";
while(true){
$response = $client->receive();
$resp = json_decode($response,true);
$code = $resp["header"]["code"];
// echo "从服务器接收到的数据: " . $response;
if(0 == $code){
$status = $resp["header"]["status"];
if($status != 2){
$content = $resp['payload']['choices']['text'][0]['content'];
$answer .= $content;
print($answer);
ob_flush(); // 刷新输出缓冲区
flush(); // 刷新系统输出缓冲区
}else{
$content = $resp['payload']['choices']['text'][0]['content'];
$answer .= $content;
$total_tokens = $resp['payload']['usage']['text']['total_tokens'];
print("\n本次消耗token用量\n");
print($total_tokens);
ob_flush(); // 刷新输出缓冲区
flush(); // 刷新系统输出缓冲区
break;
}
}else{
return $this->fail( "服务返回报错".$response);
break;
}
}
ob_flush(); // 刷新输出缓冲区
flush(); // 刷新系统输出缓冲区
return $this->success('success');
} else {
return $this->fail('无法连接到 WebSocket 服务器');
}
}
//构造参数体
function getBody($appid,$question){
$header = array(
"app_id" => $appid,
"uid" => "1"
);
$parameter = array(
"chat" => array(
"domain" => "generalv2",
"temperature" => 0.5,
"max_tokens" => 1024
)
);
$payload = array(
"message" => array(
"text" => array(
array("role" => "user", "content" => $question)
)
)
);
$json_string = json_encode(array(
"header" => $header,
"parameter" => $parameter,
"payload" => $payload
));
return $json_string;
}
public function iat()
{
$appid = "fa185cd6";
$apiSecret = "1474397d85f34828194622aab80f1e51";
$apiKey = "ZjQOYjhjMmE2NmMzYzhiMjU30GE1NjJl";
$hostUrl = "ws://iat-api.xfyun.cn/v2/iat";
// 请填写您的音频文件路径
$file = storage_path() . '/app/public/audio/1675996119143.mp3';
$st = microtime(true);
$authUrl = $this->assembleAuthUrl($hostUrl, $apiKey, $apiSecret);
$client = new Client($authUrl);
//打开音频文件
$audioFile = fopen($file, 'rb');
if ($audioFile === false) {
throw new \Exception('open file error');
}
$frameSize = 1280; //每一帧的音频大小
$intervel = 40 * 1000; //发送音频间隔
$status = 0;
// 连接到 WebSocket 服务器
if ($client) {
//发送数据
while (true) {
$len = fread($audioFile, $frameSize);
if ($len === false) {
break;
}
if ($len === '') { //文件读取完了改变status = STATUS_LAST_FRAME
$status = 2;
}
switch ($status) {
case 0: //发送第一帧音频带business 参数
$frameData = array(
'common' => array(
'app_id' => $appid //appid 必须带上,只需第一帧发送
),
'business' => array( //business 参数,只需一帧发送
'language' => 'en_us',
'domain' => 'iat',
// 'accent' => 'mandarin'
),
'data' => array(
'status' => 0,
'format' => 'audio/L16;rate=16000',
'audio' => base64_encode($len),
'encoding' => 'lame'
)
);
$conn->send(json_encode($frameData));
$status = 1;
break;
case 1:
$frameData = array(
'data' => array(
'status' => 1,
'format' => 'audio/L16;rate=16000',
'audio' => base64_encode($len),
'encoding' => 'raw'
)
);
$conn->send(json_encode($frameData));
break;
case 2:
$frameData = array(
'data' => array(
'status' => 2,
'format' => 'audio/L16;rate=16000',
'audio' => base64_encode($len),
'encoding' => 'raw'
)
);
$conn->send(json_encode($frameData));
break 2;
}
//模拟音频采样间隔
usleep($intervel);
}
//获取返回的数据
while (true) {
$msg = $client->receive();
if ($msg === null) {
break;
}
$resp = json_decode($msg, true);
$code = $resp['code'];
$message = $resp['message'];
$data = $resp['data'];
$result = $data['result'];
$status = $data['status'];
$sid = $resp['sid'];
if ($code != 0) {
echo sprintf('%d %s %f', $code, $message, microtime(true) - $st);
break;
}
var_dump($resp, $result);
if ($status === 2) {
echo sprintf('%d %s %f', $code, $message, microtime(true) - $st);
break;
}
}
} else {
echo "无法连接到 WebSocket 服务器";
}
fclose($audioFile);
usleep(1); //等待数据接收完成
}
function assembleAuthUrl($hostUrl, $apiKey, $apiSecret)
{
$ul = parse_url($hostUrl);
$date = gmdate('D, d M Y H:i:s T');
$signString = array(
'host: ' . $ul['host'],
'date: ' . $date,
'GET ' . $ul['path'] . ' HTTP/1.1'
);
$sgin = implode("\n", $signString);
$sha = $this->HmacWithShaTobase64("hmac-sha256", $sgin, $apiSecret);
$authUrl = sprintf('api_key="%s", algorithm="%s", headers="%s", signature="%s"',
$apiKey, "hmac-sha256", "host date request-line", $sha);
$authorization = base64_encode($authUrl);
$v = array(
'host' => $ul['host'],
'date' => $date,
'authorization' => $authorization
);
$query = http_build_query($v);
$callurl = $hostUrl . '?' . $query;
return $callurl;
}
function HmacWithShaTobase64($algorithm, $data, $key)
{
$encodeData = hash_hmac('sha256', $data, $key, true);
return base64_encode($encodeData);
}
}