在Vue项目中用Audio实现语音的播放

在Vue项目中用Audio实现语音的播放

​ 跟据项目的需求,有些时候我们需要实现,通过后台获取语音流,然后网页进行语音播放,在网页播放语音就可以避免用户的本地语音库的安装。

从后台获取语音流,生成Audio标签并赋值

​ 这里我用了axios请求

 getAudio() {
        this.$axios({
          url: "api/system/tts",//获取语音流的api
          data: { data},//这个是给后台传送需要播放的语音信息
          method: "post",
          responseType: "blob"//后台返回的为语音的流数据
        })
          .then(res => {
            let url = URL.createObjectURL(res.data);//通过这个API让语音数据转为成一个url地址
            let audio = new Audio();//在VUE中使用audio标签
            audio.src = url;//设置audio的src为上面生成的url
            let playPromiser = audio.play();//进行播放
            //在谷歌内核中,audio.play()会返回一个promise的值,在IE内核中就不会返回任何的值
            //所以如果你要分浏览器,可以判断playPromiser的值来进行操作哦
            audio.onended = () => {
            //onended可以检测语音是否播完
            //dosometing
            };
          })
          .catch(err => {});
    },

思路就是向后台发送需要播放的语音信息(文字),然后后台返回给你的语音流数据,通过URL.createObjectURL(data) 这个API生成一个URL,然后给audio标签附上url。

防止因为快速的请求语音数据造成语音播放叠在一起

​ 上面的方法是获取语音并播放,有时候用户会进行多次点击或请求,然后语音就会叠在一起播放,那就炸了(这里其实可以让后端做一个排队的队列,一个一个播,这里我前端也做了一个排队队列)

​ 对上面的方法进行改造改造

   getAudio() {
      if (this.callmsg.length > 0) {//如果队列是有人在排队的,这进行播放操作
        this.$axios({
          url: "api/system/tts",
          data: { data },
          method: "post",
          responseType: "blob"
        })
          .then(res => {
            let url = URL.createObjectURL(res.data);
            let audio = new Audio();
            audio.src = url;
            let playPromiser = audio.play();
            localStorage.setItem("audio", "1");//在这里我用一个标志,设置语音开始播放
            audio.onended = () => {
              this.callmsg.splice(0, 1);//队列的第一个播放完毕,所以删除
              localStorage.setItem("audio", "0");//这里是语音播放完毕
              this.getAudio();//进行下一个请求并播放
            };
          })
          .catch(err => {});
      } else {
          //this.audio是一个data数据,用来记录是否有人排队
        this.audio = true; //如果队列没人排队,就告诉外面已经读完啦
      }

​ 下面是用户的操作,就是触发播放函数的地方

     this.callmsg.push(data);//this.callmsg就是排队队列,点击一次,放进去一个需要播放的信息
          if (this.audio) {//如果没人
            this.audio = false;//改为有人排队了
            this.getAudio();//进行播放操作
          }

一开始的this.audio设置为true

思路是一开始为没人,需要播放信息时,将标志设置为有人,并向队列里面加入数据,然后进行请求,如果在播放中途有新的信息需要播放,就会再插入,但是标志不变,所以上面的递归函数会继续执行,直到队列为空,标志就会改回来。

  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在移动端中,可以使用 HTML5 的 audio 标签来实现音频播放,同时使用 CSS 样式来美化播放器的外观。 以下是一个基本的 HTML 结构: ```html <div class="audio-player"> <audio src="audio.mp3" preload="auto"></audio> <div class="play-button"></div> <div class="progress-bar"> <div class="progress"></div> </div> </div> ``` 其中,div.audio-player 是整个播放器的容器,audio 标签用于播放音频文件,div.play-button 是播放/暂停按钮,div.progress-bar 是进度条的容器,div.progress 是进度条的实际进度。 接下来是对应的 CSS 样式: ```css .audio-player { position: relative; width: 100%; height: 40px; margin: 20px 0; } .audio-player audio { display: none; } .play-button { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20px; height: 20px; border-radius: 50%; background-color: #333; } .play-button:before { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 0; height: 0; border-top: 8px solid transparent; border-left: 12px solid #fff; border-bottom: 8px solid transparent; } .progress-bar { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 80%; height: 2px; background-color: #ccc; } .progress { position: absolute; top: 0; left: 0; width: 0%; height: 100%; background-color: #333; transition: width 0.3s ease-in-out; } ``` 其中,audio 标签被隐藏了,play-button 是一个圆形按钮,progress-bar 是一个灰色的进度条,progress 是一个绿色的进度条,可以根据需要调整颜色和样式。 最后,使用 JavaScript 来实现播放/暂停和进度条的更新: ```js const audio = document.querySelector("audio"); const playButton = document.querySelector(".play-button"); const progressBar = document.querySelector(".progress"); playButton.addEventListener("click", function() { if (audio.paused) { audio.play(); playButton.classList.add("playing"); } else { audio.pause(); playButton.classList.remove("playing"); } }); audio.addEventListener("timeupdate", function() { const progress = (audio.currentTime / audio.duration) * 100; progressBar.style.width = progress + "%"; }); audio.addEventListener("ended", function() { playButton.classList.remove("playing"); progressBar.style.width = "0%"; }); ``` 其中,timeupdate 事件会在播放进度发生改变时触发,ended 事件会在播放结束时触发。在事件处理函数中,计算出当前播放进度,并将进度条的宽度设置为对应的百分比即可。 以上就是一个简单的移动端语音播放器的实现方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值