在这篇文章中,我将向您展现如何经过JavaScript在网页上访问设备的摄像头,并支持多种浏览器,而无需外部库。javascript
要访问用户的相机(或麦克风),咱们使用JavaScript MediaStream API。该API容许经过流访问这些设备捕获的视频和音频。html
第一步是检查浏览器是否支持此API:前端
if ( "mediaDevices" in navigator && "getUserMedia" in navigator.mediaDevices ) { // ok, 浏览器支持它 }
在现代浏览器中,支持是不错的(固然没有Internet Explorer)。java
要捕获由摄像机生成的视频流,咱们使用 mediaDevices
对象的 getUserMedia
方法。这个方法接收一个对象,其中包含咱们要请求的媒体类型(视频或音频)和一些要求。首先,咱们能够经过 {video: true}
来获取摄像机的视频。canvas
const videoStream = await navigator.mediaDevices.getUserMedia({ video: true });
此调用将询问用户是否容许访问摄像机。若是用户拒绝,它将引起异常而且不返回流。所以,必须在 try/catch
块内完成处理这种状况。api
请注意,它返回一个Promise,所以您必须使用 async/await
或 then
块。在Mac OS系统上还会弹出受权浏览器
点击“好”,就能够访问电脑摄像头了,控制台输出的 videoStream
对象以下async
咱们能够经过传递有关所需分辨率以及最小和最大限制的信息来改善视频的要求:ide
const constraints = { video: { width: { min: 1280, ideal: 1920, max: 2560, }, height: { min: 720, ideal: 1080, max: 1440, }, }, }; const videoStream = await navigator.mediaDevices.getUserMedia(constraints);
这样,流以正确的宽度和高度比例进入,若是它是处于纵向模式的手机,则须要进行尺寸反转。ui
既然有了流,咱们该如何处理?
咱们能够在页面上的 video
元素中显示视频:
// 页面中有一个 <video autoplay id="video"></video> 标签 const video = document.querySelector("#video"); const videoStream = await navigator.mediaDevices.getUserMedia(constraints); video.srcObject = videoStream;
请注意 video
标签中的自动播放属性 autoplay
,没有它,你须要调用 video.play()
才能真正开始显示图像。
默认状况下,getUserMedia
将使用系统默认的视频录制设备。若是是有两个摄像头的手机,它使用前置摄像头。
要访问后置摄像头,咱们必须在视频规格中包括 faceModeMode:"environment"
:
const constraints = { video: { width: { ... }, height: { ... }, facingMode: "environment" }, };
默认值为 faceingMode:"user"
,即前置摄像头。
须要注意的是,若是你想在已经播放视频的状况下更换摄像机,你须要先中止当前的视频流,而后再将其替换成另外一台摄像机的视频流。
videoStream.getTracks().forEach((track) => { track.stop(); });
你能够作的另外一件很酷的事情是捕获视频的图像(屏幕快照)。
你能够在canvas上绘制当前视频帧,例如:
// 页面中有一个 <canvas id="canvas"></canvas> 标签 const canvas = document.querySelector("#canvas"); canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext("2d").drawImage(video, 0, 0);
你还能够在 img
元素中显示画布内容。
在本教程建立的示例中,我添加了一个按钮,该按钮可从画布动态建立图像并将其添加到页面:
const img = document.createElement("img"); img.src = canvas.toDataURL("image/png"); screenshotsContainer.prepend(img);
在线效果及源代码:https://coding.zhangbing.site...
本文首发于公众号《前端全栈开发者》ID:by-zhangbing-dev,第一时间阅读最新文章,会优先两天发表新文章。关注后私信回复:大礼包,送某网精品视频课程网盘资料,准能为你节省很多钱!