vue中使用短语音识别和文本在线合成,音频转文字以及文字转音频

今天介绍百度云的两种技术:短语音识别和文本在线合成。语音识别,新注册的的用户可以免费领取三个月的使用。


image.png

1. 业务场景是,在查询的输入框加了一个录音按钮,点击录音按钮弹出弹框,点击进行录音,点击结束录音,把录音音频使用百度智能云的短语音识别成文字(音频转文字),然后进行查询搜索。

html部分:

<svg-icon
 slot="suffix"
 icon-class="icon-recorder"
 class="icon-recorder"
 style="color: #333333"
 @click="startRecorder"
/>

data部分:

   // 录音
      recorderDialogVisible: false,
      rec: null,
      recordBase64: '',
      flag: false, // false 代表还没开始录音
      audioUrl: ''

js部分:

 created() {
    this.flag = false
  },

methods: {
 // 录音
    startRecorder() {
      // 创建录音对象
      this.rec = Recorder({
        type: 'wav', // 录音格式,可以换成wav等其他格式
        sampleRate: 16000, // 阿里采样率16000 录音的采样率,越大细节越丰富越细腻
        bitRate: 16, // 录音的比特率,越大音质越好
        onProcess: (
          buffers,
          powerLevel,
          bufferDuration,
          bufferSampleRate,
          newBufferIdx,
          asyncEnd
        ) => {
          // 录音实时回调,大约1秒调用12次本回调
          // 可实时绘制波形,实时上传(发送)数据
          if (this.wave) {
            this.wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate)
          }
        }
      })

      // 打开录音,获得权限
      this.rec.open(
        () => {
          console.log('录音已打开')
          if (this.$refs.recwave) {
            // 创建音频可视化图形绘制对象
            this.wave = Recorder.WaveView({ elem: this.$refs.recwave })
          }
        },
        (msg, isUserNotAllow) => {
          // 用户拒绝了录音权限,或者浏览器不支持录音
          console.log((isUserNotAllow ? 'UserNotAllow,' : '') + '无法录音:' + msg)
          // isUserNotAllow代表用户拒绝授权或浏览器不支持录音
          if (isUserNotAllow) {
            this.msgError('无法录音:' + msg)
          } else {
            // 设备不支持
            this.msgError('无法录音:' + '设备不支持')
          }
        }
      )
      // 权限请求被忽略
      window.waitDialogClick = () => {
        this.msgError('麦克风权限请求被忽略')
      }
      this.recorderDialogVisible = true
    },
    // 开始录音
    recStart() {
      this.flag = true
      if (!this.rec) {
        console.error('未打开录音')
        return
      }
      this.rec.start()
      console.log('已开始录音')
    },
    // 结束录音
    recStop() {
      if (!this.rec) {
        console.error('未打开录音')
        return
      }
      this.rec.stop(
        (blob, duration) => {
          // blob就是我们要的录音文件对象,可以上传,或者本地播放
          this.recBlob = blob
          // 简单利用URL生成本地文件地址,此地址只能本地使用,比如赋值给audio.src进行播放,赋值给a.href然后a.click()进行下载(a需提供download="xxx.mp3"属性)
          var localUrl = (window.URL || webkitURL).createObjectURL(blob)
          console.log('录音成功', blob, localUrl, '时长:' + duration + 'ms')
          this.size = blob.size // 文件字节大小
          this.upload(blob) // 把blob文件上传到服务器
          this.rec.close() // 关闭录音,释放录音资源,当然可以不释放,后面可以连续调用start
          this.rec = null
        },
        err => {
          console.error('结束录音出错:' + err)
          this.rec.close() // 关闭录音,释放录音资源,当然可以不释放,后面可以连续调用start
          this.rec = null
        }
      )
    },
    // blob流转换为base64
    blobToDataURI(blob, callback) {
      var reader = new FileReader()
      reader.readAsDataURL(blob)
      reader.onload = e => {
        callback(reader.result)
      }
    },

    upload(blob) {
      // blob格式再转换为base64格式 并且去头部
      this.blobToDataURI(blob, result => {
        var base64String = result
        this.recordBase64 = base64String.replace(/^data:audio\/\w+;base64,/, '') // 去掉base64位头部
      })

      this.main()
    },
    async main() {
      axios({
        url: 'https://vop.baidu.com/server_api',
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json'
        },
        data: {
          format: 'wav',
          rate: 16000,
          channel: 1,
          cuid: '', // KpvVkGmfdIohVMVI3awvua79
          token: await this.getAccessToken(),
          speech: this.recordBase64,
          len: this.size
        }
      })
        .then(res => {
          this.recordBase64 = ''
          this.params.searchText = res.data.result[0]
          this.recorderDialogVisible = false
          this.handleQuery()
          this.wave = null
          this.flag = false
        })
        .catch(error => {
          console.log('错误提示', error)
          this.recordBase64 = ''
          this.params.searchText = ''
          this.recorderDialogVisible = false
          this.wave = null
          this.flag = false
        })
    },

    /**
     * 使用 AK,SK 生成鉴权签名(Access Token)
     * @return string 鉴权签名信息(Access Token)
     */
    getAccessToken() {
      const request = require('request')
      const AK = '' // 百度云申请的
      const SK = '' // 百度云申请的
      const options = {
        method: 'POST',
        url:
          'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' +
          AK +
          '&client_secret=' +
          SK
      }
      return new Promise((resolve, reject) => {
        request(options, (error, response) => {
          if (error) {
            reject(error)
          } else {
            resolve(JSON.parse(response.body).access_token)
          }
        })
      })
    },
    onClose() {
      // 结束录音后关闭弹框把内容传到input框
      // 如果点了录音没有结束直接点击关闭弹框
      if (this.recordBase64 === '') {
        this.rec.close() // 关闭录音
        this.rec = null
        this.wave = null
        this.recorderDialogVisible = false
        this.flag = false
        return
      }
      if (!this.rec) {
        console.error('未打开录音')
      } else {
        this.rec.stop(
          (blob, duration) => {
            // blob就是我们要的录音文件对象,可以上传,或者本地播放
            this.recBlob = blob
            // 简单利用URL生成本地文件地址,此地址只能本地使用,比如赋值给audio.src进行播放,赋值给a.href然后a.click()进行下载(a需提供download="xxx.mp3"属性)
            var localUrl = (window.URL || webkitURL).createObjectURL(blob)
            this.size = blob.size
            this.rec.close() // 关闭录音,释放录音资源,当然可以不释放,后面可以连续调用start
            this.rec = null
          },
          err => {
            console.error('结束录音出错:' + err)
            this.rec.close() // 关闭录音,释放录音资源,当然可以不释放,后面可以连续调用start
            this.rec = null
          }
        )
      }
      this.wave = null
      this.recorderDialogVisible = false
      this.flag = false
    },
}

