微信小程序:腾讯AI语音合成实践

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/eadio/article/details/78962247

最近正在研究小程序地图开发项目,其中有一个是要实现路线导航播放功能,找了各个平台的语音合成,发现只有腾讯AI开放平台的Restful API本人比较看得懂,于是决定先用这个接口实践测试。

官方地址请走:https://ai.qq.com/doc/aaitts.shtml

我这里使用的是第一种方式,语音合成(AI Lab)。然后后端开发环境使用的是phpStudy软件。接着跟着我下面的步骤走。

1、注册登录开放平台,我这里默认使用qq登录,然后创建一个新应用,然后就可以在应用管理列表获取到每个应用的appid和appkey了。如下图:
创建新应用
应用管理

2、使用php调用方集成语音合成API。这里重在测试,所有方法都集成在一个页面上。具体代码如下:

<?php

// 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个文本,那么超出的情况我怎么做到无缝播放。如果有该方面经验的网友看到该博文,希望分享下你的经验,谢谢~

猜你喜欢

转载自blog.csdn.net/eadio/article/details/78962247