如何在 PWA 中访问相机
已发表: 2020-08-19目录
以前在我们详细介绍 PWA 的硬件功能的文章中介绍过,摄像头访问是我们越来越多地看到的更突出的功能之一。 但是要将这种能力正确地集成到你的 PWA 中也不是一件容易的事,这就是为什么在我们今天的文章中,我们将尝试引导你完成整个过程:
先决条件
- 可以使用 ReactJS 和我们的书面指南轻松创建的基本 PWA
- 对 HTML 和 JavaScript 有扎实的理解
如何在 PWA 中访问相机
基础知识
介绍getUserMedia() — webRTC 的 API
为了直接访问摄像头和/或麦克风,Web 使用了一个名为getUserMedia()的 API,几乎所有现代浏览器都广泛支持该 API。 此 API 以及RTCPeerConnection和RTCDataChannel是 WebRTC 的一部分——WebRTC 是一个内置于浏览器中的框架,可以实现实时通信。
基本上,API ( navigator.mediaDevices.getUserMedia(constraints) ) 的作用是提示用户允许访问电话的音频和视频输入(例如,麦克风、网络摄像头、摄像头等)。 使用该权限,API 会生成一个名为local的MediaStream JavaScript 对象,该对象可以进一步操作。
例子
比如说,我们有一个按钮:
<button>露出我的脸</button>
并单击哪个按钮调用navigator.mediaDevices.getUserMedia()方法(无音频输入):
navigator.mediaDevices.getUserMedia({
视频:真实
})哎呀,我们也可以疯狂地使用约束:
navigator.mediaDevices.getUserMedia({
视频: {
最小纵横比:1.333,
最小帧率:30,
宽度:1280,
身高:720
}
}) 此外,我们可以在 video 对象中指定facingMode属性,它告诉浏览器使用设备的哪个摄像头:
{
视频: {
...
面对模式:{
//使用后置摄像头
确切的:'环境'
}
}
}或者
{
视频 : {
…
//使用前置摄像头
面对模式:'用户'
}
}备注:
- API 仅在安全来源 (HTTPS) 上可用
- 要获取当前设备上支持的约束列表,请运行:
navigator.mediaDevices.getSupportedConstraints()
复杂的部分
现在我们已经对基础有了扎实的了解,让我们继续进行高级部分。 在这一部分中,我们将尝试在 PWA 中创建一个按钮,单击该按钮后,它会打开我们的相机并让我们做进一步的工作。
创建[Get access to camera]按钮
首先,让我们从 index.html 中的<button>开始:
<button>访问相机</button> <视频自动播放></video> <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
注:

- 自动播放用于告诉媒体流自动播放而不是在第一帧冻结。
- adapter-latest.js 是一个垫片,用于将应用程序与规范更改和前缀差异隔离开来。
通过单击按钮实时流式传输视频
要在单击按钮时实时流式传输视频,我们需要添加一个EventListener ,它会在发出click事件时调用:
document.querySelector('#get-access').addEventListener('click', async function init(e) {
尝试 {
}
捕捉(错误){
}
}) 之后,它调用navigator.mediaDevices.getUserMedia()并使用设备的网络摄像头请求视频流:
document.querySelector('#get-access').addEventListener('click', async function init(e) {
尝试 {
常量流 = 等待 navigator.mediaDevices.getUserMedia({
音频:假,
视频:真实
})
常量 videoTracks = stream.getVideoTracks()
常量轨道 = videoTracks[0]
alert(`从 ${track.label} 获取视频`)
document.querySelector('video').srcObject = 流
document.querySelector('#get-access').setAttribute('hidden', true)
//视频流在播放3秒后被track.stop()停止。
setTimeout(() => { track.stop() }, 3 * 1000)
} 捕捉(错误){
警报(`${error.name}`)
控制台.错误(错误)
}
})此外,如上文“基本”部分所述,您还可以为视频流指定更多要求:
navigator.mediaDevices.getUserMedia({
视频: {
强制:{ minAspectRatio: 1.333, maxAspectRatio: 1.334, facesMode: 'user'},
可选的: [
{ minFrameRate: 60 },
{ 最大宽度:640 },
{ 最大高度:480 }
]
}
},成功回调,错误回调);创建画布
将<video>元素与<canvas>结合使用,您可以进一步处理我们的实时视频流。 这包括执行各种效果的能力,例如应用自定义滤镜、色度键控(又名“绿屏效果”)——所有这些都使用 JavaScript 代码。
如果您想了解更多有关此内容的信息,Mozilla 编写了有关使用画布操作视频的详细指南,因此请不要忘记查看!
使用takePhoto()和grabFrame()捕捉画布的快照
getUserMedia API 的新takePhoto和grabFrame方法可用于捕获当前流视频的快照。 两种方法之间仍然存在显着差异:
基本上, grabFrame所做的只是抓取下一个视频帧——这是一种简单且不那么有效的拍照方法。 另一方面, takePhoto方法使用一种更好的捕获帧的方法,即通过中断当前视频流来使用相机的“最高可用摄影相机分辨率”来捕获 Blob 图像。
在下面的示例中,我们将使用grabFrame方法将捕获的帧绘制到canvas元素中:
var grabFrameButton = document.querySelector('button#grabFrame');
var canvas = document.querySelector('canvas');
grabFrameButton.onclick = grabFrame;
函数抓取帧(){
imageCapture.grabFrame()
.then(函数(imageBitmap){
console.log('抓取的帧:', imageBitmap);
canvas.width = imageBitmap.width;
canvas.height = imageBitmap.height;
canvas.getContext('2d').drawImage(imageBitmap, 0, 0);
canvas.classList.remove('隐藏');
})
.catch(函数(错误){
console.log('grabFrame() 错误:',错误);
});
} 在这个例子中,我们使用了takePhoto()方法:
var takePhotoButton = document.querySelector('button#takePhoto');
var canvas = document.querySelector('canvas');
takePhotoButton.onclick = 拍照;
// 从当前选择的相机源中获取一个 Blob 和
// 用 img 元素显示它。
功能拍照(){
imageCapture.takePhoto().then(function(blob) {
console.log('拍照:', blob);
img.classList.remove('隐藏');
img.src = URL.createObjectURL(blob);
}).catch(函数(错误){
console.log('takePhoto() 错误:',错误);
});
}要了解上述方法的实际效果,我们建议使用 Simple Image Capture; 或者,PWA 媒体捕获也是 PWA 中基本媒体捕获功能的一个很好的例子。
结论
在本教程中,我们向您介绍了在 PWA 中实现相机功能的基础知识和一些高级技巧。 其余的只是您的想象力,以充分利用此功能。
对于希望开发下一代 PWA 支持的商店的 Magento 商家,在 SimiCart 中,我们根据您的需求提供完整的 PWA 解决方案。