2. 业务场景是,把文字使用百度智能云的文本在线合成音频文件(文字转音频),进行播放。
js部分:

async playFullText() {
      // 合成参数
      const options = {
        per: 4, // 发音人,4代表度丫丫
        spd: 5, // 语速,取值0-9,默认为5中语速
        pit: 5, // 语调,取值0-9,默认为5中语调
        vol: 5 // 音量,取值0-15,默认为5中音量
      }
      const playAudio = audioUrl => {
        const audio = new Audio(audioUrl)
        audio.play()
      }
      axios({
        url: 'https://tsn.baidu.com/text2audio',
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          Accept: '*/*'
        },
        responseType: 'blob',
        params: {
          tex: '测试',
          tok: await this.getAccessToken(),
          cuid: '', // KpvVkGmfdIohVMVI3awvua79
          ctp: '1',
          lan: 'zh',
          spd: '5',
          pit: '5',
          vol: '5',
          per: '1',
          aue: '3'
        }
      })
        .then(res => {
          const audioData = res.data /* 二进制数据 */
          const blob = new Blob([audioData], { type: 'audio/mpeg' }) // 替换 'audio/mpeg' 为你的音频类型
          // 创建可供流式播放的 URL
          const audioUrl = URL.createObjectURL(blob)
          const audio = new Audio(audioUrl)
          audio.play()
        })
        .catch(error => {
          console.log('错误提示', error)
        })
    },
image.png
image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容