<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>
Interviewer.vue
最新推荐文章于 2024-09-14 19:44:09 发布