使用百度语音技术(TTS)实现文字转语音

56

使用百度语音技术实现文字转语音

SpringBoot+Vue前后端分离项目

调用api接口需要使用AK和SK生成AccessToken,生成getAccessToken的接口有跨域限制,所以统一的由后端处理了

部分参数在控制台->语音技术->在线调试里面能找到

Controller

@RestController
@RequestMapping("/tts")
public class BaiDuTTSController {


    @PostMapping("/baidu/{infoId}")
    public ResponseEntity<byte[]> info2Audio(@PathVariable("infoId") String infoId, HttpServletResponse response){
        // todo 通过infoId查询待转换的文字,字数小于60和大于60时使用的方法不一样,这里还没优化
        String text = "你好百度";

        byte[] audioBytes = new byte[0];
        try {
            audioBytes = getAudioFromService(text);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (audioBytes != null) {
            return ResponseEntity
                    .ok()
                    .contentType(MediaType.valueOf("audio/wav")) // 或者是audio/wav等,根据你的音频格式
                    .body(audioBytes);
        } else {
            // 返回错误响应
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    // 获取响应字节
    public  byte[] getAudioFromService( String text)throws Exception{
        String url = "https://tsn.baidu.com/text2audio";
        String requestBody = "tex=" + text + "&tok=" + getAccessToken() + "&cuid=这里要替换=5&pit=5&vol=5&per=1&aue=3";
        HttpResponse response = HttpRequest.post(url)
                .contentType("application/x-www-form-urlencoded")
                .body(requestBody)
                .header("Accept", "*/*")
                .execute();
        // 处理响应
        if (response.isOk()) {
           return response.bodyBytes();
        }
        throw new RuntimeException("获取音频错误,请联系管理员");

    }




    /**
     * 从用户的AK,SK生成鉴权签名(Access Token)
     *
     * @return 鉴权签名(Access Token)
     * @throws IOException IO异常
     */
    static String getAccessToken() throws IOException {
        String AK = "你的AK";
        String SK = "你的SK";
        String url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + AK + "&client_secret=" + SK;
        String postResult = HttpUtil.post(url, "");
        if (StrUtil.isBlank(postResult)){
            throw new RuntimeException("响应体为空");
        }
        JSONObject jsonObject = JSONUtil.parseObj(postResult);
        String accessToken = jsonObject.getStr("access_token");
        if (StrUtil.isBlank(accessToken)){
            throw new RuntimeException("accessToken为空");
        }
        return accessToken;
    }

}

VUE

// 音频展示   
<el-col :span="8">
        <audio :src="audioSrc" v-if="audioSrc" controls>
          您的浏览器不支持音频播放。
        </audio>
</el-col>
// methods
    // 语音播报的函数
    handleSpeak(id) {
    baiduTTS(id).then(res =>{
      console.log(res.headers)
      console.log(res)
        // 这里注意是res还是res.data,看你后台怎么封装的
      this.audioSrc   = URL.createObjectURL(new Blob([res],{type:"audio/wav"}));
    })
 },
// 发送请求的js
import request from '@/utils/request'

export async function baiduTTS(id) {
  return request({
    url: '/tts/baidu/' + id,
    method: 'post',
    responseType: "blob"
  })
}

参考

前端使用百度 TTS(语音合成)非常详细 - 掘金 (juejin.cn)

image-20240304164623514

ChatGPT:

image-20240304170256340

问题

this.audioSrc   = URL.createObjectURL(new Blob([res],{type:"audio/wav"}));

这一行代码出错(准确的是URL.createObjectURL)

安装/升级下core-js解决(yarn add core-js)