• 百度语音合成实现步骤

Step1:成为百度AI开放平台的开发者

在线语音合成

  1. // appKey = Va5yQRHl********LT0vuXV4
  2. // appSecret = 0rDSjzQ20XUj5i********PQSzr5pVw2
  3. https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=appKey4&client_secret=appSecret
  • 可以获取如下结果
  1. {
  2. "access_token": "1.a6b7dbd428f731035f771b8d********.86400.1292922000-2346678-124328",
  3. "expires_in": 2592000,
  4. "refresh_token": "2.385d55f8615fdfd9edb7c4b********.604800.1293440400-2346678-124328",
  5. "scope": "public audio_tts_post ...",
  6. "session_key": "ANXxSNjwQDugf8615Onqeik********CdlLxn",
  7. "session_secret": "248APxvxjCZ0VEC********aK4oZExMB",
  8. }
  • scope中含有audio_tts_post 表示有语音合成能力,没有该audio_tts_post 的token调用接口会返回502错误。
  • 在结果中可以看见 token和expires_in:在2592000秒(30天)后过期。

访问合成接口

  1. let access_token = 1.a6b7dbd428f731035f771b8d********.86400.1292922000-2346678-124328
  2. // 这是一个正常MP3的下载url
  3. // tex在实际开发过程中请urlencode2
  4. https://tsn.baidu.com/text2audio?per=0&tex=你好&lan=zh&cuid=1&ctp=1&spd=4&tok=access_token

百度语音合成demo

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <title>语音测试</title>
  6. </head>
  7. <body>
  8. <div>
  9. <input type="text" id="ttsText">
  10. <input type="button" id="tts_btn" onclick="doTTS()" value="播放">
  11. </div>
  12. <div id="bdtts_div_id">
  13. <audio id="tts_autio_id" autoplay="autoplay">
  14. <source id="tts_source_id" src="http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=9&text=播报内容" type="audio/mpeg">
  15. <embed id="tts_embed_id" height="0" width="0" src="">
  16. </audio>
  17. </div>
  18. </body>
  19. <script type="text/javascript">
  20. function doTTS(){
  21. var ttsDiv = document.getElementById('bdtts_div_id');
  22. var ttsAudio = document.getElementById('tts_autio_id');
  23. var ttsText = document.getElementById('ttsText').value;
  24. ttsDiv.removeChild(ttsAudio);
  25. var au1 = '<audio id="tts_autio_id" autoplay="autoplay">';
  26. /* tsn是正式版 */
  27. var token = 24.04cdb49de323c86d4ed169965b4f6083.2592000.1639813589.282335-25190934
  28. var sss = '<source id="tts_source_id" src="https://tsn.baidu.com/text2audio?per=0&tex='+ttsText+'&lan=zh&cuid=1&ctp=1&spd=4&tok=token" type="audio/mpeg">';
  29. /* tts是测试版 */
  30. /* var sss = '<source id="tts_source_id" src="https://tts.baidu.com/text2audio?cuid=baike&spd=4&lan=ZH&ctp=1&pdt=301&vol=4&rate=32&per=5&tex='+ttsText+'" type="audio/mpeg">';*/
  31. /* var sss = '<source id="tts_source_id" src="http://tts.baidu.com/text2audio?lan=Zh&ie=UTF-8&spd=4&text='+ttsText+'" type="audio/mpeg">';*/
  32. var eee = '<embed id="tts_embed_id" height="0" width="0" src="">';
  33. var au2 = '</audio>';
  34. ttsDiv.innerHTML = au1 + sss + eee + au2;
  35. ttsAudio = document.getElementById('tts_autio_id');
  36. ttsAudio.play();
  37. }
  38. </script>
  39. </html>

