最近正在研究小程序地图开发项目,其中有一个是要实现路线导航播放功能,找了各个平台的语音合成,发现只有腾讯AI开放平台的Restful API本人比较看得懂,于是决定先用这个接口实践测试。
官方地址请走:https://ai.qq.com/doc/aaitts.shtml
我这里使用的是第一种方式,语音合成(AI Lab)。然后后端开发环境使用的是phpStudy软件。接着跟着我下面的步骤走。
1、注册登录开放平台,我这里默认使用qq登录,然后创建一个新应用,然后就可以在应用管理列表获取到每个应用的appid和appkey了。如下图:
2、使用php调用方集成语音合成API。这里重在测试,所有方法都集成在一个页面上。具体代码如下:
// getReqSign :根据 接口请求参数 和 应用密钥 计算 请求签名
// 参数说明
// - $params:接口请求参数(特别注意:不同的接口,参数对一般不一样,请以具体接口要求为准)
// - $appkey:应用密钥
// 返回数据
// - 签名结果
function getReqSign($params /* 关联数组 */, $appkey /* 字符串*/)
{
// 1. 字典升序排序
ksort($params);
// 2. 拼按URL键值对
$str = '';
foreach ($params as $key => $value)
{
if ($value !== '')
{
$str .= $key . '=' . urlencode($value) . '&';
}
}
// 3. 拼接app_key
$str .= 'app_key=' . $appkey;
//echo $str;
// 4. MD5运算+转换大写,得到请求签名
$sign = strtoupper(md5($str));
return $sign;
}
// doHttpPost :执行POST请求,并取回响应结果
// 参数说明
// - $url :接口请求地址
// - $params:完整接口请求参数(特别注意:不同的接口,参数对一般不一样,请以具体接口要求为准)
// 返回数据
// - 返回false表示失败,否则表示API成功返回的HTTP BODY部分
function doHttpPost($url, $params)
{
$curl = curl_init();
$response = false;
do
{
// 1. 设置HTTP URL (API地址)
curl_setopt($curl, CURLOPT_URL, $url);
// 2. 设置HTTP HEADER (表单POST)
$head = array(
'Content-Type: application/x-www-form-urlencoded'
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $head);
// 3. 设置HTTP BODY (URL键值对)
$body = http_build_query($params);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
// 4. 调用API,获取响应结果
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_NOBODY, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//官网提供的源码是true,需要改成2,否则报错
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
if ($response === false)
{
$response = false;
break;
}
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($code != 200)
{
$response = false;
break;
}
} while (0);
curl_close($curl);
return $response;
}
// 设置请求数据
$appkey = '你的应用的appkey';
$params = array(
'app_id' => '你的应用的appid',
'speaker' => '5',
'format' => '3',//mp3格式
'volume' => '0',
'speed' => '100',
'text' => '哈哈哈,你好,腾讯',
'aht' => '0',
'apc' => '58',
'time_stamp' => strval(time()),
'nonce_str' => strval(rand()),
'sign' => ''
);
$params['sign'] = getReqSign($params, $appkey);
//var_dump($params);
//return ;
// 执行API调用
$url = 'https://api.ai.qq.com/fcgi-bin/aai/aai_tts';
$response = doHttpPost($url, $params);
//test
//echo $response;
//return ;
//重新整合返回json数据
$res_arr=json_decode($response, true);
$ret=array(
'ret'=>$res_arr['ret'],
'data'=>$res_arr['msg']
);
if($res_arr['ret']===0){
//base64数据转mp3文件
$audio = file_put_contents('upload/audio/audio.mp3', base64_decode($res_arr['data']['speech']));
$ret['data']='http://你的本机ip地址:8282/phpserver/upload/audio/audio.mp3';//返回保存的mp3地址
//echo json_encode($ret);
}
echo json_encode($ret);
//echo $response;
?>
3、小程序发起请求得到合成的音频地址:
Page({
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let that=this;
//
const innerAudioContext = wx.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.loop=true;
wx.request({
url: 'http://你的本机ip地址:8282/phpserver/speech.php',
data: {},
method: 'POST',
success(res){
console.log('success');
console.log(res);
let data=res.data;
if(data.ret===0){
innerAudioContext.src=data.data; //后端返回的mp3文件地址
innerAudioContext.onPlay(()=>{
console.log('开始播放啦');
});
innerAudioContext.onError((res) => {
console.log(res.errMsg)
console.log(res.errCode)
});
}
},
fail(err){
console.log('err');
console.log(err)
}
});
}
})
目前有个问题未得到解决,该api的text文本长度上线是150字节,也就是75个文本,那么超出的情况我怎么做到无缝播放。如果有该方面经验的网友看到该博文,希望分享下你的经验,谢谢~