vue对接百度api实现语音识别

必备插件 js-audio-recorder

父级界面

<template>
  <div class="kfMain">
    <div class="back"><van-icon name="cross" color="#fff" @click="back" /></div>
    <van-image
      width="10rem"
      height="10rem"
      fit="contain"
      :src="kfImg"
      class="img-kf"
    />
    <div class="bk-card">
      <div class="content">
        <h2>{{ message }}</h2>
        <div class="prompt" v-if="!messageInfo">{{ prompt }}</div>
        <div class="result"  v-if="messageInfo">{{ messageInfo }}</div>
        <div class="result-button" v-if="messageInfo">
          <van-row
            ><van-col :span="12"
              ><span class="result-button1" @click="cleanInfo"
                >清空</span
              > </van-col
            ><van-col :span="12"
              ><span class="result-button2" @click="getRun">发送</span>
            </van-col></van-row
          >
        </div>
        <ul class="aubox" v-if="avdioitem">
          <li class="au1 auItem"></li>
          <li class="au2 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
          <li class="au3 auItem"></li>
          <li class="au4 auItem"></li>
          <li class="au5 auItem"></li>
          <li class="au6 auItem"></li>
          <li class="au7 auItem"></li>
        </ul>

        <div style="text-align: center">
          <recording
            @getAudio="getAudio"
            @getResult="getResult"
            ref="child"
          ></recording>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Recorder from "js-audio-recorder";
