基于阿里云微信小程序语音识别

页面效果
在这里插入图片描述
其中采用阿里云语音识别:阿里云一句话语音识别

语音识别页面


<template><view><view class="chat_list"><view v-for="v in chatList" :class="v.type == 'right' ? 'type_right' : 'type_left'"><chat :text="v.result" :type="v.type"></chat></view></view><view :class="longPress == '1' ? 'record-layer' : 'record-layer1'"><view :class="longPress == '1' ? 'record-box' : 'record-box1'"><view class="record-btn-layer flex_row"><button v-show="longPress == '1'" class="record-btn-cir" @click="isKeyWord = !isKeyWord"><image v-if="!isKeyWord" :src="keyword" style=" margin-top: -8rpx;" /><image v-else :src="record" style=" margin-top: -8rpx;" /></button><button v-show="!isKeyWord" class="record-btn":class="longPress == '1' ? 'record-btn-1' : 'record-btn-2'":style="VoiceTitle != '松开手指,取消发送' && longPress != '1' ? 'background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%);' : 'background-color: rgba(0, 0, 0, .5);color:white'"@longpress="longpressBtn" @touchend="touchendBtn()" @touchmove="handleTouchMove"><image :src="record" /><text>{{ VoiceText }}</text></button><u--input v-if="longPress == '1' && isKeyWord" shape="circle" customStyle="u_input" clearableplaceholder="请输入内容..." @confirm="confirmMsg"></u--input></view><!-- 语音音阶动画 --><view :class="VoiceTitle != '松开手指,取消发送' ? 'prompt-layer prompt-layer-1' : 'prompt-layer1 prompt-layer-1'"v-if="longPress == '2'"><view class="prompt-loader"><view class="em" v-for="(item, index) in 15" :key="index"></view></view><text class="span">{{ VoiceTitle }}</text></view></view></view></view>
</template><script>
const recorderManager = uni.getRecorderManager()
const SpeechRecognition = require("../../utils/sr")
const getToken = require("../../utils/token").getToken
import keyword from '../public/images/keyword.png'
import record from '../public/images/record.png'
import chat from './com/chat.vue'
export default {components: { chat },data() {return {record,keyword,longPress: '1', // 1显示 按住 说话 2显示 说话中delShow: false, // 删除提示框显示隐藏time: 0, //录音时长duration: 60000, //录音最大值ms 60000/1分钟tempFilePath: '', //音频路径startPoint: {}, //记录长按录音开始点信息,用于后面计算滑动距离。sendLock: true, //发送锁,当为true时上锁,false时解锁发送VoiceTitle: '松手结束录音',VoiceText: '按住 说话',token: "",srStart: false,srResult: {},sr: null,isKeyWord: false,chatList: []}},async onLoad() {recorderManager.onFrameRecorded((res) => {if (this.sr && this.srStart) {if (res.frameBuffer) {console.log("send " + res.frameBuffer.byteLength)this.sr.sendAudio(res.frameBuffer)}}})recorderManager.onStop(async (res) => {if (this.sendLock) {//上锁不发送} else {//解锁发送,发送网络请求if (res.duration < 1000) {wx.showToast({title: "录音时间太短",icon: "none",duration: 1000});await this.sr.close()this.srStart = false}else {// this.tempFilePath = res.tempFilePathawait this.sr.close()this.srStart = falsethis.srResult.payload.type = 'right'this.chatList.push(this.srResult.payload)console.log('this.chatList.', this.chatList);}}})try {let token = await getToken('your akid','your akkey')this.token = token} catch (e) {console.log("error on get token:", JSON.stringify(e))}},onUnload: function () {this.srStart = falserecorderManager.stop()if (this.sr) {this.sr.shutdown()}},methods: {initSt() {const sr = new SpeechRecognition({url: 'wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1',appkey: 'your app key',token: this.token})console.warn("sr 初始化成功")sr.on("started", (msg) => {console.log("Client recv started", JSON.parse(msg))})sr.on("changed", (msg) => {console.log("Client recv changed:", JSON.parse(msg))this.srResult = JSON.parse(msg)})sr.on("completed", (msg) => {console.log("Client recv completed:", JSON.parse(msg))this.srResult = JSON.parse(msg)})sr.on("failed", (msg) => {console.log("Client recv failed:", JSON.parse(msg))})sr.on("closed", () => {console.error("sr 连接已关闭")})this.sr = sr},// 长按录音事件async longpressBtn(e) {recorderManager.start({duration: 600000,numberOfChannels: 1,sampleRate: 16000,format: "PCM",frameSize: 4})this.initSt()this.startPoint = e.touches[0];//记录长按时开始点信息,后面用于计算上划取消时手指滑动的距离。this.longPress = '2';this.VoiceText = '说话中...';if (!this.sr || this.srStart) {return}try {await this.sr.start(this.sr.defaultStartParams())this.srStart = true} catch (e) {console.log("start failed:" + e)return}// 监听音频开始事件this.sendLock = false;//长按时是不上锁的。},// 长按松开录音事件touchendBtn() {this.longPress = '1';this.VoiceText = '按住 说话';this.VoiceTitle = '松手结束录音'recorderManager.stop();},// 删除录音handleTouchMove(e) {//touchmove时触发var moveLenght = e.touches[e.touches.length - 1].clientY - this.startPoint.clientY; //移动距离if (Math.abs(moveLenght) > 70) {this.VoiceTitle = "松开手指,取消发送";this.VoiceText = '松开手指,取消发送';this.delBtn()this.sendLock = true;//触发了上滑取消发送,上锁} else {this.VoiceTitle = "松手结束录音";this.VoiceText = '松手结束录音';this.sendLock = false;//上划距离不足,依然可以发送,不上锁}},delBtn() {this.delShow = false;this.time = 0// this.tempFilePath = '';// this.VoiceTitle = '松手结束录音'},}
}
</script><style lang="scss">
/* 语音录制开始--------------------------------------------------------------------- */
.record-layer {width: 91vw;box-sizing: border-box;height: 15vw;position: fixed;margin-left: 4vw;z-index: 10;bottom: 2vh;
}.record-layer1 {width: 100vw;box-sizing: border-box;height: 100vh;position: fixed;background-color: rgba(0, 0, 0, .6);z-index: 10;bottom: 0vh;
}.record-box {width: 100%;position: relative;
}.record-box1 {width: 100%;position: relative;bottom: -83vh;height: 17vh;
}.record-btn-layer {// width: 100%;
}.record-btn-layer button::after {border: none;transition: all 0.1s;
}.record-btn-layer button {font-size: 14px;line-height: 40px;width: 100%;height: 40px;text-align: center;transition: all 0.1s;
}.record-btn-layer button image {width: 16px;height: 16px;margin-right: 4px;vertical-align: middle;transition: all 0.3s;
}.record-btn-layer .record-btn-2 {border-radius: 168rpx 168rpx 0 0;height: 17vh;line-height: 17vh;transition: all 0.3s;
}/* 提示小弹窗 */
.prompt-layer {border-radius: 15px;background: #95EB6C;padding: 8px 16px;box-sizing: border-box;position: absolute;left: 50%;height: 11vh;transform: translateX(-50%);transition: all 0.3s;
}.prompt-layer::after {content: '';display: block;border: 12px solid rgba(0, 0, 0, 0);border-radius: 10rpx;border-top-color: #95EB6C;position: absolute;bottom: -46rpx;left: 50%;transform: translateX(-50%);transition: all 0.3s;
}//取消动画
.prompt-layer1 {border-radius: 15px;background: #FB5353;padding: 8px 16px;box-sizing: border-box;position: absolute;left: 50%;height: 11vh;transform: translateX(-50%);transition: all 0.3s;
}.prompt-layer1::after {content: '';display: block;border: 12px solid rgba(0, 0, 0, 0);border-radius: 10rpx;border-top-color: #FB5353;position: absolute;bottom: -46rpx;left: 50%;transform: translateX(-50%);transition: all 0.3s;
}.prompt-layer-1 {font-size: 12px;width: 150px;text-align: center;display: flex;flex-direction: column;align-items: center;justify-content: center;top: -400rpx;
}.prompt-layer-1 .p {color: #000000;
}.prompt-layer-1 .span {color: rgba(0, 0, 0, .6);
}.prompt-loader .em {}/* 语音音阶------------- */
.prompt-loader {width: 96px;height: 20px;display: flex;align-items: center;justify-content: space-between;margin-bottom: 6px;
}.prompt-loader .em {display: block;background: #333333;width: 1px;height: 10%;margin-right: 2.5px;float: left;
}.prompt-loader .em:last-child {margin-right: 0px;
}.prompt-loader .em:nth-child(1) {animation: load 2.5s 1.4s infinite linear;
}.prompt-loader .em:nth-child(2) {animation: load 2.5s 1.2s infinite linear;
}.prompt-loader .em:nth-child(3) {animation: load 2.5s 1s infinite linear;
}.prompt-loader .em:nth-child(4) {animation: load 2.5s 0.8s infinite linear;
}.prompt-loader .em:nth-child(5) {animation: load 2.5s 0.6s infinite linear;
}.prompt-loader .em:nth-child(6) {animation: load 2.5s 0.4s infinite linear;
}.prompt-loader .em:nth-child(7) {animation: load 2.5s 0.2s infinite linear;
}.prompt-loader .em:nth-child(8) {animation: load 2.5s 0s infinite linear;
}.prompt-loader .em:nth-child(9) {animation: load 2.5s 0.2s infinite linear;
}.prompt-loader .em:nth-child(10) {animation: load 2.5s 0.4s infinite linear;
}.prompt-loader .em:nth-child(11) {animation: load 2.5s 0.6s infinite linear;
}.prompt-loader .em:nth-child(12) {animation: load 2.5s 0.8s infinite linear;
}.prompt-loader .em:nth-child(13) {animation: load 2.5s 1s infinite linear;
}.prompt-loader .em:nth-child(14) {animation: load 2.5s 1.2s infinite linear;
}.prompt-loader .em:nth-child(15) {animation: load 2.5s 1.4s infinite linear;
}@keyframes load {0% {height: 10%;}50% {height: 100%;}100% {height: 10%;}
}/* 语音音阶-------------------- */
.prompt-layer-2 {top: -40px;
}.prompt-layer-2 .text {color: rgba(0, 0, 0, 1);font-size: 12px;
}/* 语音录制结束---------------------------------------------------------------- */
.flex_row {display: flex;flex-direction: row;gap: 10rpx
}.record-btn-cir {flex-basis: 100rpx;border-width: 0.5px !important;border-color: #dadbde !important;border-style: solid;
}.u_input {border-width: 0.5px !important;border-color: #dadbde !important;border-style: solid;
}.record-btn-layer .record-btn-1 {background: #fff !important;// background-image: linear-gradient(to right, #43e97b 0%, #38f9d7 100%);color: #000000 !important;border-width: 0.5px !important;border-color: #dadbde !important;border-style: solid;border-radius: 8px;
}.chat_list {padding-top: 30rpx;max-height: 86vh;overflow-y: scroll;
}.type_right {margin: 30rpx 0 30rpx 50%;
}.type_left {margin: 30rpx 0 30rpx 30rpx;
}
</style>

聊天组件

<template><view class="box"><view class="qpk">{{ text }}</view><view :class="type == 'right' ? 'triangle_right' : 'triangle_left'"></view></view>
</template><script>
export default {props: {text: {type: String,default: ""},type: {type: String,default: "right"}},data() {return {};},watch: {},methods: {},
};
</script>
<style lang="scss" scoped>
// 气泡框样式
.box {position: relative;.qpk {width: 300rpx;height: 100%;text-align: left;background: #43e97b !important;-webkit-border-radius: 10px;-moz-border-radius: 10px;border-radius: 10px;word-break: break-all;padding: 18rpx 20rpx;font-size: 14px;}.triangle_left {position: absolute;height: 0px;width: 0px;border-width: 8px 18px 8px 0;border-style: solid;border-color: transparent #43e97b transparent transparent;top: 8rpx;left: -26rpx;}.triangle_right {position: absolute;height: 0px;width: 0px;border-width: 8px 0px 8px 18px;border-style: solid;border-color: transparent transparent transparent #43e97b;top: 8rpx;left: 326rpx;}
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/2087.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nautilus Chain 更换全新测试网,主网即将在不久上线

目前&#xff0c;Nautilus Chain 正在为主网上线前的最后阶段做准备&#xff0c;据悉该链更新了全新的测试网&#xff0c;在此前版本的测试网的基础上进行了全新的技术升级&#xff0c;最新测试网版本与生态发展的技术规划更为贴近。本次测试网升级将会是最后一次测试网版本的迭…

MacOS上安装Portainer

Portainer介绍 Portainer 是一个很方便的 Docker 可视化管理工具。主要的功能包括: 管理 Docker 主机,可以添加和删除 Docker 主机管理容器,可以启动、停止、删除等容器管理镜像,可以搜索、拉取、删除镜像管理卷,可以查看、删除卷管理网络,可以创建 Docker 网络管理用户和角色…

Redis数据持久化

Redis数据持久化 redis一共提供了两种数据持久化的方式RDB和AOF。 RDB ​ RDB全称为Redis Database Backup file&#xff08;数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是将内存中的全部数据都记录到磁盘中&#xff0c;当redis发生宕机或是一些…

VSCode种git rebase分支冲突解决无法继续rebase

情景&#xff1a; 常规来说我们git开分支开发完新功能之后&#xff0c;提交之前rebase dev分支&#xff0c;然后合并到dev上算是开发完成。 问题还原&#xff1a; 在开发完之后执行如下指令&#xff1a; 1.执行变基操作&#xff1a;git rebase dev。 //这一步出现冲突vscode上…

微信小程序基于Promise封装发起网络请求

1.创建一个request.js // 相当于域名 const baseURL ***************; // 暴露一个request函数 export function request(parms) {// 路径拼接const url baseURL parms.url;// 请求体&#xff0c;默认为{}const data parms.data || {};// 请求方式&#xff0c;默认为GETco…

HTTPS详解

1 概述 HTTPS 协议之所以是安全的是因为 HTTPS 协议会对传输的数据进行加密&#xff0c;而加密过程是使用了非对称加密实现。但其实&#xff0c;HTTPS 在内容传输的加密上使用的是对称加密&#xff0c;非对称加密只作用在证书验证阶段。 2 HTTPS请求过程 HTTPS的整体过程分为…

【FAQ】API6低代码开发问题汇总

参考文档&#xff1a; 低代码开发参考文档&#xff1a; 文档中心:使用低代码进行开发 基于景区模板开发元服务&#xff1a; 文档中心:模板简介 使用API6低代码开发遇到的问题汇总情况如下&#xff1a; 1、低代码环境下&#xff0c;如何实现box-shadow阴影效果的配置&#…

Angular 调试工具(Augury)

目录 1、简介 2、检验代码 3、Angury 本地构建和安装 3.1 添加到Chrome 浏览器&#xff1a; 3.2 添加到Firefox浏览器 4、项目中对应的Npm脚本 5、Augury 三大主要功能 5.1 组件树&#xff08;Component Tree&#xff09; 5.1.1 Component Tree 5.2 路由树&#xff0…

带记忆的Transformer模块

MEMORIZING TRANSFORMERS 返回论文和资料目录 论文地址 1.导读 谷歌去年做的一个工作。内容很简单&#xff0c;在Transformer模块中加入了一层记忆层&#xff0c;结果表明这个方法可以帮助模型提高在NLP任务上的表现&#xff1a;generic webtext (C4), math papers (arXiv),…

Generative Adversarial Network

Goodfellow,2014年 文献阅读笔记--GAN--Generative Adversarial NetworkGAN的原始论文-组会讲解_gan英文论文_Flying Warrior的博客-CSDN博客 启发:如何看两个数据是否来自同一个分布? 在统计中,two sample test。训练一个二分类的分类器,如果能分开这两个数据,说明来自…

数据库复习

select 查询 字段别名用 as (可以为中文) 例如 select distinct 关键字 去重复值 例如select distinct deptno from test where 条件过滤 and or 和 not运算符 and同时成立 or有一个成立就可以了 优先级and>or>not不符合&#xff08;!&#xff09; in 匹配多个值 selec…

Windows上查看服务器上tensorboad内容

文章目录 前言一、SSH的设置二、tensorboard命令 前言 本篇文章是针对于局域网内的服务器的tensorboard可视化&#xff0c;由于设置方式稍微有点复杂&#xff0c;导致我每次隔了一段时间之后&#xff0c;就不知道该怎么查看tensorboard了&#xff0c;每次都要百度搜一大堆资料…

SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

在SpringCloud系列&#xff08;十五&#xff09;[分布式搜索引擎篇] - 结合实际应用场景学习并使用 RestClient 客户端 API这篇文章中我们已经对 RestClient 有了初步的了解, 并且已经将一些数据进行了存储, 但是这并不是我们学习 ElasticSearch 的目的, ElasticSearch 最擅长的…

物业管理微信小程序的设计与开发

1.物业管理微信小程序实现的功能 该微信小程序包含小程序端&#xff0c;后台管理端以及后端。 小程序端提供给业主使用&#xff0c;实现的功能模块有公告通知、访客预约、车位申请、装修申请、一键报修、报修单、意见反馈、缴费通知、一键求助、个人信息管理&#xff1b; 后台…

arcgis建筑物平均高度

主要用到相交和属性表的汇总功能。 路网 建筑物栋 相交结果 右键&#xff0c;bh列汇总 原始块有392&#xff0c;这里只有389&#xff0c;说明有的地块没有建筑&#xff0c;所以应该将表连接到原始街区上检查是否合理&#xff0c;以及随机验证一个结果是否正确。 连接结果&…

Spring6.0 源码部署

环境依赖 Git JDK17 Gradle&#xff08;版本号需要和Spring源码中的版本一致&#xff09; 源码下载 官网地址 源码配置修改 maven { url "https://maven.aliyun.com/repository/central" }gradle-wrapper.properties #distributionUrlhttps\://services.gradle…

无虚拟 DOM 版 Vue 进行到哪一步了?

前言 就在一年前的 Vue Conf 2022&#xff0c;尤雨溪向大家分享了一个非常令人期待的新模式&#xff1a;无虚拟 DOM 模式&#xff01; 我看了回放之后非常兴奋&#xff0c;感觉这是个非常牛逼的新 feature&#xff0c;鉴于可能会有部分人还不知道或者还没听过什么是 Vue 无虚…

Excel-公式VLOOKUP 使用方法-小记

个人愚见 表示 MongoDB列中的任意一条数据 在 MySQL列 精确查找 和MongoDB列 中一模一样的数据&#xff0c;有的话返回MongoDB列数据&#xff0c;没有话返回#N/A 官方解释

【Web安全】小白怎么快速挖到第一个漏洞,src漏洞挖掘经验分享,绝对干货!

src漏洞挖掘经验分享 – 掌控安全以恒 一、公益src 公益src是一个白帽子提交随机发现的漏洞的品台&#xff0c;我们可以把我们随机发现或者是主动寻找到的漏洞在漏洞盒子进行提交。 在挖掘src的时候不能越红线&#xff0c;一般情况下遇到SQL注入 只获取数据库名字以证明漏洞的…

myAgv的slam算法学习以及动态避障下篇

引言 在之前的一篇文章中有提到购入了一台myAGV&#xff0c;以树莓派4B为控制核心的移动机器人。上篇文章中向大家介绍了myAGV如何实现建图、导航以及静态避障&#xff0c;但我们深知&#xff0c;这只是机器人自主导航能力的基础。在实际应用场景中&#xff0c;机器人需要面对复…