|
|
@@ -45,10 +45,10 @@
|
|
|
<view class="send-box" :style="{ 'padding-bottom': isShowKeyBoard + 'px' }">
|
|
|
<image :src="[!isVoiceType ? '/static/icon/voice-icon.png' : '/static/icon/keyBoard-icon.png']" @click.stop="tabVoice()"></image>
|
|
|
|
|
|
- <view class="voice-mode" v-if="isVoiceType" @click="asrStart">语音识别</view>
|
|
|
+ <view class="voice-mode" v-if="isVoiceType" @touchstart="longPressStart" @touchend="touchMoveEnd">按住说话</view>
|
|
|
<!-- <view>{{arsRes}}</view> -->
|
|
|
<!-- 语音识别 -->
|
|
|
- <wechat-asr ref="weixinAsr" @callback="asrResult" />
|
|
|
+ <!-- <wechat-asr ref="weixinAsr" @callback="asrResult" /> -->
|
|
|
<input
|
|
|
type="text"
|
|
|
v-if="!isVoiceType"
|
|
|
@@ -76,14 +76,22 @@
|
|
|
</view>
|
|
|
</uni-popup>
|
|
|
</view>
|
|
|
- <!-- 录音UI效果
|
|
|
- <view class="record" :class="recording?'':'hidden'">
|
|
|
- <view class="ing" :class="willStop?'hidden':''"><image src="../../static/icon/send-icon.png" style="width: 64rpx;height: 64rpx;"></image></view>
|
|
|
- <view class="cancel" :class="willStop?'':'hidden'"><image src="../../static/icon/cancel-icon.png" style="width: 64rpx;height: 64rpx;"></image></view>
|
|
|
- <view class="tis" :class="willStop?'change':''">{{recordTis}}</view>
|
|
|
- </view> -->
|
|
|
-
|
|
|
- <!-- <drag-button :isDock="true" :existTabBar="true" @btnClick="goUserSelf" /> -->
|
|
|
+ <view class="mask" v-show="isShowVoice">
|
|
|
+ <view class="weixin-asr">
|
|
|
+ <view class="title">语音识别</view>
|
|
|
+ <!-- 动画 -->
|
|
|
+ <view class="spinner">
|
|
|
+ <view class="rect rect1"></view>
|
|
|
+ <view class="rect rect2"></view>
|
|
|
+ <view class="rect rect3"></view>
|
|
|
+ <view class="rect rect4"></view>
|
|
|
+ <view class="rect rect5"></view>
|
|
|
+ </view>
|
|
|
+ <view class="tip">说出股票代码</view>
|
|
|
+ <!-- <view>{{resultText}}</view> -->
|
|
|
+ <!-- <button class="btn" type="default" @click="recordStop">说完了</button> -->
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
<uni-popup ref="popup" type="bottom">
|
|
|
<view class="uni-share">
|
|
|
<view class="uni-share-content">
|
|
|
@@ -124,10 +132,13 @@ import WechatAsr from '../chat/chat.vue';
|
|
|
var md5 = require("../../common/md5.js");
|
|
|
var page = 1;
|
|
|
const recorderManager = uni.getRecorderManager();
|
|
|
-const innerAudioContext = uni.createInnerAudioContext();
|
|
|
+const innerAudioContext = uni.createInnerAudioContext();
|
|
|
+const WechatSI = requirePlugin("WechatSI");
|
|
|
+const ASRManager = WechatSI.getRecordRecognitionManager();
|
|
|
export default {
|
|
|
data() {
|
|
|
- return {
|
|
|
+ return {
|
|
|
+ isShowVoice:false,
|
|
|
isShowSend:false,
|
|
|
isShowSetModal:false,
|
|
|
isShowSetCenter:true,
|
|
|
@@ -186,6 +197,40 @@ export default {
|
|
|
},
|
|
|
onPageScroll(e) {
|
|
|
this.scrollTopNav = e.scrollTop;
|
|
|
+ },
|
|
|
+ onReady () {
|
|
|
+ // 录音开启成功回调
|
|
|
+ ASRManager.onStart = function (res) {
|
|
|
+ _this.isShowVoice = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ const _this = this;
|
|
|
+ // 识别错误事件
|
|
|
+ ASRManager.onError = (res) => {
|
|
|
+ _this.isShowVoice = false;
|
|
|
+ uni.showToast({
|
|
|
+ title:'请再试一次',
|
|
|
+ icon:'none',
|
|
|
+ duration:2000
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 录音停止回调
|
|
|
+ ASRManager.onStop = function (res) {
|
|
|
+ if (res && res.result) {
|
|
|
+ // _this.resultText = res.result;
|
|
|
+ // _this.$emit('callback', res.result);
|
|
|
+ res = (res.result).substring(0,res.result.length-1)
|
|
|
+ console.log(res)
|
|
|
+ page = 1;
|
|
|
+ _this.sendMsgRequest(res)
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: '抱歉,没听到您的声音哦'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
},
|
|
|
onShareAppMessage(){
|
|
|
return {
|
|
|
@@ -615,18 +660,59 @@ export default {
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
- // 语音识别
|
|
|
- asrStart () {
|
|
|
- let that = this;
|
|
|
- this.$jiuaiDebounce.canDoFunction({
|
|
|
- key:"asrStart",//基于此值判断是否可以操作,如两个方法传入了同样的key,则会混淆,建议传入调用此事件的方法名,简单好梳理
|
|
|
- time:3000,//如果传入time字段,则为定时器后,自动解除锁定状态,单位(毫秒)
|
|
|
- success:()=>{//成功中调用应该操作的方法,被锁定状态不会执行此代码块内的方法
|
|
|
- that.$refs.weixinAsr.show();
|
|
|
- console.log(666)
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
+ // 语音识别
|
|
|
+ show() {
|
|
|
+ const _this = this;
|
|
|
+ // 获取是否授权信息
|
|
|
+ uni.getSetting({
|
|
|
+ success(res) {
|
|
|
+ if (res && res.authSetting && res.authSetting.hasOwnProperty('scope.record')) {
|
|
|
+ if (res.authSetting['scope.record']) {
|
|
|
+ start();
|
|
|
+ } else { // 拒绝授权,打开授权设置
|
|
|
+ uni.openSetting({
|
|
|
+ success() {
|
|
|
+ start();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ start();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ function start () {
|
|
|
+ ASRManager.start({
|
|
|
+ lang: "zh_CN"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 录音停止
|
|
|
+ recordStop () {
|
|
|
+ this.isShowVoice = false;
|
|
|
+ ASRManager.stop();
|
|
|
+ },
|
|
|
+
|
|
|
+ // asrStart () {
|
|
|
+ // let that = this;
|
|
|
+ // this.$jiuaiDebounce.canDoFunction({
|
|
|
+ // key:"asrStart",//基于此值判断是否可以操作,如两个方法传入了同样的key,则会混淆,建议传入调用此事件的方法名,简单好梳理
|
|
|
+ // time:3000,//如果传入time字段,则为定时器后,自动解除锁定状态,单位(毫秒)
|
|
|
+ // success:()=>{//成功中调用应该操作的方法,被锁定状态不会执行此代码块内的方法
|
|
|
+ // this.isShowVoice = true;
|
|
|
+ // this.show();
|
|
|
+ // console.log(666)
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ // },
|
|
|
+ longPressStart(){
|
|
|
+ this.isShowVoice = true;
|
|
|
+ this.show();
|
|
|
+ },
|
|
|
+ touchMoveEnd(){
|
|
|
+ this.recordStop()
|
|
|
+ },
|
|
|
asrResult (res) {
|
|
|
//this.arsRes = res;
|
|
|
res = res.substring(0,res.length-1)
|
|
|
@@ -641,7 +727,7 @@ export default {
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
-<style>
|
|
|
+<style lang="scss">
|
|
|
.content {
|
|
|
text-align: center;
|
|
|
}
|
|
|
@@ -981,5 +1067,104 @@ export default {
|
|
|
margin-top: 5%;
|
|
|
color: #fff;
|
|
|
background: #00bfff;
|
|
|
-}
|
|
|
+}
|
|
|
+
|
|
|
+ .mask {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ z-index: 300;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: rgba(0, 0, 0, .54);
|
|
|
+ }
|
|
|
+ .weixin-asr {
|
|
|
+ position: absolute;
|
|
|
+ top: calc(50% - #{477upx / 2});
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ margin: 0 auto;
|
|
|
+ width: 560upx;
|
|
|
+ height: 477upx;
|
|
|
+ background: #fff;
|
|
|
+ text-align: center;
|
|
|
+ transform: .5s ease-out .5s;
|
|
|
+ .title {
|
|
|
+ margin-top: 42upx;
|
|
|
+ color: #000;
|
|
|
+ font-size: 34upx;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ .spinner {
|
|
|
+ margin: 50upx;
|
|
|
+ height: 100upx;
|
|
|
+ }
|
|
|
+ .tip {
|
|
|
+ color: #787878;
|
|
|
+ }
|
|
|
+ .btn {
|
|
|
+ margin-top: 28upx;
|
|
|
+ width: 225upx;
|
|
|
+ height: 82upx;
|
|
|
+ background: #27BCEF;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 34upx;
|
|
|
+ line-height: 82upx;
|
|
|
+ border-radius: 82upx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .spinner {
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .spinner > .rect {
|
|
|
+ background-color: #EDAA35;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 13upx;
|
|
|
+ width: 13upx;
|
|
|
+ display: inline-block;
|
|
|
+
|
|
|
+ -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
|
|
|
+ animation: stretchdelay 1.2s infinite ease-in-out;
|
|
|
+
|
|
|
+ & + .rect {
|
|
|
+ margin-left: 15upx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .spinner .rect2 {
|
|
|
+ -webkit-animation-delay: -1.1s;
|
|
|
+ animation-delay: -1.1s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .spinner .rect3 {
|
|
|
+ -webkit-animation-delay: -1.0s;
|
|
|
+ animation-delay: -1.0s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .spinner .rect4 {
|
|
|
+ -webkit-animation-delay: -0.9s;
|
|
|
+ animation-delay: -0.9s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .spinner .rect5 {
|
|
|
+ -webkit-animation-delay: -0.8s;
|
|
|
+ animation-delay: -0.8s;
|
|
|
+ }
|
|
|
+
|
|
|
+ @-webkit-keyframes stretchdelay {
|
|
|
+ 0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
|
|
|
+ 20% { -webkit-transform: scaleY(1.0) }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes stretchdelay {
|
|
|
+ 0%, 40%, 100% {
|
|
|
+ transform: scaleY(0.4);
|
|
|
+ -webkit-transform: scaleY(0.4);
|
|
|
+ } 20% {
|
|
|
+ transform: scaleY(1.0);
|
|
|
+ -webkit-transform: scaleY(1.0);
|
|
|
+ }
|
|
|
+ }
|
|
|
</style>
|