赞
踩
- <!-- 听说组件 -->
- <template>
- <div class="lestening-speaking-container">
- <p class="middleSizeBlob">Type the statement that you hear.</p>
- <img style="width: 1.32rem;height:1.24rem;margin-top: .07rem;" src="../assets/images/secondary/lesting.png" alt="">
-
- <!-- <p><span>可播放次数:</span><span style="color: #4581e1;font-weight: blob;">{{ count }}</span></p> -->
- <div class="btn-trim">
- <!-- <tiny-button type="primary" :disabled="disabled" :icon="iconStartCircle" @click="Play"> Play </tiny-button> -->
- <span>{{ audioData.starTime }} / {{ audioData.endTime }}</span>
- <audio src="" :muted="audioData.muted"></audio>
- </div>
- <div class="function-box">
- <canvas id="canvas"></canvas>
- <canvas id="playChart"></canvas>
- <tiny-button :disabled="disabled" type="primary" native-type="submit" @click="nextStep"> Speaking/Stop
- </tiny-button>
- </div>
-
- <tiny-dialog-box v-model:visible="dialogData.visible" top="42%" title="音频将在倒计时结束后自动播放" width="30%">
- <span style="font-size: .14rem;font-weight: 700;">{{ dialogData.countNum }}</span>
- </tiny-dialog-box>
- </div>
- </template>
- <script setup>
- import { ref, reactive, onMounted } from 'vue'
- import { Button as TinyButton, DialogBox as TinyDialogBox } from '@opentiny/vue'
- import Recorder from 'js-audio-recorder'
- const lamejs = require('lamejs')
- // 子组件向父组件传参数
- const emits = defineEmits(['nextQuestion'])
-
- onMounted(() => {
- data.startCanvas()
- data.voice()
- })
-
- // 录音所需的信息
- const data = reactive({
- //用于存储创建的语音对象
- recorder: new Recorder({
- sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
- sampleRate: 48000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
- numChannels: 1, // 声道,支持 1 或 2, 默认是1
- // compiling: false,(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
- }),
- formData: null,
- // 控制录音动画的显示隐藏
- showAnima: false,
- mation: true,
- isHistory: true,
- soundSize: 0,
- // 录音时长
- duration: 0,
-
- //波浪图-录音
- drawRecordId: null,
- oCanvas: null,
- ctx: null,
- //波浪图-播放
- drawPlayId: null,
- pCanvas: null,
- pCtx: null,
- startCanvas() {
- //录音波浪
- data.oCanvas = document.getElementById('canvas');
- data.ctx = data.oCanvas.getContext("2d");
- //播放波浪
- data.pCanvas = document.getElementById('playChart');
- data.pCtx = data.pCanvas.getContext("2d");
- },
- drawRecord() {
- // 用requestAnimationFrame稳定60fps绘制
- data.drawRecordId = requestAnimationFrame(data.drawRecord);
-
- // 实时获取音频大小数据
- // console.log(data.recorder.getRecordAnalyseData())
- // return
- let dataArray = data.recorder.getRecordAnalyseData()
- let bufferLength = dataArray.length;
-
- // 填充背景色
- data.ctx.fillStyle = 'rgb(200, 200, 200)';
- data.ctx.fillRect(0, 0, data.oCanvas.width, data.oCanvas.height);
-
- // 设定波形绘制颜色
- data.ctx.lineWidth = 2;
- data.ctx.strokeStyle = 'rgb(0, 0, 0)';
-
- data.ctx.beginPath();
-
- var sliceWidth = data.oCanvas.width * 1.0 / bufferLength, // 一个点占多少位置,共有bufferLength个点要绘制
- x = 0; // 绘制点的x轴位置
-
- for (var i = 0; i < bufferLength; i++) {
- var v = dataArray[i] / 128.0;
- var y = v * data.oCanvas.height / 2;
-
- if (i === 0) {
- // 第一个点
- data.ctx.moveTo(x, y);
- } else {
- // 剩余的点
- data.ctx.lineTo(x, y);
- }
- // 依次平移,绘制所有点
- x += sliceWidth;
- }
-
- data.ctx.lineTo(data.oCanvas.width, data.oCanvas.height / 2);
- data.ctx.stroke();
- },
-
- 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().then(() => {
- data.drawRecord();//开始绘制图片
- }, (error) => {
- // 出错了
- console.log(`${error.name} : ${error.message}`);
- }); // 开始录音
- data.recorder.onprogress = function (params) {
- // console.log('录音时长(秒)', params.duration);
- // console.log('录音大小(字节)', params.fileSize);
- data.soundSize = params.vol
- // console.log('录音音量百分比(%)', params.vol);
- // console.log('当前录音的总数据([DataView, DataView...])', params.data);
- }
- }, (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 audioData = reactive({
- starTime: '00:00',
- endTime: '00:00',
- muted: true,
- })
-
- // 弹出层的信息
- const dialogData = reactive({
- visible: false,
- countNum: 2,
- })
-
- // 录音和停止录音的的按钮
- const disabled = ref(true)
-
- // 点击按钮时触发
- function nextStep() {
- emits('nextQuestion')
- }
-
- </script>
- <style lang="scss" scoped>
- .lestening-speaking-container {
- width: 100%;
- height: 100%;
- text-align: center;
- font-size: .11rem;
- border: 1px solid red;
-
- .btn-trim {
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: .1rem;
- font-weight: normal;
- height: .18rem;
- margin-top: .14rem;
-
- .tiny-button {
- width: .72rem;
- height: .18rem;
- // margin: 0 auto;
- font-size: .08rem;
- border-radius: .1rem;
- font-weight: 700;
- margin-top: .04rem;
- margin-right: .04rem;
- }
-
- ::v-deep .tiny-svg {
- width: .1rem !important;
- height: .1rem !important;
- }
- }
-
- .function-box {
- width: 5.59rem;
- height: 1.15rem;
- opacity: 1;
- background: rgba(252, 252, 252, 0.94);
- box-shadow: 0rem .01rem .03rem rgba(0, 0, 0, 0.25);
- margin: .07rem auto 0rem;
-
- #playChart,
- #canvas {
- height: .28rem;
- width: 100%;
- border: 1px solid aqua;
- margin-top: .29rem;
-
- }
-
- .tiny-button {
- width: 1.42rem;
- height: .24rem;
- margin: .21rem auto 0;
- font-size: .11rem;
- border-radius: .13rem;
- }
- }
-
- ::v-deep .tiny-dialog-box__body {
- padding-bottom: .21rem;
- text-align: center;
- }
-
- ::v-deep .tiny-dialog-box__headerbtn {
- display: none;
- }
- }
- </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。