js
const app = getApp();
//引入插件:微信同声传译
const plugin = requirePlugin('WechatSI');
//获取全局唯一的语音识别管理器recordRecoManager
const manager = plugin.getRecordRecognitionManager();
const db = wx.cloud.database();
Page({
/**
* 页面的初始数据
*/
data: {
play_stop: 2,
textInputTis: 1,
tis: '按住 说话',
//语音
recordState: false, //录音状态
content: '', //内容
answer: '', //答案
src: '', //答案语音
// 当is_clock为true时识别
is_clock: true,
list: [{
type: 2,
src: '',
text: '智能人机聊天!',
},
]
},
// 发送消息
sendOut(e) {
var that = this
console.log(1111, e)
let text = e.detail.value
if (text == '') {
wx.showToast({
title: '请输入聊天内容',
icon: 'none',
})
} else {
let arr = {
type: 1,
src: '',
text: text
};
var a = that.data.list;
a.push(arr)
that.setData({
content: text,
list: a,
title: ''
})
this.answer()
}
},
// 语音文字切换
textInputTis() {
console.log('this.data.textInputTis', this.data.textInputTis)
if (this.data.textInputTis == 1) {
this.setData({
textInputTis: 2
})
} else if (this.data.textInputTis == 2) {
this.setData({
textInputTis: 1
})
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
//
//识别语音
this.initRecord();
},
onReady() {
//创建内部 audio 上下文 InnerAudioContext 对象。
this.innerAudioContext = wx.createInnerAudioContext();
this.innerAudioContext.onError(function(res) {
console.log(res);
this.setData({
play_stop:1,
})
})
},
//识别语音 -- 初始化
initRecord: function() {
const that = this;
// 有新的识别内容返回,则会调用此事件
manager.onRecognize = function(res) {
console.log(res)
}
// 正常开始录音识别时会调用此事件
manager.onStart = function(res) {
console.log("成功开始录音识别", res)
}
// 识别错误事件
manager.onError = function(res) {
console.error("error msg", res)
}
//识别结束事件
manager.onStop = function(res) {
console.log('..............结束录音')
console.log('录音临时文件地址 -->' + res.tempFilePath);
console.log('录音总时长 -->' + res.duration + 'ms');
console.log('文件大小 --> ' + res.fileSize + 'B');
console.log('语音内容 --> ' + res.result);
if (that.data.is_clock == true) {
// 语音结束识别
if (res.result == '') {
wx.showModal({
title: '提示',
content: '听不清楚,请重新说一遍!',
showCancel: false,
success: function(res) {}
})
return;
}
var text = res.result;
text = text.replace(/[\ |\。|\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g, "");
console.log('text', text)
let arr = {
type: 1,
src: res.tempFilePath,
text: res.result
};
var a = that.data.list;
a.push(arr)
console.log(333333333, a)
that.setData({
content: text,
list: a,
})
that.answer();
that.bottom()
} else {
console.log('取消')
that.setData({
is_clock: true,
})
}
}
},
// 匹配答案
answer() {
this.stoppreviewImage()
// console.log('list',this.data.list)
var that = this
let content = this.data.content
db.collection("yuyin").where({
daan: {
$regex: '.*' + content + '.*',
$options: '1'
}
}).get({
success: res => {
console.log('匹配', res)
if (res.data.length == 0) {
wx.showModal({
title: '提示',
content: '暂时没找到对应答案',
showCancel: false,
success: function(res) {}
})
return;
}
that.setData({
answer: res.data[0].yuyin
})
this.wordYun()
}
})
},
bottom() {
var that = this;
this.setData({
scrollTop: 100000
})
},
// 答案文字转语音
wordYun: function(e) {
var that = this
var that = this;
let content = that.data.answer;
plugin.textToSpeech({
lang: "zh_CN",
tts: true,
content: content,
success: function(res) {
console.log(res);
console.log("succ tts", res.filename);
let arr = {
type: 2,
src: res.filename,
text: content
};
var a = that.data.list;
a.push(arr)
that.setData({
src: res.filename,
list: a,
})
that.yuyinPlay();
that.bottom()
},
fail: function(res) {
console.log("fail tts", res)
}
})
},
// 点击并播放当前语音
previewImage(e) {
if (this.data.src == '') {
console.log('暂无语音');
return;
}
console.log(this.data.play_stop)
let src = e.currentTarget.dataset.src
if (this.data.play_stop =='play') {
console.log(1238765432, src != this.data.src)
if (src != this.data.src) {
this.innerAudioContext.stop();
this.innerAudioContext.src = src //设置音频地址
this.innerAudioContext.play(); //播放音频
this.setData({
src: src,
play_stop:'play',
})
} else {
this.innerAudioContext.stop();
this.setData({
play_stop: 'stop',
})
}
} else {
this.innerAudioContext.src = this.data.src //设置音频地址
this.innerAudioContext.play(); //播放音频
this.setData({
play_stop: 'play',
})
}
},
// 停止音频播放
stoppreviewImage(e) {
this.innerAudioContext.stop(); //播放音频
this.setData({
play_stop:'stop',
})
},
//播放语音
yuyinPlay: function(e) {
if (this.data.src == '') {
console.log('暂无语音');
return;
}
this.setData({
play_stop: 'play',
})
this.innerAudioContext.src = this.data.src //设置音频地址
this.innerAudioContext.play(); //播放音频
},
//语音 --按住说话
touchStart: function(e) {
this.stoppreviewImage()
console.log('长按')
this.setData({
recordState: true, //录音状态
is_clock: true,
startPoint: e.touches[0], //记录触摸点的坐标信息
tis: '松开 结束'
})
// 语音开始识别
manager.start({
lang: 'zh_CN', // 识别的语言,目前支持zh_CN en_US zh_HK sichuanhua
})
},
//语音 --松开结束
touchEnd: function(e) {
console.log('结束')
this.setData({
tis: '按住 说话'
})
manager.stop();
},
handleTouchMove: function(e) {
//计算距离,当滑动的垂直距离大于25时,则取消发送语音
if (Math.abs(e.touches[e.touches.length - 1].clientY - this.data.startPoint.clientY) > 25) {
this.setData({
is_clock: false //设置为不发送语音
})
}
},
})
wxml
{{item.sendOutname}} {{item.dataTime}}
{{item.text}}
{{item.sendOutname}} {{item.dataTime}}
{{item.text}}
{{tis}}
css
page {
background: #f2f2f2;
height: 100%;
overflow: hidden
}
.top_bo {
display: flex;
background: white;
flex-direction: row;
}
.top_bo view {
flex: 1;
font-size: 28rpx;
text-align: center;
border: 1rpx solid #ccc;
line-height: 80rpx;
}
scroll-view {
height: 84vh;
overflow: hidden;
padding-bottom: 100rpx;
padding-top:50rpx;
}
.noList {
background: white;
margin-top: 30rpx;
/* height: 230rpx; */
width: 100%;
/* padding-top: 25%; */
}
.noMsg {
text-align: center;
color: #999;
font-size: 28rpx;
}
.inp {
position: absolute;
bottom: 0;
width: 100%;
background: #e0e0e0;
height: 100rpx;
padding: 10rpx 0;
}
.inp input {
background: #d0d0d0;
border-radius: 15rpx;
padding-left: 20rpx;
height: 84rpx;
/* margin-left: 2%; */
width:80%;
background: #fff;
/* padding-left: 20rpx; */
/* height: 84rpx; */
margin-top: 10rpx;
line-height: 80rpx;
font-size: 32rpx;
color: #0a0a0a
}
.yuyin {
/* width: 60rpx */
/* background: #00a9ec; */
border-radius: 15rpx;
height: 84rpx;
line-height: 84rpx;
color: #fff;
padding: 0 10rpx;
margin-left: 10rpx;
margin-top: 10rpx;
text-align: center;
}
.yuyin image{
width: 60rpx;
margin:15rpx 10rpx 0 10rpx;
}
.prohibit {
background: #d0d0d0;
border-radius: 15rpx;
padding-left: 20rpx;
height: 84rpx;
margin-top: 10rpx;
width: 94%;
margin-left: 2%;
text-align: center;
line-height: 84rpx;
color: rgb(34, 34, 34);
}
.plaCC {
margin-left: 5rpx;
}
.p_r {
display: flex;
flex-direction: row;
}
.flexRoe {
display: flex;
flex-direction: row;
}
.body {
width: 100%;
position: relative;
/* border: 1rpx solid #ccc; *//* height: 200rpx */
}
.right_body {
width: 100%;
/* border: 1rpx solid red; */
padding: 20rpx;
/* margin-top: 50rpx; */
}
.left_body {
/* margin-top: 50rpx; */
}
.posRit {
right: 20rpx;
}
.textBo {
width: 620rpx;
text-align: right;
}
.lfBo {
margin-left: 10rpx;
}
.ritTxt {
background: #44426a;
padding: 10rpx 20rpx 10rpx 20rpx;
color: white;
border-radius: 15rpx 0 15rpx 15rpx;
margin-top: 20rpx;
float: right;
max-width: 500rpx;
word-wrap: break-word;
text-align: left;
font-size: 28rpx;
}
.lftTxt {
background: #44426a;
padding: 10rpx 20rpx 10rpx 20rpx;
color: white;
border-radius: 0rpx 15rpx 15rpx 15rpx;
margin-top: 20rpx;
float: left;
max-width: 500rpx;
word-wrap: break-word;
text-align: left;
font-size: 28rpx;
}
.my_audio {
height: 60rpx;
width: 60rpx;
z-index: 2;
position: relative;
top: 10rpx;
left: 20rpx;
margin-right: 30rpx;
}
.dataTime {
font-size: 28rpx;
}
.textImg {
width: 50rpx;
margin-top: 5rpx;
}
.head {
width: 80rpx;
height: 80rpx;
}
._ {
height: 130rpx;
width: 100%;
background: #ccc;
}
.serac_img {
width: 80%;
background: #fff;
border-radius: 15rpx;
/* padding-left: 20rpx; */
/* height: 84rpx; */
margin-top: 10rpx;
margin-left: 2%;
text-align: center;
line-height: 80rpx;
font-size: 32rpx;
color: #0a0a0a
}
.serac_img view {
width: 70%;
text-align: right;
line-height: 80rpx;
color: #bfbfbf;
}
.serac_img image {
width: 50rpx;
margin-top: 25rpx;
}
.jifBo{
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
}
.jifBo image{
width: 40%;
margin-left: 30%;
margin-top: 50%;
}