Interviewer.vue

20 篇文章 0 订阅
2 篇文章 0 订阅
<template>
	<el-card class="interviewer" style="height: 350px; border-radius: 0px; box-shadow: none;">
		<div style="text-align: center;">
			<video v-if="recordtype !== 'END'" id="video" autoplay ref="videos" style="width: 320px; height: 240px;"
				muted></video>
			<video v-else style="width: 320px; height: 240px;" id="videosreplay" src="" ref="videosreplay"
				@click="toggleReplayVideo" @ended="resetReplay"></video>
		</div>
		<div style="text-align: center; margin-top: 20px;">
			<el-button type="primary" @click="toggleRecording">{{ buttonText }}</el-button>
		</div>
	</el-card>
</template>

<script>
	import axios from 'axios';
	import fixWebmDuration from 'webm-duration-fix';
	import emitter from "../api/bus.js";

	export default {
		data() {
			return {
				progress: 0,
				replayVideo: false,
				recordtype: 'BEGIN',
				timer: null,
				recordtime: 0,
				second: 0,
				minute: 0,
				hour: 0,
				playtime: 0,
				playtimer: null,
				buttonText: '开始面试',

			};
		},
		mounted() {
			this.initializeMediaUtils();
		},
		methods: {
			initializeMediaUtils() {
				this.MediaUtils = {
					getUserMedia: (videoEnable, audioEnable, callback) => {
						navigator.getUserMedia =
							navigator.getUserMedia ||
							navigator.webkitGetUserMedia ||
							navigator.mozGetUserMedia ||
							navigator.msGetUserMedia ||
							window.getUserMedia;
						const constraints = {
							video: videoEnable,
							audio: audioEnable,
						};
						if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
							navigator.mediaDevices
								.getUserMedia(constraints)
								.then((stream) => {
									callback(false, stream);
								})
								.catch((err) => {
									callback(err);
								});
						} else if (navigator.getUserMedia) {
							navigator.getUserMedia(
								constraints,
								(stream) => {
									callback(false, stream);
								},
								(err) => {
									callback(err);
								}
							);
						} else {
							callback(new Error('Not support userMedia'));
						}
					},
					closeStream: (stream) => {
						if (typeof stream.stop === 'function') {
							stream.stop();
						} else {
							const trackList = [stream.getAudioTracks(), stream.getVideoTracks()];

							for (let i = 0; i < trackList.length; i++) {
								const tracks = trackList[i];
								if (tracks && tracks.length > 0) {
									for (let j = 0; j < tracks.length; j++) {
										const track = tracks[j];
										if (typeof track.stop === 'function') {
											track.stop();
										}
									}
								}
							}
						}
					},
				};
			},
			async callCamera() {
				try {
					await this.MediaUtils.getUserMedia(true, true, (err, stream) => {
						if (err) {
							throw err;
						} else {
							const mimeType = 'video/webm;codecs=vp8,opus';
							mediaRecorder = new MediaRecorder(stream, {
								mimeType,
							});
							mediaStream = stream;
							const chunks = [];
							const video = this.$refs.videos;

							if (video) {
								video.srcObject = stream;
								video.play();

								mediaRecorder.ondataavailable = (e) => {
									mediaRecorder.blobs.push(e.data);
									chunks.push(e.data);
								};
								mediaRecorder.blobs = [];

								mediaRecorder.onstop = async () => {
									recorderFile = await fixWebmDuration(
										new Blob(chunks, {
											type: mimeType,
										})
									);
									const url = URL.createObjectURL(recorderFile);
									const videosreplay = this.$refs.videosreplay;

									if (videosreplay) {
										videosreplay.setAttribute('src', url);
									}

									chunks.length = 0;

									if (stopRecordCallback) {
										stopRecordCallback();
									}

									this.download();
								};
								this.startRecording();
							}
						}
					});
				} catch (error) {
					this.$message.error(error.message);
				}
			},
			toggleRecording() {
				if (this.recordtype === 'ING') {
					this.stopRecord(() => {
						emitter.emit('isAction', false);
						this.buttonText = '开始面试';

					});
				} else if (this.recordtype === 'BEGIN') {
					emitter.emit('isAction', true);
					this.callCamera();
					this.buttonText = '结束面试';
				}
			},
			startRecording() {
				console.log('开始面试');
				this.startAudio();
				mediaRecorder.start();
				startTime = Date.now();
				this.recordtype = 'ING';
			},
			startAudio() {
				this.timer = setInterval(() => {
					this.recordtime += 1000;
					if (this.recordtime === 1000000) {
						this.stopRecord();
					}
					this.second++;
					if (this.second >= 60) {
						this.second = 0;
						this.minute += 1;
					}
					if (this.minute >= 60) {
						this.minute = 0;
						this.hour += 1;
					}
				}, 1000);
			},
			stopRecord(callback) {
				this.recordtype = 'END';
				stopRecordCallback = callback;
				clearInterval(this.timer);
				mediaRecorder.stop();
				this.MediaUtils.closeStream(mediaStream);
				const videosreplay = this.$refs.videosreplay;
				if (videosreplay) {
					videosreplay.onended = () => {
						this.resetReplay();
					};
				}
			},
			toggleReplayVideo() {
				this.replayVideo = !this.replayVideo;
				const videosreplay = this.$refs.videosreplay;
				if (videosreplay) {
					if (this.replayVideo) {
						videosreplay.play().catch((err) => {
							this.$message.error(err.message);
						});
						this.playtimer = setInterval(() => {
							this.playtime += 1000;
						}, 1000);
					} else {
						videosreplay.pause();
						clearInterval(this.playtimer);
					}
				}
			},
			resetReplay() {
				this.playtime = 0;
				this.replayVideo = false;
				clearInterval(this.playtimer);
			},
			download() {
				const url = URL.createObjectURL(recorderFile);
				const a = document.createElement('a');
				document.body.appendChild(a);
				a.style.display = 'none';
				a.href = url;
				a.download = `${new Date().toISOString()}.mp4`;
				a.click();
				window.URL.revokeObjectURL(url);
			},
			submit() {
				this.download();
				const file = new File([recorderFile], `msr-${new Date().toISOString().replace(/:|\./g, '-')}.mp4`, {
					type: 'video/mp4',
				});
				const formdata = new FormData();
				formdata.append('file', file);
			},
		},
	};
	var startTime, mediaRecorder, mediaStream, stopRecordCallback, recorderFile;
</script>

<style scoped>
	.interviewer {
		margin: auto;
		border: 1px solid #ebeef5;
		border-radius: 4px;
		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
	}

	video {
		background-image: url('../../public/img/audio.png');
	}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Adellle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值