最近有一个需求,把企业微信同步过来的音频文件同步
转成文字,音频文件是存储在阿里云OSS上的,按说用阿里云的语音转文字是最方便的,但好巧不巧,企业微信的音频文件全是amr
格式的,阿里云的录音文件识别极速版不支持这个格式!而腾讯云的录音文件识别极速版是支持的。
所以一番辗转之下,就使用了腾讯云的录录音文件识别极速版服务,这个服务使用服务端API对接只支持到2.0版本,控制台的API Explorer里没有对应的接口调用,好在网上有人写好了PHP语言版的代码,拿过来改改就能用了,很方便,不用安装第三方库。
首先是核心类:
<?php
namespace app\common\library;
/**
* 腾讯云录音文件识别极速版
*/
class TencentSpeedVoice
{
//腾讯云密钥信息 需要配置
const APPID = "xxx";
const SECRET_ID = "xxx";
const SECRET_KEY = "xxxxx";
const AGREEMENT = "https";
const VOICE_URL = "asr.cloud.tencent.com/asr/flash/v1/";
const HTTPRequestMethod = "POST";
//引擎模型类型。8k_zh:8k 中文普通话通用;16k_zh:16k 中文普通话通用;16k_en:16k 英语;16k_zh_video:16k 音视频领域。
static $ENGINE_MODEL_TYPE = '16k_zh';
//结果返回方式 0:同步返回,拿到全部中间结果, or 1:尾包返回
static $RES_TYPE = 1;
//支持格式 wav、pcm、ogg-opus、speex、silk、mp3、m4a、aac、amr
static $VOICE_FORMAT = 'amr';
//是否开启说话人分离
static $SPEAKER_DIARIZATION = 0;
//后处理参数
static $FILTER_DIRTY = 0;
static $FILTER_MODAL = 0;
static $FILTER_PUNC = 0;
static $CONVERT_NUM_MODE = 1;
static $WORD_INFO = 0;
static $FIRST_CHANNEL_ONLY = 1;
/**
* 语音识别
* @param $pathFile string 文件路径
* @return bool|string
*/
public static function voice2Text($pathFile)
{
//get请求 设置url参数
$timestamp = time();
$httpUrlParams =
[
"appid" => self::APPID,
"secretid" => self::SECRET_ID,
"engine_type" => self::$ENGINE_MODEL_TYPE,
"voice_format" => self::$VOICE_FORMAT,
"timestamp" => $timestamp,
"speaker_diarization" => self::$SPEAKER_DIARIZATION,
"filter_dirty" => self::$FILTER_DIRTY,
"filter_modal" => self::$FILTER_MODAL,
"filter_punc" => self::$FILTER_PUNC,
"convert_num_mode" => self::$CONVERT_NUM_MODE,
"word_info" => self::$WORD_INFO,
"first_channel_only" => self::$FIRST_CHANNEL_ONLY
];
//get请求url拼接
$requestUrl = self::AGREEMENT . "://" . self::VOICE_URL . self::APPID . "?";
//剔除appid
unset($httpUrlParams["appid"]);
//生成URL请求地址
$requestUrl .= http_build_query($httpUrlParams);
//鉴权
$sign = self::getAuthorizationString($httpUrlParams);
//分片数据包
$sectionData = file_get_contents($pathFile);
$headers = [
'Host: asr.cloud.tencent.com',
'Content-Type: application/octet-stream',
'Authorization: ' . $sign,
'Content-Length: ' . strlen($sectionData),
];
$result = self::get_curl_request($requestUrl, $sectionData, 'POST', $headers);
try {
$result = json_decode($result, true);
if ($result['code'] == 0) {
return $result['flash_result'][0]['text'];
} else {
return false;
}
} catch (\Exception $e) {
return false;
}
}
/**
* 发送请求
* @param $url
* @param array $param
* @param string $mothod
* @param array $headers
* @param int $return_status
* @param int $flag 关闭https证书
* @return array|bool|string
*/
static private function get_curl_request($url, $param, $mothod = 'POST', $headers = [], $return_status = 0, $flag = 0)
{
$ch = curl_init();
if (!$flag) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if (strtolower($mothod) == 'post') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
} else {
$url = $url . "?" . http_build_query($param);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 2);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$ret = curl_exec($ch);
$code = curl_getinfo($ch);
curl_close($ch);
if ($return_status == "1") {
return array($ret, $code);
}
return $ret;
}
/**
* 创建签名
* @param $params array 提交参数数组
* @return string
*/
private static function getAuthorizationString($params)
{
//加密字符串拼接
$signString = self::HTTPRequestMethod . self::VOICE_URL . self::APPID . "?";
//排序
ksort($params, SORT_STRING);
//去除appid
unset($params["appid"]);
//转url
$signString .= http_build_query($params);
$sign = base64_encode(hash_hmac('SHA1', $signString, self::SECRET_KEY, true));
return $sign;
}
}
调用示例
use app\common\library\TencentSpeedVoice;
public function test_voice(){
// 如果是其它音频格式,取消掉下面一行的注释并改成相应的格式
// TencentSpeedVoice::$VOICE_FORMAT = "amr";
// 文件是可以是本地相对路径的文件,也可以是url
$file = "";
$rs = TencentSpeedVoice::voice2Text($file);
var_dump($rs);
}
成功的话直接输出识别后的文本,失败的话返回false
,可以根据自己的需要修改核心类。