03.浏览器打开摄像头
1、概念
navigator.mediaDevices.getUserMedia是一个Web API,用于在浏览器中获取访问音频和视频设备的权限,从而进行媒体的捕获。具体来说,它可以用于在网页上实时获取用户的摄像头和麦克风。
它返回一个 Promise
对象,成功后会resolve
回调一个 MediaStream
对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promise
会reject
回调一个 PermissionDeniedError
或者 NotFoundError
。
ps: 返回的 promise 对象可能既不会 resolve 也不会 reject,因为用户不是必须选择允许或拒绝。
2、语法
navigator.mediaDevices .getUserMedia(constraints) .then(function (stream) { /* 使用这个 stream stream */ }) .catch(function (err) { /* 处理 error */ });
3、参数
constraints
onstraints 参数是一个包含了video
和 audio
两个成员的MediaStreamConstraints
对象,用于说明请求的媒体类型。必须至少一个类型或者两个同时可以被指定。如果浏览器无法找到指定的媒体类型或者无法满足相对应的参数要求,那么返回的 Promise 对象就会处于 rejected[失败]状态,NotFoundError
作为 rejected[失败]回调的参数。
以下同时请求不带任何参数的音频和视频:
{ audio: true, video: true }
设置分辨率
浏览器会试着满足这个请求参数,但是如果无法准确满足此请求中参数要求或者用户选择覆盖了请求中的参数时,有可能返回其他的分辨率。
{ audio: true, video: { width: 1280, height: 720 } }
强制要求获取特定的尺寸时,可以使用关键字min
、max
或者 exact
(就是 min == max)。以下参数表示要求获取最低为 1280x720 的分辨率。
{ audio: true, video: { width: { min: 1280 }, height: { min: 720 } } }
如果摄像头不支持请求的或者更高的分辨率,返回的 Promise 会处于 rejected 状态,NotFoundError 作为
rejected 回调的参数,而且用户将不会得到要求授权的提示。
造成不同表现的原因是,相对于简单的请求值和ideal
关键字而言,关键字min
, max
, 和 exact
有着内在关联的强制性,请看一个更详细的例子:
{ audio: true, video: { width: { min: 1024, ideal: 1280, max: 1920 }, height: { min: 776, ideal: 720, max: 1080 } } }
当请求包含一个 ideal(应用最理想的)值时,这个值有着更高的权重,意味着浏览器会先尝试找到最接近指定的理想值的设定或者摄像头(如果设备拥有不止一个摄像头)。
简单的请求值也可以理解为是应用理想的值,因此我们的第一个指定分辨率的请求也可以写成如下:
{ audio: true, video: { width: { ideal: 1280 }, height: { ideal: 720 } } }
并不是所有的 constraints 都是数字。例如,在移动设备上面,如下的例子表示优先使用前置摄像头(如果有的话):
{ audio: true, video: { facingMode: "user" } }
强制使用后置摄像头,请用:
{ audio: true, video: { facingMode: { exact: "environment" } } }
4、返回值
返回一个 Promise
,这个 Promise 成功后的回调函数带一个 MediaStream
对象作为其参数。
5、示例
<!DOCTYPE html> <html> <body> <video id="local-video" autoplay playsinline></video> <button id="showVideo">打开摄像头</button> <p>通过getUserMedia()获取视频</p> </body> <script> const constraints = { audio:true, video:true }; function onOpenCamera(e){ navigator.mediaDevices.getUserMedia(constraints).then(stream=>{ const video = document.querySelector("#local-video"); video.srcObject = stream; }).catch(err=>{ }); } document.querySelector("#showVideo").addEventListener("click",onOpenCamera); </script> </html>
备注:在video标签里面加muted属性可以不到自己声音,但声音是有在音视流里面
效果:
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia