js获取相机信息,并输入到video,同时绘制到canvas上,性能实现如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Demo</title>
<style>
body { margin: 0; }.container { height: 150px; background: #f4f4f4;}input { margin: 20px; display: inline-block;}video { position: fixed; top: 30%; left: 50%; transform: translate(-50%, -50%); display: none;}#canvas2 { position: fixed; top: 60%; left: 50%; transform: translate(-50%, -50%); display: none;}
</style>
<!-- vconsole引入 -->
<script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
<script type="text/javascript">
new VConsole()
</script>
</head>
<body>
<div class="container">
<input type="button" title="开启摄像头" value="开启摄像头" muted onclick="getMedia();" />
<input type="button" title="切换摄像头" value="切换摄像头" muted onclick="changeMode();" />
<video
height="120px" autoplay="autoplay" x5-video-player-type="h5-page" playsinline="true" webkit-playsinline="true" x5-video-ignore-metadata="false" x5-video-player-fullscreen="false" x5-video-player-orientation="landscape"
</video>
<!-- <input type="button" title="视频" value="视频绘制" onclick="getVideo();" />
-->
<canvas id="canvas2"></canvas>
</div>
<script>
// 老的浏览器可能基本没有实现 mediaDevices,所以咱们能够先设置一个空的对象if (navigator.mediaDevices === undefined) { navigator.mediaDevices = {};}// 一些浏览器局部反对 mediaDevices。咱们不能间接给对象设置 getUserMedia// 因为这样可能会笼罩已有的属性。这里咱们只会在没有getUserMedia属性的时候增加它。if (navigator.mediaDevices.getUserMedia === undefined) { navigator.mediaDevices.getUserMedia = function(constraints) { // 首先,如果有getUserMedia的话,就取得它 var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; // 一些浏览器基本没实现它 - 那么就返回一个error到promise的reject来放弃一个对立的接口 if (!getUserMedia) { return Promise.reject(new Error('getUserMedia is not implemented in this browser')); } // 否则,为老的navigator.getUserMedia办法包裹一个Promise return new Promise(function(resolve, reject) { getUserMedia.call(navigator, constraints, resolve, reject); }); }}var video = document.querySelector('video');var audio, audioType;var canvas2 = document.getElementById('canvas2');var context2 = canvas2.getContext('2d');var mode = 'user'var streamDatafunction getMedia() { if (navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia({ 'video': { frameRate: { ideal: 10, max: 15 }, facingMode: mode }, 'audio':false }).then(successFunc).catch(errorFunc) } else { alert('Native device media streaming (getUserMedia) not supported in this browser.'); }}function successFunc(stream) { streamData = stream if (video.mozSrcObject !== undefined) { //Firefox中,video.mozSrcObject最后为null,而不是未定义的,咱们能够靠这个来检测Firefox的反对 video.mozSrcObject = stream; } else if ('srcObject' in video) { console.log('srcObject') video.srcObject = stream; } else { console.log('src') // 避免在新的浏览器里应用它,应为它曾经不再反对了 video.src = window.URL.createObjectURL(stream); } video.style.display = 'block'; getVideo() video.onloadedmetadata = function(e) { console.log('onloadedmetadata') // video.play(); }; // 音频 // audio = new Audio(); // audioType = getAudioType(audio); // if (audioType) { // audio.src = 'polaroid.' + audioType; // audio.play(); // }}function errorFunc(e) { console.log('获取资源谬误', e)}// 切换摄像头function changeMode() { mode = mode === 'user' ? 'environment' : 'user' streamData.getTracks()[0].stop() getMedia()}//获取音频格式function getAudioType(element) { if (element.canPlayType) { if (element.canPlayType('audio/mp4; codecs="mp4a.40.5"') !== '') { return ('aac'); } else if (element.canPlayType('audio/ogg; codecs="vorbis"') !== '') { return ("ogg"); } } return false;}//视频function getVideo() { drawVideoAtCanvas(video, context2);}// 将视频帧绘制到Canvas对象上,Canvas每60ms切换帧,造成肉眼视频成果function drawVideoAtCanvas(video, context2) { canvas2.style.display = 'block'; window.setInterval(function () { var w = parseInt(getComputedStyle(video).width) var h = parseInt(getComputedStyle(video).height) var x = (parseInt(getComputedStyle(canvas2).width) - w) / 2 context2.drawImage(video, x, 0, w, h); }, 60);}
</script>
</body>
</html>
踩坑指南:
1、iOS不反对裁剪绘制到canvas上
2、兼容性如下:
android: 局部浏览器只能关上前置摄像头,反对双向的浏览器切换摄像头前须要先将原mideaStream暂停;
ios:初始化和切换均可实现;