找回密码
 立即注册

小程序-语音播报功能

匿名  发表于 2022-12-9 17:57:20 阅读模式 打印 上一主题 下一主题
功用需求

实现经过传入“语音文案自动播报”,如:“测试播报”,语音自动播报“测试播报”
计划

利用wx.playVoice播放语音文件

优点:利用简单,间接播放录制好的音频文件
弱点:只能播放录制好的语音文件
第三方语音办事 + wx.createInnerAudioContext

优点:功用强大,可定制,可以满足复杂的场景;
弱点:需要办事端对接,付费
小法式插件 + wx.createInnerAudioContext

优点:简单快速,适用于简单场景;
弱点:功用单一,没法定制,大写英文没法识别,部分小写英文发音不准
第三方语音平台

语音平台


  • 腾讯Ai
  • 科大讯飞
  • 百度Ai
  • 阿里云
办事端

对接第三方平台,将转换后的语音数据交给小法式。
小法式

增加请求
wx.request({
  url: 'https://xxxx.com',
  data: { data: "待分解的语音数据"},
  method: "get",
  header: {
    'content-type': 'application/json' // 默许值
  },
  dataType: "json",
  success: function (res) {
    const innerAudioContext = wx.createInnerAudioContext();
    innerAudioContext.src = res.filename;
    innerAudioContext.play();
  }
})微信插件


  • 增加微信同声传译插件:在微信公众平台设置,找到设备–第三方设备–插件治理–点击增加插件

小法式-语音播报功用-1.jpg

  • 搜索微信同声传译,点击增加

小法式-语音播报功用-2.jpg

  • 引入插件:在项目根目录app.json文件中设置
"plugins": {   
    // 引入插件
    "WechatSI": {     //   自界说的名字
      "version": "0.3.5",   // 引入插件的版本号
      "provider": "wx069ba97219f66d99"    // 引入插件的appID
    }
  }

  • 利用
const plugin = requirePlugin('WechatSI');

onReady() {
  this.innerAudioContext = wx.createInnerAudioContext();
  const that = this;
  plugin.textToSpeech({
    // 挪用插件的方式
    lang: 'zh_CN',
    content: '测试语音播报',
    success: function (res) {
      that.playAudio(res.filename);
    }
  });
},

playAudio(e) {
  this.innerAudioContext.src = e;
  this.innerAudioContext.play();
},封装优化

const plugin = requirePlugin('WechatSI');
import { trim, isLetter } from '@/shared/index';

class PluginService {
  innerAudioContext;

  audioBroadcast(content: string): Promise<any> {
    return new Promise((resolve, reject) => {
      this.innerAudioContext = wx.createInnerAudioContext();
      plugin.textToSpeech({
        // 挪用插件的方式
        lang: 'zh_CN',
        content,
        success: res => {
          this.playAudio(res.filename, resolve, reject);
        },
        fail: reject
      });
    });
  }

  playAudio(e, resolve, reject) {
    this.innerAudioContext.src = e;
    this.innerAudioContext.play();

    this.innerAudioContext.onStop(() => {
      console.log('[ onStop ] >');
      resolve({
        type: 'stop'
      });
    });

    this.innerAudioContext.onEnded(() => {
      //播放竣事,烧毁该实例
      this.innerAudioContext.destroy();

      console.log('[ onEnded ] >');

      resolve({
        type: 'end'
      });
    });

    this.innerAudioContext.onError(error => {
      console.log('[ onError ] >', error);

      this.innerAudioContext.destroy();
      reject(error);
    });
  }

  stopAudio() {
    this.innerAudioContext.stop();
    this.innerAudioContext.destroy();
  }
}

export default new PluginService();在shared/index中工具函数:
// 去掉字符串中一切空格(包括中心空格,需要设备第2个参数为:true)
export function trim(str: string, isGlobal = true) {
  if (!str) {
    return str;
  }
  const result = str.replace(/(^\s+)|(\s+$)/g, '');
  return isGlobal ? result.replace(/\s/g, '') : result;
}

// 判定能否为字母
export function isLetter(str) {
  const reg = /^[A-Za-z]+$/;
  return reg.test(str);
}

// 字母转中文
export function translateAlphabet(letters) {
  if (!letters || !(letters.length > 0)) {
    return letters;
  }

  let tLetters = '';

  for (const key of letters) {
    tLetters += alphabetComparison(key);
  }

  return trim(tLetters);
}

// 字母中文读法
export function alphabetComparison(letter) {
  if (!letter || !isLetter(letter)) {
    return letter;
  }

  const letterCase = letter.toUpperCase();
  const letterMap = {
    A: '诶',
    B: 'b',
    C: '西',
    D: '帝',
    E: '伊',
    F: 'f',
    G: 'g',
    H: 'h',
    I: 'i',
    J: 'j',
    K: 'k',
    L: 'l',
    M: 'm',
    N: 'n',
    O: '欧',
    P: 'p',
    Q: 'q',
    R: 'r',
    S: '爱死',
    T: 't',
    U: '优',
    V: 'v',
    W: 'w',
    X: 'x',
    Y: '歪',
    Z: 'z'
  };
  return letterMap[letterCase];
}在页面中利用:
import { pluginService, translateAlphabet } from '@util';
import { formatCabinetNo, getCacheCabinet } from '@/shared/index';

Page({

  ...
  
  onLoad(e) {
    // 获得定单成果范例
    this.autoPlay();
  },
  
  onUnload() {
    pluginService.stopAudio();
  },

  // 轮询播放屡次
  autoPlay(timerCount = 0, maxCount = 100) {
    const { address, lockerName } = this.data;

    console.log('timerCount:', timerCount);

    if (timerCount > maxCount) {
      return;
    }

    const tAddress = translateAlphabet(address);

    console.log('[ translateAlphabet ] >', tAddress);

    // '认准柜门号再寄存,不要存错门'
    const message = `您的柜门号是${tAddress}${lockerName},请认准柜门号寄存,不要存错门`;

    pluginService
      .audioBroadcast(message)
      .then(res => {
        if (res.type !== 'stop') {
          this.autoPlay(++timerCount);
        }
        console.log('audioBroadcast.complete', res);
      })
      .catch(err => {
        console.log('[ audioBroadcast.err ] >', err);
        this.autoPlay(timerCount);
      });
  }
}); 留意:

  • 语音输入配额:每个小法式250条/分钟,3w条/天。
  • 文本翻译配额:每个小法式500次/分钟,10w次/天。
  • 语音分解配额:每个小法式100次/分钟,2w次/天。
题目归档


  • 在小法式onHide,onUnload函数里挪用stop方式无效;需要同时挪用destroy方式
this.innerAudioContext.stop();
this.innerAudioContext.destroy();

  • 经测试发现中文中的大写英笔墨母没法识别,部分小写英笔墨母发音有误
参考


  • 移动端快速接入语音播报
  • 微信同声传译小法式插件 —— 机械翻译、智能语音
关注我

操纵余暇时候免费兼职(无门坎,持久有用),请联系我(PS:关注公众号后,点击“联系我”获得联系方式)~
回复

使用道具

说点什么

您需要登录后才可以回帖 登录 | 立即注册
HOT • 推荐

神回复

站长姓名:王殿武 杭州共生网络科技 创始人 云裂变新零售系统 创始人 飞商人脉对接平台 创始人 同城交友聚会平台 创始人 生活经验分享社区 创始人 合作微信:15924191378(注明来意)