Vue中实现百度语音播放demo

  • voicePlay.js 播报语音方法

    1. export function voicePlay(word) {
    2. let url = "https://tts.baidu.com/text2audio?cuid=baike&spd=5&lan=ZH&ctp=1&pdt=301&vol=4&rate=32&per=0&tex=' " + encodeURI(word);
    3. let n = new Audio(url);
    4. n.src = url;
    5. n.play();//播放阅读
    6. return n
    7. }
  • 语音播报的混入代码 ```javascript / 播报语音方法 / import {voicePlay} from “@/utils/voicePlay” / websocket实时推送接口 / import {cancelVoiceWordMessage,voiceWordMessage} from ‘@/api/socket’

export const voicePlayerMiXin = { data() { return{ isOpenPlay: false, // 浏览器是否开启了语音播报

  1. voicePlayObj: null, // audio对象
  2. voiceWord: '', // 当前语音播报内容
  3. voiceType: '', // 当前播报语音的类型 0 事件,1 联勤
  4. voiceWordNew: '', // 最新推送的播报内容
  5. voicePlayState: false, // 播报状态
  6. voiceWordIsShow: false, // 播报文字是否显示
  7. isPlaying: false, // 语音是否正在播报
  8. eventId: '', // 事件id
  9. orderId: '',// 工单id
  10. }
  11. },
  12. watch:{
  13. '$store.state.connectStatus'() {
  14. this.initVoicePlayerSub()
  15. },
  16. // 监听区域ID变化
  17. '$store.state.region'() {
  18. this.initVoicePlayerSub()
  19. },
  20. //平台实时播报的内容
  21. '$store.state.voiceWord'() {
  22. let data = this.$store.state.voiceWord
  23. // 第一条数据来了之后,就开始播报,
  24. if (!this.isPlaying && this.isOpenPlay) {
  25. this.isPlaying = true
  26. this.voiceWord = ''
  27. this.voiceWordIsShow = false
  28. this.voicePlayMethod(data)
  29. }
  30. },
  31. },
  32. mounted() {
  33. this.initVoicePlayerSub();
  34. },
  35. methods: {
  36. // 监听用户鼠标悬浮事件,启用音频播放 浏览器默认是不播放音频的 需要事件启动
  37. openBrowserPlayVoice() {
  38. if (!this.isOpenPlay) {
  39. this.resetVoice()
  40. this.isOpenPlay = !this.isOpenPlay
  41. voicePlay('-')
  42. }
  43. },
  44. // 初始化语音播报的websocket连接
  45. initVoicePlayerSub() {
  46. cancelVoiceWordMessage()
  47. if (this.$store.state.connectStatus) {
  48. // 实时播报内容
  49. voiceWordMessage(this.$store.state.region.regionCode)
  50. }
  51. },
  52. // 播报语音
  53. voicePlayMethod(data) {
  54. let that = this
  55. // 如果没有开启语音播报,就返回
  56. if (!that.isOpenPlay) {
  57. that.resetVoice()
  58. return
  59. }
  60. // 正在播报,就返回
  61. if (that.voicePlayState) {
  62. return
  63. }
  64. that.orderId = data.orderId
  65. that.eventId = data.eventId
  66. // 没有播报,就开始播报
  67. if (!that.voicePlayState) {
  68. // 存储当前播报的类型和内容
  69. that.voiceType = data.tag
  70. that.eventId = data.eventId
  71. that.orderId = data.orderId
  72. that.voiceWord = data.desc
  73. // 显示播报弹窗
  74. that.voiceWordIsShow = true
  75. // 播报文字内容
  76. that.voicePlayObj = voicePlay(that.voiceWord)
  77. //当浏览器能够开始播放指定的音频/视频时,发生 canplay 事件。
  78. that.voicePlayObj.addEventListener("canplay", function () {
  79. that.voicePlayState = true
  80. });
  81. //当播放完一首歌曲时也会触发
  82. that.voicePlayObj.addEventListener("ended", function () {
  83. // 修改为当前没有语音播报
  84. that.resetVoice()
  85. })
  86. }
  87. },
  88. resetVoice() {
  89. // 修改为当前没有语音播报
  90. this.voicePlayState = false
  91. this.isPlaying = false // 播报完,设置为false
  92. this.voiceWord = ''
  93. this.voiceWordIsShow = false
  94. },
  95. // 点击语音播报,根据播报类型,跳转到新窗口 0 事件,1 联勤工单
  96. jumpNewWindow() {
  97. if (this.voiceType === 1) {
  98. let routeNameStr = this.$route.path
  99. // 根据当前路由名称是否为 /eventProcessing, 如果是联勤联动页面,就直接显示工单详情,如果不是就跳转到联勤联动页面
  100. if(routeNameStr === '/eventProcessing') {
  101. let orderId = this.orderId;
  102. this.curOrderIdName = this.orderId;
  103. if (orderId) {
  104. manageInfo({orderId}).then(res => {
  105. if (res.code == 0) {
  106. this.dialogVisible = true;
  107. this.$refs.workOrderDetails_.initDetailes();
  108. }
  109. })
  110. }
  111. } else {
  112. this.$router.push({
  113. name: 'eventProcessing',
  114. params: {
  115. orderId: this.orderId
  116. }
  117. });
  118. }
  119. return
  120. }
  121. if (this.voiceType === 0) {
  122. this.$store.state.curClickEventId = this.eventId
  123. let routeNameStr = this.$route.path
  124. // 根据当前路由名称是否为 /eventCenter, 如果是事件中心,就调用这个方法this.clickEventItem(null)
  125. if(routeNameStr === '/eventCenter') {
  126. this.clickEventItem(null)
  127. } else {
  128. // 当前路由名称不是 /eventCenter, 就跳转到 事件中心,显示事件详情
  129. this.$router.push({path: '/eventCenter'})
  130. }
  131. }
  132. },
  133. },
  134. destroyed() {
  135. this.voicePlayObj = null
  136. /* 断开webscoket */
  137. cancelVoiceWordMessage()
  138. },

}

  1. - 语音播报文字弹窗组件
  2. ```javascript
  3. <template>
  4. <div v-if="voiceWordIsShow" class="flex flex-center">
  5. <div @click="jumpNewWindow" class="voiceWord flex flex-center"
  6. style="z-index: 9999">
  7. <i class="iconfont iconfont_">&#xe697;</i>
  8. <span>{{voiceWord}}</span>
  9. </div>
  10. </div>
  11. </template>
  12. <script>
  13. export default {
  14. name: "voicePlay",
  15. props: {
  16. voiceWordIsShow: {
  17. type: Boolean,
  18. default: false
  19. },
  20. voiceWord: {
  21. type: String,
  22. default: ''
  23. }
  24. },
  25. data() {
  26. return {
  27. }
  28. },
  29. methods: {
  30. jumpNewWindow() {
  31. this.$emit('jumpNewWindow')
  32. }
  33. }
  34. }
  35. </script>
  36. <style lang="less" scoped>
  37. .voiceWord {
  38. position: absolute;
  39. top: calc(var(--num88) * var(--num));
  40. height: calc(var(--num40) * var(--num));
  41. line-height: calc(var(--num40) * var(--num));
  42. border-width: calc(var(--num1) * var(--num));
  43. border-style: solid;
  44. border-radius: calc(var(--num4) * var(--num));
  45. border-color: @primary5;
  46. background: @fill5;
  47. }
  48. .voiceWord span {
  49. margin: 0 calc(var(--num18) * var(--num)) 0 calc(var(--num11) * var(--num));
  50. font-size: calc(var(--num14) * var(--num));
  51. }
  52. .voiceWord i {
  53. margin-left: calc(var(--num18) * var(--num));
  54. }
  55. .iconfont_ {
  56. color: @yellow1 !important;
  57. font-size: calc(var(--num22) * var(--num)) !important;
  58. }
  59. </style>

使用语音播报组件

  1. <template>
  2. <div @mouseover.stop="openBrowserPlayVoice" >
  3. <!--语音播报组件-->
  4. <voicePlayComp
  5. @jumpNewWindow="jumpNewWindow"
  6. :voiceWordIsShow="voiceWordIsShow"
  7. :voiceWord="voiceWord"/>
  8. </div>
  9. </template>
  10. <script>
  11. import {voicePlayerMiXin} from '../../mixins/voicePlayerMiXin';
  12. export default {
  13. data() {
  14. return{}
  15. },
  16. mixins:[ voicePlayerMiXin ],
  17. mounted(){
  18. },
  19. methods:{
  20. }
  21. }
  22. </script>