最近研究通过h5+的API录制视频用作人脸识别,编写了一个demo,附上源码,分享一下。
<!DOCTYPE html>
<!-- saved from url=(0075)https://wendychengc.github.io/media-recorder-video-canvas/cameracanvas.html -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MediaRecorder使用示例</title>
<style>
canvas {
box-shadow: 0 0 10px gray;
display: block;
}
.rect-box{
width: 460px;
height: 460px;
/*border: 1px solid #ccc;*/
box-sizing: border-box;
position: relative;
}
.rect{
width: 230px;
height: 460px;
box-sizing: border-box;
position: absolute;
overflow:hidden;
top: 0;
}
.left{
left: 0;
}
.right{
right: 0;
}
.rect > div{
width: 460px;
height: 460px;
border:20px solid transparent;
border-radius: 50%;
box-sizing: border-box;
position: absolute;
top:0;
z-index: 3;
transform: rotate(45deg);
}
.right .circle{
border-top:20px solid #999;
border-right:20px solid #999;
border-left:20px solid rgb(81, 197, 81);
border-bottom:20px solid rgb(81, 197, 81);
right:0;
-webkit-animation: right 12s linear 1;
}
.left .circle{
border-bottom:20px solid #999;
border-left:20px solid #999;
left:0;
-webkit-animation: left 12s linear 1;
}
@-webkit-keyframes right{
0%{
border-left:20px solid rgb(182, 239, 182);
border-bottom:20px solid rgb(182, 239, 182);
-webkit-transform: rotate(45deg);
}
50%{
border-left:20px solid rgb(81, 197, 81);
border-bottom:20px solid rgb(81, 197, 81);
-webkit-transform: rotate(45deg);
}
84%{
border-left:20px solid green;
border-bottom:20px solid green;
-webkit-transform: rotate(225deg);
}
100%{
border-left:20px solid green;
border-bottom:20px solid green;
-webkit-transform: rotate(225deg);
}
}
@-webkit-keyframes left{
0%{
border-top:20px solid rgb(81, 197, 81);
border-right:20px solid rgb(81, 197, 81);
-webkit-transform: rotate(45deg);
}
16%{
border-top:20px solid rgb(81, 197, 81);
border-right:20px solid rgb(81, 197, 81);
-webkit-transform: rotate(45deg);
}
50%{
border-top:20px solid rgb(81, 197, 81);
border-right:20px solid rgb(81, 197, 81);
-webkit-transform: rotate(225deg);
}
100%{
border-top:20px solid green;
border-right:20px solid green;
-webkit-transform: rotate(225deg);
}
}
.tip{
font-size: 60px;
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
}
.face-box{
text-align: center;
margin:10px auto;
border-radius: 50%;
height:460px;
width:460px;
overflow:hidden;
position:relative
}
</style></head>
<body>
<div style="text-align: center;">
<div class="tip" id="tip"></div>
<div class="face-box">
<div class="rect-box">
<div class="rect left">
<div class="circle"></div>
</div>
<div class="rect right">
<div class="circle"></div>
</div>
<canvas id="canvas" height="460" width="460" style="margin:auto;"></canvas>
<video src="" id="srcvideo" style="display:none;"></video>
</div>
</div>
<script>
var allChunks = [];
if(navigator.mediaDevices){
init();
}else{
alert("请使用其他方式验证")
}
function init() {
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
navigator.mediaDevices.getUserMedia({
video: true
})
.then(function(mediaStream) {
var srcvideo = document.getElementById("srcvideo")
srcvideo.srcObject = mediaStream;
srcvideo.play()
playCanvas(srcvideo, ctx)
})
setFormatSelect('video/webm;codecs=h264')
}
function playCanvas(srcvideo, ctx) {
ctx.drawImage(srcvideo, 0, 0, 460, 460)
requestAnimationFrame(() => {
playCanvas(srcvideo, ctx)
})
}
function setFormatSelect(format){
if(!MediaRecorder.isTypeSupported(format)){
alert(format)
alert("当前浏览器不支持该编码类型");
return;
}
allChunks = [];
setRecorder(format)
}
function blobToBase64(blob){
return new Promise((resolve, reject) => {
const fileReader = new FileReader()
fileReader.onload = (e) => {
resolve(e.target.result)
}
fileReader.readAsDataURL(blob)
fileReader.onerror = () => {
reject(new Error('blobToBase64 error'))
}
})
}
function setRecorder(format) {
const stream = canvas.captureStream(40); // 60 FPS recording
const recorder = new MediaRecorder(stream, {
mimeType: format
});
recorder.ondataavailable = e => {
allChunks.push(
e.data
);
}
recorder.start(10)
tip.innerHTML="请将人脸放进方框内"
setTimeout(function(){
tip.innerHTML="开始录制..."
},2000)
setTimeout(function(){
tip.innerHTML="笑一笑"
},4000)
setTimeout(function(){
tip.innerHTML="眨一眨眼"
},7000)
setTimeout(function(){
recorder.stop()
tip.innerHTML="录制结束,正在验证..."
},10000)
setTimeout(function(){
const fullBlob = new Blob(allChunks)
blobToBase64(fullBlob).then((res) => {
console.log('base64', res)
})
},12000)
}
</script>
</body></html>