<template>
<div class="container">
<div class="step-box">
<div class="min-box">
</div>
<tiny-time-line :data="dataLine" :active="normalActive" type="normal"></tiny-time-line>
</div>
<div class="describe-box">
<div class="test-box">
<div class="title">欢迎您即将开始北英测评考试,请准备好耳机,点击下面【播放】图标,并调整好您的音量。</div>
<div :class="normalActive == 0 ? 'btn-box btn-box-active' : 'btn-box'" @click="stepOne">
<img v-show="normalActive == 0" src="../../../assets/images/laba.png" alt="">
<img v-show="normalActive !== 0" src="../../../assets/images/labaactive.png" alt="">
<span :class="normalActive == 0 ? 'white' : ''">Put on your headphones and click here Play Sound</span>
</div>
</div>
<div class="test-box">
<div class="title">请您打开麦克风,调整好音量后,点击下面图标,向我们打招呼吧</div>
<div :class="normalActive == 1 ? 'btn-box btn-box-active' : 'btn-box'" @click="stepTwo">
<img style="width: .42rem;height:.69rem" v-show="normalActive == 1"
src="../../../assets/images/maikefeng.png" alt="">
<img style="width: .42rem;height:.69rem" v-show="normalActive !== 1"
src="../../../assets/images/maikefengactive.png" alt="">
<span :class="normalActive == 1 ? 'white' : ''">Open your microphone and set the volume level
properly</span>
</div>
</div>
<div class="test-box">
<div class="title">点击下面图标,看看能否成功听到自己的声音</div>
<div :class="normalActive == 2 ? 'btn-box btn-box-active' : 'btn-box'" @click="stepThree">
<img v-show="normalActive == 2" src="../../../assets/images/bofang.png" alt="">
<img v-show="normalActive !== 2" src="../../../assets/images/bofangicon.png" alt="">
<span :class="normalActive == 2 ? 'white' : ''">Click on Play Sound. If you cannot hear the sound,change
the
volume on your device</span>
</div>
</div>
</div>
<div class="nextStep">
<div class="nextStepTitle" v-show="!disabled">一切正常,我们就开始吧!</div>
<div class="nextStepBtn">
<tiny-button :disabled="disabled" type="primary" native-type="submit" @click="nextStep"> 检测完成 </tiny-button>
</div>
</div>
<tiny-dialog-box v-model:visible="boxVisibility" :modal="false" :title="dialogText.title" width="30%" top="30%">
<span v-html="dialogText.describe"></span>
<template #footer>
<tiny-button type="primary" @click="confrim"> {{ dialogText.sureBtn }} </tiny-button>
<tiny-button @click="boxVisibility = false"> {{ dialogText.cancleBtn }} </tiny-button>
</template>
</tiny-dialog-box>
<!-- <div class="dialog" v-show="boxVisibility">
<tiny-button type="primary" @click="confrim"> {{ dialogText.sureBtn }} </tiny-button>
</div> -->
<!-- <pointOut></pointOut> -->
</div>
</template>
<script setup>
// 数据、VUE模块、第三方UI组件库的引入
import { reactive, ref, onMounted, createApp } from 'vue'
import { TimeLine as TinyTimeLine, Modal, Button as TinyButton, DialogBox as TinyDialogBox, Notify } from '@opentiny/vue'
import { useRouter } from 'vue-router'
import Recorder from 'js-audio-recorder'
const data = reactive({
//用于存储创建的语音对象
recorder: null,
formData: null,
// 控制录音动画的显示隐藏
showAnima: false,
mation: true,
isHistory: true,
// 录音时长
duration: 0,
submit() { // 发送语音的方法
data.recorder.pause() // 暂停录音
data.timer = null
console.log('上传录音')// 上传录音
var formData = new FormData()
var blob = data.recorder.getWAVBlob()//获取wav格式音频数据
//此处获取到blob对象后需要设置fileName满足当前项目上传需求,其它项目可直接传把blob作为 file塞入formData
var newbolb = new Blob([blob], { type: 'audio/wav' })
var fileOfBlob = new File([newbolb], new Date().getTime() + '.wav')
//formData是传给后端的对象,
formData.append('file', fileOfBlob)
//计算出录音时长
data.duration = Math.ceil((new Date() - data.duration) / 1000);
console.log(data.duration);
//发送给后端的方法
sendAudio(formData).then(res => {
console.log(res);
})
},
// 录音按钮的点击事件
voice() {
//实例化语音对象
data.recorder = new Recorder({
sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
sampleRate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
numChannels: 1 // 声道,支持 1 或 2, 默认是1
})
//记录开始录音的时间
data.duration = new Date();
Recorder.getPermission().then(() => {
console.log('开始录音')
data.recorder.start() // 开始录音
}, (error) => {
console.log(`${error.name} : ${error.message}`)
})
},
handleStop() {
console.log('停止录音')
data.recorder.stop() // 停止录音
data.mation = false;
},
handlePlay() {
console.log('播放录音')
data.recorder.play() // 播放录音
},
handleDestroy() {
console.log('销毁实例')
if (data.recorder) {
data.recorder.destroy() // 毁实例
}
},
})
// 页面数据的定义
const normalActive = ref(0) //步骤条的控制
const disabled = ref(true) //判断检测完成按钮时都可以点击
const boxVisibility = ref(false) //控制dialog的显示与隐藏
// 步骤条的描述文字
const dataLine = ref([{ name: '耳机检测' }, { name: '麦克风检测' }, { name: '录音播放' }])
// dialog里面的内容字段
const dialogText = reactive({
title: '步骤一:耳机检测',
describe: '是否可以听清播放内容',
cancleBtn: '不可以',
sureBtn: '可以'
})
const app = createApp({})
const router = useRouter()
app.component({
// pointOut
})
// 进入页面获取麦克风权限
onMounted(() => {
})
function nextStep() {
router.push({
path: '/secondaryAnswer'
})
}
// 耳机测试
function stepOne() {
if (normalActive.value == 0) {
setTimeout(() => {
boxVisibility.value = true
}, 2000)
}
}
// 麦克风测试
const stepTwo = function () {
if (normalActive.value == 1) {
// 录音
data.voice()
dialogText.title = '步骤二:麦克风检测'
dialogText.describe = `请阅读以下内容:</br><p>You are not strong, no one strong for you.</p>`
dialogText.sureBtn = '阅读完毕'
dialogText.cancleBtn = '返回'
boxVisibility.value = true
}
}
// 听取录音设置
const stepThree = function () {
if (normalActive.value == 2) {
// 播放录音
data.handleStop()
data.handlePlay()
// console.log(normalActive)
dialogText.title = '步骤二:录音播放'
dialogText.describe = `可以听清楚自己的录音吗?`
dialogText.sureBtn = '可以'
dialogText.cancleBtn = '不可以'
setTimeout(() => {
boxVisibility.value = true
}, 2000)
}
}
const confrim = function () {
// 点击的第二个步骤的时候,结束录音机的录制
if (normalActive.value == 1) {
}
// 判断是否是第三个步骤,是的话normalActive禁止++
if (normalActive.value !== 2) {
normalActive.value++
} else {
disabled.value = false
}
boxVisibility.value = false
}
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
// border: 1px solid red;
// border: 1px solid red;
.dialog {
position: fixed;
top: 0;
left: 0;
background-color: rgb(202, 205, 207, .4);
width: 10rem;
height: 10rem;
}
.step-box {
height: .56rem;
width: 100%;
border-radius: .17rem;
margin-top: .49rem;
display: flex;
align-items: center;
position: relative;
.min-box {
position: absolute;
border-radius: .17rem;
// border: 1px solid red;
background-color: #fff;
width: 80%;
left: 10%;
height: .56rem;
}
// border: 1px solid red;
.tiny-steps {
width: 100%;
}
}
.describe-box {
width: 100%;
margin-top: .49rem;
display: flex;
justify-content: space-evenly;
.test-box {
width: 2.78rem;
// border: 1px solid red;
.title {
width: 2.72rem;
height: .49rem;
margin: 0 auto;
font-size: .08rem;
}
.btn-box {
width: 100%;
height: 1.35rem;
border-radius: .21rem;
display: flex;
background-color: #fff;
justify-content: center;
align-items: center;
img {
width: .69rem;
height: .52rem;
}
span {
width: 1.61rem;
margin-left: .17rem;
font-size: .08rem;
color: #000;
}
.white {
width: 1.61rem;
margin-left: .17rem;
font-size: .08rem;
color: white;
}
}
.btn-box-active {
width: 100%;
height: 1.35rem;
border-radius: .21rem;
display: flex;
background-color: #4696e9;
justify-content: center;
align-items: center;
}
}
}
.nextStep {
display: flex;
align-content: center;
justify-content: center;
flex-direction: column;
margin-top: .38rem;
.nextStepTitle {
font-size: .08rem;
letter-spacing: 0rem;
line-height: .16rem;
color: rgba(25, 151, 240, 1);
text-align: center;
}
.nextStepBtn {
margin: 0 auto;
width: 2.85rem;
height: .38rem;
opacity: 1;
border-radius: .21rem;
margin-top: .07rem;
.tiny-button {
width: 2.85rem;
height: .24rem;
margin: 0 auto;
font-size: .11rem;
border-radius: .13rem;
}
}
}
}
</style>>
vue3实现录音并播放
最新推荐文章于 2024-06-18 09:23:11 发布