针对上两篇微信同声传译语音播报功能,又出现了坑

我又双叒叕来了,自己写的bug,跪着也要改完,我是真的服了

  • 首先,我们来说说是什么问题吧

    1. 上一篇文章的这张图还记得吧,不记得的,我在下面贴出来了;
    1. 我们在长度大于300的时候,根据句号或者逗号进行了切片,然后将这些片段转换成若干个短语音,通过遍历来进行完整播放(不记得的看上一篇吧);
    1. 图中的1和2都是根据句号来切成几个小片段;
    1. 在1正在播放时,切换到2进行播放,等2播放完成了之后,图标会从红色变成绿色,但是语音会接着1暂停的时机继续播放;
  • 原因呢?其实我也不确定,我稍微思考了几个可能得原因

    1. 可能是我写的遍历播放的方法有问题?
    1. 或者是因为我在切换的时候写的是pause(),暂停的方法
    1. 又或者是,wx.createInnerAudioContext()实例里面已经缓存了之前的语音地址
    1. 反正我不确定,但是问题我解决了(鼓掌吧,兄弟们)

解决方式

在切换图中1和2时,直接把实例清掉,然后再重新注册一个实例,简单且粗暴(我另外又偷偷的进行了一项优化)

js 复制代码
// 我在page外定义了两个全局属性,注意:这是写在page外的哈
let radioId = 0    // 存储当前播放id
let radioOldList = []    // 存储当前正在播放的语音列表


// 在onLoad里面进行实例化
this.innerAudioContext = wx.createInnerAudioContext();

// 阅读文字,页面上的点击图标
readText: async function (e) {
    const { item } = e.currentTarget.dataset
    const that = this;
    // 判断当前id和上一次存储的id是不是相同
    if (item.id == radioId) {
    // 相同就调用pause()暂停方法,再次点击会接着之前暂停处播放
      that.innerAudioContext.pause()
    } else {
    // 不相同就调用stop()停止方法
      that.innerAudioContext.stop()
      // 同时将实例清除
      that.innerAudioContext = null
      // 重新创建一个实例
      that.innerAudioContext = wx.createInnerAudioContext()
    }
    that.data.questionList.forEach(el => {
        if (el.id == item.id) {
          el.type = 'pause'
        } else {
          el.type = 'play'
        }
    });
    that.setData({
      questionList: that.data.questionList,
      playItem: item
    })
    // 当前id和上一次存储的id相同时,跳过语音转换步骤,直接使用之前的存储的语音列表
    if (item.id == radioId) {
      that.readStart(radioOldList, item.id)
      return
    }
    let list = splitStringByLength(item.audiodialogue, 300)
    let radioList = list.map(el => {
      return new Promise(resolve => {
        plugin.textToSpeech({
          lang: "zh_CN",
          tts: true,
          content: el,
          success: function (res) {
            resolve(res.filename)
          },
          fail: function (res) {
            wx.showToast({
              title: '语音转换失败',
            })
          }
        })
      })
    })
    Promise.all(radioList).then(res => {
      that.readStart(res, item.id)
    })
  },
  // 开始阅读
  readStart: async function (radioList, id) {
    const that = this
    // 将当前播放的语音列表存储起来
    radioOldList = radioList
    for (let text of radioList) {
      this.innerAudioContext.src = text;
      this.innerAudioContext.onPlay(() => {
        console.log('开始播放当前片段', 'onPlay');
      });
      this.innerAudioContext.onError((err) => {
        console.error('音频播放出错', err);
      });
      this.innerAudioContext.onEnded(async () => {
        // 如果是最后一个片段,这里可以结束,否则不需要await
        if (text === radioList[radioList.length - 1]) {
          that.data.questionList.forEach(el => {
            if (el.id == id) {
              el.type = 'play'
            }
          })
          that.setData({
            questionList: that.data.questionList,
          })
          that.innerAudioContext.stop()
          return
        }
      });
      // 将当前播放的id存储起来
      radioId = id
      // 确保前一个音频播放结束后再播放下一个
      await new Promise(resolve => {
        this.innerAudioContext.onEnded(resolve);
        this.innerAudioContext.play();
      });
    }
  },
关键代码:
  • 存储上一次的播放id和播放列表

  • readText方法内,判断当前播放的id是否和存储的相同,相同就跳过语音转换步骤

  • 如果不相同,先停止当前的播放并清除实例后,重新创建实例

总结:

全是坑,一个坑填完还有另外好多坑排着队等着,咋整?站着填不完,那就跪着填吧。就这样吧,累了
相关推荐
qtj-00116 小时前
普通人在刚开始做副业时要注意哪些细节?
大数据·微信·新媒体运营·创业创新
小杨互联网17 小时前
微信第三方开放平台接入本地消息事件接口报错问题java.security.InvalidKeyException: Illegal key size
微信·微信公众号·微信第三方开放平台·第三方开放平台接入
a6953188_17 小时前
如何评估一个副业项目的可行性?
大数据·微信·创业创新
2401_844137952 天前
JAVA智慧社区系统跑腿家政本地生活商城系统小程序源码
微信·微信小程序·小程序·生活·微信公众平台·微信开放平台
程序员入门进阶3 天前
基于微信的乐室预约小程序+ssm(lw+演示+源码+运行)
微信·小程序
太阳火神的美丽人生5 天前
WeChat_DevTools 断点调试方法总结
java·前端·微信
2401_844137957 天前
PHP探索校园新生态校园帮小程序系统小程序源码
微信·微信小程序·小程序·微信公众平台·微信开放平台
v(kaic_kaic)7 天前
基于STM32热力二级管网远程监控系统设计(论文+源码)_kaic
android·数据库·学习·mongodb·微信·目标跟踪·小程序
2401_844137578 天前
PHP探索校园新生态校园帮小程序系统小程序源码
微信·微信小程序·小程序·微信公众平台·微信开放平台
聊天宝快捷回复9 天前
必收藏,售后客服日常回复必备的话术 (精华版)
java·前端·数据库·经验分享·微信·职场发展·快捷回复