利用benz-amr-recorder开发语音发送窗口功能以及所遇到的坑

安装依赖

npm install benz-amr-recorder

html

<template>
<div class="voice_view">
        <p class="voice_view_star_tip" v-show="voice.type === 0">点击录音</p>
        <van-divider class="voice_view_ing_tip" dashed :hairline="false"  :style="{padding: '0',margin: '0' }" v-show="voice.type >= 1">
          <span v-if="voice.type === 3">{{voice.playLength | secondFormat}}/</span>
          <span>{{voice.length | secondFormat}}</span>
        </van-divider>
        <div class="voice_star">
          <!--off on stop play-->
          <div class="off" @click="offVoiceChange" v-if="voice.type === 0"></div>
          <div class="on" @click="onVoiceChange" v-else-if="voice.type === 1"></div>
          <div class="stop" @click="stopVoiceChange" v-else-if="voice.type === 2"></div>
          <div class="play" @click="playVoiceChange" v-else-if="voice.type === 3"></div>
        </div>
        <div class="voice_send van-slide-up" v-if="voice.type >= 2">
          <div class="voice_send_cancel" @click="onCancelVoice">取消</div>
          <div class="voice_send_ok" @click="onSendVoice">发送</div>
        </div>
      </div>
</template>

js

import BenzAMRRecorder from 'benz-amr-recorder'
export default {
  name: 'chatroom',
  data () {
    return {
      voice: {
        interval: null, // 录音定时器
        playInterval: null, // 播放录音定时器
        type: 0, // 0未录音 1录音中 2录音完毕 3回放录音
        length: 0, // 录音长度
        playLength: 0,// 当前播放长度
        src: null // 录音资源
      },
      amrRec: null, // 录音对象
      playRec: null // 播放对象
    }
  },
  filters: {
    secondFormat(val){
      let minute = Math.floor(val / 60),
        second = val % 60;
      return minute + ':'+ (second < 10 ? '0' + second : second)
    }
  },
  methods: {
    // 录音面板操作-开始录音
    offVoiceChange(){
      this.amrRec = new BenzAMRRecorder();
      this.amrRec.initWithRecord().then(() => {
        this.amrRec.startRecord();
        this.voice.interval = setInterval(() => {
          this.voice.length++
        }, 1000)
        this.voice.type = 1
      }).catch((e) => {
        alert(e)
        this.$notify('录音失败,请检查相关权限和设备')
      })
    },
    // 录音面板操作-结束录音
    onVoiceChange(){
      clearInterval(this.voice.interval)
      // 当前不是在录音,可能快速点击开始并且同时快速点击了结束
      if (!this.amrRec.isRecording()) {
        return this.$notify('操作频繁')
      }
      this.amrRec.finishRecord().then(() => {
        if (this.voice.length === 0) {
          this.voice.type = 0
          this.voice.length = 0
          // 放弃录音
          this.amrRec.cancelRecord()
          this.$notify({
            type: 'warning',
            message: '录音时间较短'
          })
        } else {
          // 获取音频时长
          this.voice.length = Math.ceil(this.amrRec.getDuration())
          // 获取音频文件
          this.voice.src = this.amrRec.getBlob()
          this.voice.type = 2
        }
      }).catch(() => {
        this.$notify('录音失败,请检查相关权限')
      })
    },
    // 录音面板操作-播放录音
    stopVoiceChange() {
      // 先停止正在播放的音频
      if (this.playRec !== null) {
        this.stopPlayVoice()
      }
      this.voice.playInterval = setInterval(() => {
        if (this.voice.playLength === this.voice.length) {
          this.playVoiceChange()
        } else {
          this.voice.playLength++
        }
      }, 1000)
      this.playRec = new BenzAMRRecorder();
      this.playRec.initWithBlob(this.voice.src).then(()=> {
        this.playRec.play();
      }).catch((e) => {
        alert(e)
        this.$notify('播放录音失败')
      });
      this.voice.type = 3
    },
    // 录音面板操作-停止播放
    playVoiceChange() {
      clearInterval(this.voice.playInterval);
      this.voice.playLength = 0;
      this.voice.type = 2;
      this.stopPlayVoice();
    },
    // 发送语音
    onSendVoice(){
    },
    // 取消语音
    onCancelVoice(){
      clearInterval(this.voice.playInterval)
      this.voice.playLength = 0
      this.voice.type = 0
      this.voice.length = 0
      this.voice.src = null
      this.stopPlayVoice()
    },
    // 停止播放
    stopPlayVoice(){
      if (this.playRec.isPlaying()){
        this.playRec.stop()
      }
    }
  }
}

less

    /*语音*/
    &>.voice_view{
      height: 220px;
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      &>p{
        color: #bababa;
        line-height: 10px;
      }
      .voice_view_ing_tip{
        width: 120px;
        /*border-width: 2px;*/
      }
      &>.voice_star{
        width: 90px;
        height: 90px;
        border-radius: 100%;
        padding: 10px;
        box-shadow: rgba(0, 0, 0, 0.1) 0 3px 3px;
        display: flex;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        &>div{
          transition: all 400ms;
        }
        &>.off{
          width: 100%;
          height: 100%;
          background: linear-gradient(right, #ff1315, #ff5356);
          border-radius: 100%;
        }
        &>.on{
          width: 50%;
          height: 50%;
          background: linear-gradient(right,#ff1315, #ff5356);
          border-radius: 10%;
        }
        &>.stop{
          display: inline-block;
          font-size: 0;
          overflow: hidden;
          transform: translateX(5px);
          &:before{
            content: "";
            position: relative;
            display: inline-block;
            border: 20px solid transparent;
          }
          position: relative;
          right: 2px;
          border-top-right-radius: 50%;
          border-bottom-right-radius: 50%;
          &:before{
            left: 2px;
            border-right-width: 0;
            border-left-width: 40px;
            border-left-color: #5c5f5e;
          }
        }
        .play{
          width: 50%;
          height: 50%;
          background: linear-gradient(right, #4a4b4b, #5f5f61);
          border-radius: 10%;
        }
        &:active{
          opacity: 0.8;
        }
      }
      /*发送*/
      &>.voice_send{
        width: 100%;
        height: 35px;
        margin-top: 10px;
        display: flex;
        justify-content: center;
        &>div{
          width: 40%;
          height: 100%;
          border-radius: 5px;
          text-align: center;
          line-height: 35px;
          &:active{
            opacity: 0.8;
          }
        }
        &>.voice_send_cancel{
          background: #d1d1d1;
          margin-right: 2%;
        }
        &>.voice_send_ok{
          color: #ffffff;
          background: #0CAAED;
          margin-right: 2%;
        }
      }
    }

注意点

1.van-divider是vant的组件,改为div即可,这个不多说

2.this.$notify(’’)这是vant的提示组件,改为alert即可,这个不多说

3.benz-amr-recorder中的api,不能通过if,switch去判断再执行,必须每个事件写一个方法,如有if一定要用‘卫语句‘,否则报错 语法不执行等一系列问题

4.描述第三点的坑:前后对比


5.benz-amr-recorder官方文档

https://www.npmjs.com/package/benz-amr-recorder

6.文档有描述播放本地音频的细节,我没写细节因为我最终是线上地址

效果图




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值