【语音评测】开启英文口语学习新纪元
在全球化的今天,英语作为国际通用语言,其重要性不言而喻。然而,对于许多学习者来说,英语口语的学习却成为了一道难以逾越的鸿沟。传统的学习方法往往依赖于教师的主观评价和有限的练习机会,导致学习效率低下,进步缓慢。幸运的是,随着人工智能技术的飞速发展,语音评测技术应运而生,为英文口语学习带来了革命性的变化。
语音评测技术,通过机器自动对发音进行评分、检错并给出矫正指导,不仅弥补了人工评测的主观性和低效性,更为学习者提供了一个实时、准确、个性化的学习反馈机制。这一技术的应用,使得英文口语学习不再受限于时间和空间,学习者可以随时随地进行自我练习和评估,大大提高了学习的便捷性和灵活性。
以驰声团队为例,他们自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)!