自学内容网 自学内容网

【语音评测】开启英文口语学习新纪元

在全球化的今天,英语作为国际通用语言,其重要性不言而喻。然而,对于许多学习者来说,英语口语的学习却成为了一道难以逾越的鸿沟。传统的学习方法往往依赖于教师的主观评价和有限的练习机会,导致学习效率低下,进步缓慢。幸运的是,随着人工智能技术的飞速发展,语音评测技术应运而生,为英文口语学习带来了革命性的变化。

语音评测技术,通过机器自动对发音进行评分、检错并给出矫正指导,不仅弥补了人工评测的主观性和低效性,更为学习者提供了一个实时、准确、个性化的学习反馈机制。这一技术的应用,使得英文口语学习不再受限于时间和空间,学习者可以随时随地进行自我练习和评估,大大提高了学习的便捷性和灵活性。

以驰声团队为例,他们自2007年起就致力于将先进的语音技术应用于教育领域,经过多年的研发和实践,已经形成了一套完善的中英文口语评测体系。该体系不仅能够模拟母语专家的打分,还能够根据学习者的具体情况提供个性化的学习建议和辅导,帮助学习者更快地掌握正确的发音技巧,提升口语表达能力。

在实际应用中,语音评测技术的优势更加明显。它可以实现大规模、高频次、高效率的口语练习,大幅降低师资和时间成本。同时,结合大数据智能分析,语音评测技术还可以量化学情,协助教师精准督学、导学,让学习者在AI的辅导下快速提高口语发音能力。此外,语音评测技术还具有丰富的应用场景和题型设计,如单词发音练习、纠音、背诵和看图说词等,旨在帮助学习者全面提升口语能力。

值得一提的是,语音评测技术还具有强大的互动性。通过即时评分和游戏化设计,学习者可以在轻松愉快的氛围中进行口语练习,不再感到枯燥乏味。这种寓教于乐的方式,不仅提高了学习者的兴趣和积极性,还促进了知识的内化和习得效率。

总之,语音评测技术的出现,为英文口语学习带来了前所未有的便利和效率。它不仅解决了传统学习方法中的诸多痛点,还为学习者提供了一个全新的学习体验。在未来的日子里,随着技术的不断进步和应用范围的不断扩大,我们有理由相信,语音评测技术将成为英文口语学习的主流方式之一,引领学习者走向更加广阔的世界舞台。

实现源码:
 