import moment from "moment";
import recording from "../components/recording";
export default {
  components: { recording },

  data() {
    return {
      recorder: null,
      playTime: 0,
      timer: null,
      src: null,
      kfImg: require("../../../assets/images/kfs.png"),
      kfmk: require("../../../assets/images/kfmk.png"),

      message: "AI助手在听,请提问",
      prompt: "请点击下方按钮开始",
      items: "开始",
      isStart: false,
      avdioitem: false, //是否显示音频波纹
      messageInfo: null,
    };
  },
  created() {},
  methods: {
    back() {
      this.$router.go(-1);
    },
    getResult(value) {
      this.messageInfo = value;
    },
    getAudio() {
      this.avdioitem = !this.avdioitem;
    },
    cleanInfo() {
      this.messageInfo = null;
      this.$refs.child.cleanMessage();
    },
    getRun() {
      this.$router.push({
        path: "/xxx",
       
      });
    },
  },
};
</script>
<style scoped  lang="scss">
.kfMain {
  .back {
    width: 100%;
    text-align: right;
    margin: 0 -10px;
    padding: 10px 0;
  }
  height: 100vh;
  background: linear-gradient(90deg, #00d1ed, #00b5ff, #1890ff);
  .img-kf {
    position: absolute;
    bottom: 280px;
  }
  .bk-card {
    margin: 0 auto;
    height: 300px;
    position: flex;
    bottom: 0px;

    padding: 10px;
    position: fixed;
    .content {
      background: #fff;
      border-radius: 10px;
      height: 300px;
      width: calc(100vw - 20px);
      h2 {
        font-size: 18px;
        text-align: center;
        padding-top: 30px;
      }
      .prompt {
        padding: 20px 0;
        font-size: 14px;
        text-align: center;
        color: #666;
      }
    }
  }
}

.result {
  padding: 10px;
  height: 190px;
}
.result-button {
  text-align: center;
  .result-button1 {
    color: #888;
  }
  .result-button2 {
    color: #1890ff;
  }
}

.aubox {
  display: flex;
  align-items: flex-end; //重要属性,让hight翻转过来,往上延伸
  justify-content: center;
}
.auItem {
  width: 1px;
  margin-right: 5px;
  list-style: none;
  background: black;
  height: 20px;
}
.au1 {
  animation: audio 0.5s linear 0.1s infinite alternate;
}
.au2 {
  animation: audio 0.5s linear 0.2s infinite alternate;
}
.au3 {
  animation: audio 0.5s linear 0.5s infinite alternate;
}
.au4 {
}
.au5 {
  animation: audio 0.5s linear 0.2s infinite alternate;
}
.au6 {
  animation: audio 0.5s linear 0.3s infinite alternate;
}
.au7 {
  animation: audio 0.5s linear 0.1s infinite alternate;
}
@keyframes audio {
  from {
    height: 1px;
  }
  to {
    height: 20px;
  }
}
</style>




子组件recording.vue

<template>
  <div class="recordPlagin">
    <div v-if="yxsbPlay">
      <div class="mask" v-if="yingPingDisPlay">
        <span>正在听,松开进行搜索!</span>
      </div>
      <div
        @touchstart="gtouchstart()"
        @touchend="gtouchend()"
        style="background-image: linear-gradient(#FE4C6B, #FE4C6B); font-weight: bold; border-radius: 20px; display: flex;align-items: center;color: #fff; center;padding: 5px 2%;width: 30%;margin: 10px 33%;justify-content: space-evenly;"
      >
        <img
          style="width: 20px; height: 20px"
          :src="buttonImg"
          v-if="!yingPingDisPlay"
        />
        <img style="width: 20px; height: 20px" :src="buttonImg2" v-else />
        <div>{{ viodeText }}</div>
      </div>
    </div>
  </div>
</template>
<script>
import Recorder from "js-audio-recorder";
import axios from "axios";
import Config from "../utils/setting";
export default {
  data() {
    return {
      viodeText: "长按说话",
      search: "",
      yingPingDisPlay: false,
      buttonImg: require("../../../assets/images/kfmk1.png"),
      buttonImg2: require("../../../assets/images/kfmk2.png"),
      recorder: null,
      Tolsize: null, //录音大小
      yxsbPlay: true,
      resultMessage: "",
    };
  },
  created() {
    if (!localStorage.getItem("ai_access_token")) {
      axios
        .post(
          `/api/oauth/2.0/token?grant_type=client_credentials&client_id=${Config.client_id}&client_secret=${Config.client_secret}`
        )
        .then((res) => {
          localStorage.setItem("ai_access_token", res.data.access_token);
        })
        .catch((e) => {});
    } else {
    }
    this.recorder = new Recorder({
      sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
      sampleRate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
      numChannels: 1, // 声道,支持 1 或 2, 默认是1
      // compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换,默认是false
    });
    // 绑定事件-打印的是当前录音数据
    this.recorder.onprogress = function (params) {
      // alert('--------------START---------------')
      // alert('录音时长(秒)', params.duration);
      // alert('录音大小(字节)', params.fileSize);
      // alert('录音音量百分比(%)', params.vol);
      // alert('当前录音的总数据([DataView, DataView...])', params.data);
      // alert('--------------END---------------')
    };
  },
  mounted() {
    //获取录音权限
    Recorder.getPermission().then(
      () => {
        // this.$vux.toast.text('获取权限成功', 'top');
      },
      (error) => {
        alert(`${error.name} : ${error.message}`);
      }
    );
  },
  methods: {
    gtouchstart() {
      // this.viodeText = '松开搜索'
      //   (this.buttonImg = require("../../../assets/images/kfmk1.png"))
      this.startRecorder();
      this.yingPingDisPlay = true;
      this.$emit("getAudio");
    },
    gtouchend(event) {
      this.yingPingDisPlay = false;
      // this.viodeText = '长按说话'
      //   this.buttonImg = require("../../../assets/images/kfmk2.png");
      this.stopRecorder();
      this.getRecorder();
      // this.getAudio();
    
      this.$emit("getAudio");
    },
    //开始录音
    startRecorder() {
      this.recorder.start().then(
        () => {},
        (error) => {
          // 出错了
          alert(`${error.name} : ${error.message}`);
        }
      );
    },
    // 结束录音
    stopRecorder() {
      this.recorder.stop();
    },

    cleanMessage() {
      this.yxsbPlay = true;
    },
    //获取onload里面的录音信息
    getRecordInfo(e) {
      var that = this;
      let wavValue = e.split("base64,")[1];
      var data = {
        cuid: "keinfo_str_12456", //用户唯一标识,用来区分用户,计算UV值。建议填写能区分用户的机器 MAC 地址或 IMEI 码,长度为60字符以内。
        token: localStorage.getItem("ai_access_token"), //开放平台获取到的开发者[access_token]获取 Access Token "access_token")
        SourceType: 1, //语音数据
        format: "wav", //识别音频的音频格式。
        speech: wavValue,
        channel: 1, //声道数,仅支持单声道,请填写固定值 1
        len: this.Tolsize, //本地语音文件的的字节数,单位字节
        rate: 16000, //采样率,16000、8000,固定值s
      };
      axios
        .post("/vopapi/server_api", data)
        .then((res) => {
          console.log(res.data.result[0]);

          this.recorder.destroy(); // 毁实例
          if (res.data.result[0]) {
            this.resultMessage = res.data.result[0];
            this.yxsbPlay = false;
            this.$emit("getResult", this.resultMessage);
          }
        })
        .catch((e) => {
          console.log("失败了");
          this.recorder.destroy(); // 毁实例
        });
    },
    //获取录音wav
    getRecorder() {
      let toltime = this.recorder.duration; //录音总时长
      let fileSize = this.recorder.fileSize; //录音总大小

      var wav = this.recorder.getWAVBlob(); //获取 WAV 数据

      this.Tolsize = wav.size;
      var reader = new FileReader();
      reader.readAsDataURL(wav);
      this.search = "";
      reader.onload = () => {
        this.search = reader.result;

        //调用其他方法
        this.getRecordInfo(this.search, "");
      };
    },
  },
};
</script>
<style scoped lang="scss">
.recordPlagin {
  position: fixed;
  bottom: 50px;
  width: 100%;
  .mask {
    margin-bottom: 35px;
    img {
      width: 100%;
    }
    span {
      display: flex;
      justify-content: center;
      opacity: 0.5;
    }
  }
  .buttonImg {
    width: 135px;
    height: 37.44px;
    background-size: 100% 100%;
    margin: auto;
  }
}
</style>

注:百度ai接口需自己制作代理 。 具体逻辑根据自己需求修改 文中icon可私信免费领取,如有需要请私信。

可开发app h5 pc web端 微信小程序 微信公众号等项目 指导毕设等 拥有5年一线开发经验  如有需要私信联系

感谢你的关注。觉得有用点个赞吧!!!!!!!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值