在Yii框架中接入语音识别功能,核心思路是通过框架的HTTP客户端组件调用第三方AI语音识别接口,完成音频文件的上传与识别结果获取,整个过程不需要自行开发语音识别算法,只需要做好接口对接和逻辑封装即可。

环境准备与依赖配置
首先确保Yii框架版本在2.0及以上,并且已经安装Guzzle HTTP客户端扩展,用于发送网络请求。如果还未安装,可以在项目根目录执行以下命令安装:
composer require guzzlehttp/guzzle
接着在Yii的配置文件config/web.php中添加接口相关的配置项,方便后续统一管理密钥和接口地址:
return [
// 其他配置项
'params' => [
'ai_voice' => [
'app_key' => '你的AI平台应用密钥',
'app_secret' => '你的AI平台应用密文',
'recognize_url' => 'https://api.ipipp.com/voice/recognize', // 替换为实际语音识别接口地址
'timeout' => 30
]
]
];
封装语音识别服务类
为了复用代码,我们可以创建一个专门的语音识别服务类,封装请求发送、参数处理、结果解析的逻辑。在common/services目录下创建VoiceRecognizeService.php文件:
<?php
namespace commonservices;
use Yii;
use GuzzleHttpClient;
use yiibaseException;
class VoiceRecognizeService
{
/**
* 调用语音识别接口
* @param string $audioPath 本地音频文件路径
* @param string $audioFormat 音频格式 如wav mp3
* @return string 识别后的文字内容
* @throws Exception
*/
public static function recognize($audioPath, $audioFormat = 'wav')
{
// 检查音频文件是否存在
if (!file_exists($audioPath)) {
throw new Exception('音频文件不存在');
}
$config = Yii::$app->params['ai_voice'];
$client = new Client([
'timeout' => $config['timeout']
]);
// 构造请求参数
$postData = [
'app_key' => $config['app_key'],
'timestamp' => time(),
'audio_format' => $audioFormat,
'audio_data' => base64_encode(file_get_contents($audioPath))
];
// 生成签名 不同平台签名规则不同 这里以简单拼接为例
$postData['sign'] = md5($config['app_key'] . $postData['timestamp'] . $config['app_secret']);
try {
$response = $client->post($config['recognize_url'], [
'form_params' => $postData
]);
$result = json_decode($response->getBody()->getContents(), true);
if ($result['code'] != 200) {
throw new Exception('识别失败:' . $result['msg']);
}
return $result['data']['text'];
} catch (Exception $e) {
throw new Exception('接口请求异常:' . $e->getMessage());
}
}
}
控制器中调用实现功能
接下来在控制器中编写接口,接收前端上传的音频文件,调用服务类完成识别并返回结果。创建VoiceController.php:
<?php
namespace frontendcontrollers;
use Yii;
use yiiwebController;
use yiiwebUploadedFile;
use commonservicesVoiceRecognizeService;
use yiiwebResponse;
class VoiceController extends Controller
{
public $enableCsrfValidation = false;
/**
* 语音识别接口
*/
public function actionRecognize()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$request = Yii::$app->request;
$audioFile = UploadedFile::getInstanceByName('audio_file');
if (empty($audioFile)) {
return ['code' => 1001, 'msg' => '请上传音频文件'];
}
// 保存临时音频文件
$tmpPath = Yii::getAlias('@runtime') . '/voice_' . time() . '.' . $audioFile->extension;
if (!$audioFile->saveAs($tmpPath)) {
return ['code' => 1002, 'msg' => '文件保存失败'];
}
try {
$text = VoiceRecognizeService::recognize($tmpPath, $audioFile->extension);
// 删除临时文件
unlink($tmpPath);
return ['code' => 200, 'msg' => '识别成功', 'data' => ['text' => $text]];
} catch (Exception $e) {
if (file_exists($tmpPath)) {
unlink($tmpPath);
}
return ['code' => 1003, 'msg' => $e->getMessage()];
}
}
}
常见问题与优化建议
音频格式兼容问题
不同AI平台的语音识别接口支持的音频格式不同,常见的有16k采样率的wav、mp3格式,如果上传的音频格式不符合要求,需要先使用FFmpeg等工具做格式转换,再调用识别接口。
大文件处理优化
如果音频文件较大,直接base64编码后传输会占用大量内存,建议先上传音频到对象存储,再将文件地址传给AI接口,避免本地临时文件占用过多磁盘空间。
异常重试机制
网络波动可能导致接口请求失败,可以在服务类中添加重试逻辑,当请求失败时自动重试2-3次,提升功能的稳定性。
总结
Yii框架实现语音识别的核心是对接第三方AI接口,通过封装服务类可以简化调用逻辑,提升代码复用性。实际开发中需要根据所用AI平台的接口文档调整参数构造和签名规则,同时做好异常处理和临时文件清理,保证功能的稳定运行。