<template>
  <div class="Evaluate-container">
    <!--    评测题型列表 -->
    <div>
      <!--第一行-->
      <el-row :gutter="10" style="border-bottom: 1px dashed grey">
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/12.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              中文字评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: dodgerblue;color: white">
                普通话
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">小学群体</span>
              <br>
              <el-radio v-model="radio" label="cn_vip+read_syllable">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/12.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              中文词语评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: dodgerblue;color: white">
                普通话
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">小学/初中</span>
              <br>
              <el-radio v-model="radio" label="cn_vip+read_word">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/12.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              中文句子评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: dodgerblue;color: white">
                普通话
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">高中群体</span>
              <br>
              <el-radio v-model="radio" label="cn_vip+read_sentence">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/12.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              中文篇章评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: dodgerblue;color: white">
                普通话
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">高中/大学</span>
              <br>
              <el-radio v-model="radio" label="cn_vip+read_chapter">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <!--        <el-col :span="4">
                  <el-card style="height: 102px;">
                    <img src="../css_assets/9.png" style="width: 15%">
                    <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
                      男生飞哲<br>
                      <span
                          style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: dodgerblue;color: white">
                        普通话
                      </span>
                      <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">成年男生</span>
                      <br>
                      <el-radio v-model="radio" label="x4_lingfeizhe_oral">使用</el-radio>
                    </div>
                  </el-card>
                </el-col>
                <el-col :span="4">
                  <el-card style="height: 102px;">
                    <img src="../css_assets/8.png" style="width: 15%">
                    <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
                      女生小琪<br>
                      <span
                          style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: dodgerblue;color: white">
                        普通话
                      </span>
                      <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">成年女生</span>
                      <br>
                      <el-radio v-model="radio" label="x4_lingxiaoqi_oral">使用</el-radio>
                    </div>
                  </el-card>
                </el-col>-->
      </el-row>
      <br>
      <!--第二行-->
      <el-row :gutter="10" style="border-bottom: 1px dashed grey">
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文单词评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                英文
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">小学/初中</span>
              <br>
              <el-radio v-model="radio" label="en_vip+read_word">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文句子评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                英文
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">初中/高中</span>
              <br>
              <el-radio v-model="radio" label="en_vip+read_sentence">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文篇章评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
               英文
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">高中/大学</span>
              <br>
              <el-radio v-model="radio" label="en_vip+read_chapter">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文选择评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                英文
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">高中/大学</span>
              <br>
              <el-radio v-model="radio" label="en_vip+read_choice">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文复述评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                英文
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">通用</span>
              <br>
              <el-radio v-model="radio" label="en_vip+retell">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文自由评测<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                        英文
                      </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">通用</span>
              <br>
              <el-radio v-model="radio" label="en_vip+topic">使用</el-radio>
            </div>
          </el-card>
        </el-col>
      </el-row>
      <br>
      <!--第三行-->
      <el-row :gutter="10" style="border-bottom: 1px dashed grey">
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文口头翻译<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                英文
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">通用</span>
              <br>
              <el-radio v-model="radio" label="en_vip+oral_translation">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文情景反应<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                英文
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">通用</span>
              <br>
              <el-radio v-model="radio" label="en_vip+simple_expression">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/13.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              英文看图说话<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                       英文
                      </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">通用</span>
              <br>
              <el-radio v-model="radio" label="en_vip+picture_talk">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <!--        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/5.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              男童宁宁<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                儿童场景
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">男童男声</span>
              <br>
              <el-radio v-model="radio" label="x4_ningning">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/5.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              男童楠楠<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                儿童场景
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">男童男声</span>
              <br>
              <el-radio v-model="radio" label="x4_nannan">使用</el-radio>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card style="height: 102px;">
            <img src="../css_assets/6.png" style="width: 15%">
            <div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
              女童璜璜<br>
              <span
                  style="padding-left: 5px;padding-right: 5px;  font-size: 12px;background-color: orangered;color: white">
                儿童场景
              </span>
              <span style="margin-left: 10px;font-size: 12px;color: #409EFF;">女童女声</span>
              <br>
              <el-radio v-model="radio" label="x4_xiaofang">使用</el-radio>
            </div>
          </el-card>
        </el-col>-->
      </el-row>
    </div>
    <br>
    <!--  合成文本区域  -->
    <div>
      <el-input type="textarea" v-model="iseContent" rows="15"
                style="font-family: 'Microsoft YaHei';font-size: medium;font-weight: bold"
                :maxlength="2000" show-word-limit placeholder="请输入不超过2000个汉字的文本进行合成">
      </el-input>
    </div>
    <br>
    <!--  按钮区域  -->
 
  </div>
</template>
<script>
// 听写个性化开始!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
import CryptoJS from '../js_util/crypto-js/crypto-js.js'
import Recorder from '../../public/recorder/index.umd.js'
import * as base64 from 'js-base64'
import parser from '../../public/fast-xml-parser/src/parser'
 
