You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
7.2 KiB
263 lines
7.2 KiB
<template>
|
|
<div class="container">
|
|
<meet-sticky :bg="bg">
|
|
<meet-navbar title="会议中" :isFixed="false"></meet-navbar>
|
|
</meet-sticky>
|
|
<view class="list" v-for="(item, index) in 10">
|
|
<view class="flex-left color-1">1</view>
|
|
<view class="flex-child">
|
|
<view class="flex-center">我公司碳中和具体的应用场景包括以下几方面:1.碳丝路APP-全民低碳场景的数据收集 碳普惠应用。 2.全国性碳交易平台数据。</view>
|
|
<view class="flex-right">5"</view>
|
|
</view>
|
|
</view>
|
|
<view class="footer">
|
|
<image class="icon01" src="/static/image/online/online.gif"></image>
|
|
<view class="footer-center">
|
|
<view class="text-1">正在录音中</view>
|
|
<view class="text-2"><span>00:12</span>/02:00:00</view>
|
|
</view>
|
|
<view class="footer-icon" @click="startRecord()" v-if="isRecording == false">
|
|
<image class="img" src="/static/image/online/play.png"></image>
|
|
<view class="text-1">开始</view>
|
|
</view>
|
|
<view class="footer-icon" @click="endRecord()" v-if="isRecording == true">
|
|
<image class="img" src="/static/image/online/pause.png"></image>
|
|
<view class="text-1">结束</view>
|
|
</view>
|
|
<view class="footer-icon">
|
|
<image class="img" src="/static/image/online/stop.png"></image>
|
|
<view class="text-1">结束</view>
|
|
</view>
|
|
</view>
|
|
<!-- 弹框 -->
|
|
<meet-pop :dialogShow="popConfig.show" :btnType="popConfig.btnType" :dialogTitle="popConfig.title"
|
|
:CancelText="popConfig.CancelText" :ConfirmText="popConfig.ConfirmText" @handleConfirm="confirm"
|
|
@handleCancel="cancel">
|
|
<view class="popClass">
|
|
结束后无法在本记录继续录音
|
|
</view>
|
|
</meet-pop>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
const recorderManager = uni.getRecorderManager();
|
|
const innerAudioContext = uni.createInnerAudioContext();
|
|
innerAudioContext.autoplay = true;
|
|
export default {
|
|
components: {
|
|
},
|
|
data() {
|
|
return {
|
|
list: [],
|
|
popConfig: {
|
|
show: false,
|
|
btnType: 2,
|
|
title: "确定结束录音吗?",
|
|
CancelText: "在考虑下",
|
|
ConfirmText: "结束录音"
|
|
},
|
|
//录音
|
|
recorderManager: null,
|
|
innerAudioContext: {},
|
|
isRecording: false,
|
|
ws: null,
|
|
webSocketUrl: "",
|
|
VITE_APP_WS: "wss://u140106-8027-537a5c07.westx.seetacloud.com:8443/api/stt/service"
|
|
};
|
|
},
|
|
onLoad() {
|
|
// this.recorderManager = uni.getRecorderManager();
|
|
// console.log('recorderManager', this.recorderManager);
|
|
// innerAudioContext.autoplay = true;
|
|
// console.log("uni.getRecorderManager()", uni.getRecorderManager())
|
|
// console.log("uni.createInnerAudioContext()", uni.createInnerAudioContext())
|
|
// let self = this;
|
|
// recorderManager.onStop(function (res) {
|
|
// console.log('recorder stop' + JSON.stringify(res));
|
|
// self.voicePath = res.tempFilePath;
|
|
// });
|
|
this.initWebSocket();
|
|
},
|
|
methods: {
|
|
async initWebSocket() {
|
|
let url = this.VITE_APP_WS;
|
|
var audio_type = "mic_stream";
|
|
var hot_words = "碳丝路 元梦空间";
|
|
var hot_words2 = "碳丝路元梦空间";
|
|
var language = "zh";
|
|
var sample_rate = "16000";
|
|
var timestamp = Math.floor(Date.now() / 1000);
|
|
var api_key = "AT_syAHhLp3vqOA!@+T9Cocxc0^6z@^9";
|
|
var auth = `api_key=${api_key}&audio_type=${audio_type}&hot_words=${hot_words2}&language=${language}&sample_rate=${sample_rate}&stream=True×tamp=${timestamp}`;
|
|
const sign = await this.sha256(auth);
|
|
url = `${url}?audio_type=${audio_type}&hot_words=${encodeURIComponent(hot_words)}&language=${language}&sample_rate=${sample_rate}×tamp=${timestamp}&api_key=${encodeURIComponent(api_key)}&auth=${sign}`;
|
|
createdWebSocket(url);
|
|
},
|
|
async sha256(str) {
|
|
// 将输入字符串转换为二进制数据
|
|
const encoder = new TextEncoder();
|
|
const data = encoder.encode(str);
|
|
// 调用原生的SubtleCrypto API计算SHA-256哈希
|
|
return crypto.subtle.digest("SHA-256", data).then(buffer => {
|
|
// 将哈希结果转换为十六进制字符串
|
|
const hexArray = Array.from(new Uint8Array(buffer));
|
|
const hexString = hexArray
|
|
.map(byte => byte.toString(16).padStart(2, "0"))
|
|
.join("");
|
|
return hexString;
|
|
});
|
|
},
|
|
confirm() {
|
|
this.popConfig.show = false;
|
|
},
|
|
cancel() {
|
|
this.popConfig.show = false;
|
|
},
|
|
startRecord() {
|
|
console.log('开始录音');
|
|
if (this.isRecording) return;
|
|
this.isRecording = true;
|
|
// const recorderManager = this.recorderManager;
|
|
const options = {
|
|
duration: 60000, // 录音的最大时长,单位 ms
|
|
sampleRate: 8000, // 采样率
|
|
numberOfChannels: 1, // 录音的 channel 数量
|
|
encodeBitRate: 44100, // 编码码率
|
|
format: 'mp3', // 音频格式,支持 'aac' 或 'mp3'
|
|
frameSize: 20
|
|
};
|
|
recorderManager.start(options);
|
|
recorderManager.onStart(() => {
|
|
console.log('录音开始');
|
|
});
|
|
|
|
recorderManager.onFrameRecorded((res) => {
|
|
// 实时获取录音进度回调
|
|
const { frameBuffer } = res;
|
|
console.log(frameBuffer);
|
|
});
|
|
|
|
},
|
|
endRecord() {
|
|
this.isRecording = false;
|
|
// const recorderManager = this.recorderManager;
|
|
recorderManager.onStop((res) => {
|
|
console.log('录音结束', res.tempFilePath);
|
|
});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "../common.scss";
|
|
|
|
.container {
|
|
min-height: 100vh;
|
|
background-color: #d1dcfe;
|
|
padding: 20rpx 0;
|
|
padding-bottom: 200rpx;
|
|
|
|
.list {
|
|
display: flex;
|
|
margin-top: 36rpx;
|
|
padding: 0 24rpx;
|
|
|
|
.flex-left {
|
|
width: 56rpx;
|
|
height: 56rpx;
|
|
font-size: 36rpx;
|
|
line-height: 56rpx;
|
|
text-align: center;
|
|
border-radius: 50%;
|
|
color: #fff;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.color-1 {
|
|
background-color: #70CD9E;
|
|
}
|
|
|
|
.flex-child {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
flex: 1;
|
|
|
|
.flex-center {
|
|
|
|
margin: 0 16rpx 0 16rpx;
|
|
border: 1px solid #fff;
|
|
background-color: rbga(255, 255, 255, 0.5);
|
|
border-radius: 16rpx;
|
|
box-sizing: border-box;
|
|
padding: 16rpx 24rpx;
|
|
}
|
|
|
|
.flex-right {
|
|
color: #23262B;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.footer {
|
|
background: rgba(255, 255, 255, 1);
|
|
border-top-right-radius: 40rpx;
|
|
border-top-left-radius: 40rpx;
|
|
position: fixed;
|
|
bottom: 0;
|
|
width: 100%;
|
|
height: 180rpx;
|
|
display: flex;
|
|
box-sizing: border-box;
|
|
padding: 12rpx 24rpx;
|
|
|
|
.icon01 {
|
|
width: 88rpx;
|
|
height: 88rpx;
|
|
border-radius: 24rpx;
|
|
margin-right: 24rpx;
|
|
}
|
|
|
|
.footer-center {
|
|
flex: 1;
|
|
|
|
.text-1 {
|
|
color: #23262B;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.text-2 {
|
|
color: #93999F;
|
|
font-size: 24rpx;
|
|
|
|
span {
|
|
color: #23262B;
|
|
}
|
|
}
|
|
}
|
|
|
|
.footer-icon {
|
|
margin-right: 56rpx;
|
|
|
|
.img {
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
}
|
|
|
|
.text-1 {
|
|
color: #23262B;
|
|
font-size: 22rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.popClass {
|
|
text-align: center;
|
|
color: #4B5158;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
</style> |