function toBase64(buffer) {
  var binary = "";
  var bytes = new Uint8Array(buffer);
  var len = bytes.byteLength;
  for (var i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  return window.btoa(binary);
};
 
// 初始化录音工具,注意目录
let recorder = new Recorder("../../recorder")
recorder.onStart = () => {
  console.log("开始录音了")
}
recorder.onStop = () => {
  console.log("结束录音了")
  // 拿听写结果去请求大模型
}
 
let wsFlag = false;
let wsTask = {};
 
recorder.onFrameRecorded = ({isLastFrame, frameBuffer}) => {
  // alert("执行了...")
  // console.log(isLastFrame, frameBuffer)
  if (!isLastFrame && wsFlag) { // 发送中间帧
    const params = {
      data: {
        status: 1,
        format: "audio/L16;rate=16000",
        encoding: "raw",
        audio: toBase64(frameBuffer),
      },
    };
    // console.log("发送中间帧", params, wsFlag)
    wsTask.send(JSON.stringify(params)) // 执行发送
  } else {
    if (wsFlag) {
      const params = {
        data: {
          status: 2,
          format: "audio/L16;rate=16000",
          encoding: "raw",
          audio: "",
        },
      };
      console.log("发送最后一帧", params, wsFlag)
      wsTask.send(JSON.stringify(params)) // 执行发送
    }
  }
}
// 听写个性化配置结束!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
export default {
  data() {
    return {
      URL: 'wss://ise-api.xfyun.cn/v2/open-ise', // 评测地址
      radio: 'cn_vip+read_syllable', // 单选项
      iseContent: "欢迎使用评测",
      iseResult: "",
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
    }
  },
  watch: { // 这个场景watch 就是监听各个评测题型对应的值变化
    radio(newVal, oldVal) {
      if (newVal == "x4_EnUs_Lila_emo" || newVal == "x4_EnUs_Grant_emo") {
        this.iseContent = "Welcome to use the text-to-speech function to make your words sound beautiful.";
      } else {
        this.iseContent = "欢迎使用拟真人发音功能,让你的文字发出和真人一样的声音。";
      }
    }
  },
  methods: {
    // 结束录音
    stopRecorder() {
      recorder.stop();
      _this.$message.success("实时录音停止,报警自动上报,请稍后!")
      /*  this.$message.success("实时录音停止,报警内容将通过大模型自动识别上报!")
        this.$http.post("/big/big_model", this.iatRes).then(res => {
          console.log(res);
        })*/
    },
    // 建立ws连接
    async wsInit() {
      this.$message.success("请开始朗读对应评测文本...")
      let _this = this;
      if (typeof (WebSocket) == 'undefined') {
        console.log('您的浏览器不支持ws...')
      } else {
        console.log('您的浏览器支持ws!!!')
        let reqeustUrl = await _this.getWebSocketUrl()
        wsTask = new WebSocket(reqeustUrl);
        // ws的几个事件,在vue中定义
        wsTask.onopen = function () {
          console.log('ws已经打开...')
          wsFlag = true
          let params = { // 第一帧数据
            common: {
              app_id: _this.APPID
            },
            business: {
              language: "zh_cn",
              domain: "iat",
              accent: "mandarin",
              vad_eos: 6000,
              dwa: "wpgs",
            },
            data: {
              status: 0,
              format: "audio/L16;rate=16000",
              encoding: "raw",
            },
          };
          console.log("发送第一帧数据...")
          wsTask.send(JSON.stringify(params)) // 执行发送
          // 下面就可以循环发送中间帧了
          // 开始录音
          console.log("开始录音")
          recorder.start({
            sampleRate: 16000,
            frameSize: 1280,
          });
        }
        wsTask.onmessage = function (message) { // 调用第二个API 自动把语音转成文本
          // console.log('收到数据===' + message.data)
          let jsonData = JSON.parse(message.data);
          if (jsonData.data && jsonData.data.result) {
            let data = jsonData.data.result;
            let str = "";
            let ws = data.ws;
            for (let i = 0; i < ws.length; i++) {
              str = str + ws[i].cw[0].w;
            }
            // 开启wpgs会有此字段(前提:在控制台开通动态修正功能)
            // 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段
            if (data.pgs) {
              if (data.pgs === "apd") {
                // 将resultTextTemp同步给resultText
                _this.resultText = _this.resultTextTemp;
              }
              // 将结果存储在resultTextTemp中
              _this.resultTextTemp = _this.resultText + str;
            } else {
              _this.resultText = _this.resultText + str;
            }
            _this.iatRes = _this.resultTextTemp || _this.resultText || "";
          }
          // 检测到结束或异常关闭
          if (jsonData.code === 0 && jsonData.data.status === 2) { // 拿到最终的听写文本后,我们会调用大模型
            // alert("执行了")
            recorder.stop();
            _this.$message.success("检测到您6秒没说话,报警自动结束上报,请稍后!")
            let iatContent = {};
            iatContent.content = _this.iatRes;
            iatContent.ing = _this.ing;
            iatContent.iat = _this.iat;
            _this.$http.post("/big/big_model", iatContent).then(res => {
              console.log(res);
              if (res.data.code === "200") {
                _this.modelRes = res.data.object;
                _this.$message.success("报警成功,警员将尽快赶到!")
              } else {
                // console.log(res.data)
                _this.$message.error(res.data.message);
              }
            })
            wsTask.close();
            wsFlag = false
          }
          if (jsonData.code !== 0) {
            wsTask.close();
            wsFlag = false
            console.error(jsonData);
          }
        }
        // 关闭事件
        wsTask.onclose = function () {
          console.log('ws已关闭...')
        }
        wsTask.onerror = function () {
          console.log('发生错误...')
        }
      }
    },
    // 获取鉴权地址与参数
    getWebSocketUrl() {
      return new Promise((resolve, reject) => {
        // 请求地址根据语种不同变化
        var url = this.URL;
        var host = "ise-api.xfyun.cn";
        var apiKeyName = "api_key";
        var date = new Date().toGMTString();
        var algorithm = "hmac-sha256";
        var headers = "host date request-line";
        var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/open-ise HTTP/1.1`;
        var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, this.APISecret);
        var signature = CryptoJS.enc.Base64.stringify(signatureSha);
        var authorizationOrigin =
            `${apiKeyName}="${this.APIKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
        var authorization = base64.encode(authorizationOrigin);
        url = `${url}?authorization=${authorization}&date=${encodeURI(date)}&host=${host}`;
        // console.log(url)
        resolve(url); // 主要是返回地址
      });
    },
  }
}
</script>
 
<style scoped>
</style>


原文地址:https://blog.csdn.net/p6448777/article/details/145244665

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!