vue webrtc
Both iOS and Android OS allow users to add websites to their home screen like bookmarks. If these websites were built as Progressive Web Apps (PWA) they could also really feel native. I was aware of this but never really pursued it because iOS home screen apps were lacking support for WebRTC (access to the camera and microphone.) Well, you can just about imagine my surprise when I found out that support was added in a recent update to iOS. I quickly revisited and rebuilt my “CAMERA” app from 2018 and was very happy with the results.
iOS和Android OS均允许用户将网站(如书签)添加到其主屏幕。 如果这些网站是作为渐进式Web应用程序 (PWA)构建的,那么它们也可能真的很原生。 我意识到了这一点,但从未真正追求它,因为iOS主屏幕应用程序缺少对WebRTC (访问摄像头和麦克风)的支持。嗯,当我发现最近更新中添加了支持时,您可以想象我的惊讶到iOS。 从2018年起,我Swift回顾并重建了我的“ CAMERA”应用程序,并对结果感到非常满意。
In this blog, I’d like to share my approach for building the simplest PWA camera and hopefully it will serve as a base for your own experiments. Be sure to check out and fork the companion CodePen so you can build your own camera.
在此博客中,我想分享我构建最简单的PWA相机的方法,并希望它将作为您自己实验的基础。 请务必签出并插入配套的CodePen,以便您可以构建自己的相机。
用户旅程 (User Journey)
The user journey is broken down into three parts. When the user initially lands on the application, they will see an intro. This helps establish the functionality of the camera and also allows you to prepare the user for granting access to their device’s camera.
用户旅程分为三个部分。 当用户最初登陆应用程序时,他们会看到一个介绍。 这有助于建立摄像头的功能,还允许您准备授予用户访问其设备摄像头的权限。
Once the user grants access, we’ll redirect them directly to the camera itself. At the very least, this screen should provide a capture button fixed to the bottom center of the screen. Depending on your concept, you may want to try displaying the video feed itself in interesting ways. In the case of this simple example, I’ll be displaying it full bleed.
用户授予访问权限后,我们会将其直接重定向到摄像机本身。 至少,此屏幕应提供一个固定在屏幕底部中央的捕获按钮。 根据您的概念,您可能想尝试以有趣的方式显示视频供稿本身。 在这个简单的例子中,我将显示它的完整出血。
When the user taps the capture button, we’ll bring up the download screen which shows them a preview of the photo they just captured. From here the user may download the photo or return to the camera to take another.
当用户点击拍摄按钮时,我们将弹出下载屏幕,向他们显示他们刚拍摄的照片的预览。 用户可以从此处下载照片或返回相机拍摄另一张照片。
存取相机 (Accessing Camera)
The “Allow Access” button on our intro page is connected to the startCamera
method in our Vue app. First, the method calls getUserMedia
which asks for permission to utilize the user’s device camera. Once permission is granted, we pass the stream to the src
of an awaiting <video>
element. I am also using the stream
variable to conditionally show or hide the intro and camera <section>
elements.
简介页面上的“允许访问”按钮已连接到Vue应用程序中的startCamera
方法。 首先,该方法调用getUserMedia
,以请求使用用户设备摄像头的许可。 授予权限后,我们会将流传src
等待中的<video>
元素的src
。 我还使用stream
变量有条件地显示或隐藏intro和camera <section>
元素。
this.stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
facingMode: 'environment'
}
})this.$refs.video.srcObject = this.stream
We don’t want users capturing photos until the <video>
element is ready. We can check for this by listening for the loadedmetadata
event. I’ll use the ready
boolean to enable or disable the capture button.
我们不希望用户在<video>
元素准备好之前捕获照片。 我们可以通过侦听loadedmetadata
事件来进行检查。 我将使用ready
布尔值启用或禁用捕获按钮。
this.$refs.video.onloadedmetadata = () => {
this.ready = true
}
When WebRTC is running from a home screen app, iOS will show a small red bar at the top of the screen to let users know their camera is in use. Users have the ability to click this and stop the camera. We should listen for this action so that we can send users back to the intro page as soon as the camera stops. You can do this by listening for the ended
event.
当从主屏幕应用程序运行WebRTC时,iOS将在屏幕顶部显示一个红色的小条,以使用户知道其相机正在使用中。 用户可以单击它并停止相机。 我们应该听取此操作,以便我们可以在相机停止播放后立即将用户带回到简介页面。 您可以通过侦听ended
事件来做到这一点。
this.$refs.video.onended = () => {
this.ready = false
this.stream = null
}
拍摄照片 (Capturing Photo)
Once the WebRTC stream is connected to the <video>
element and the metadata is loaded, users will have the ability to capture photos. As I mentioned in the user journey section, this is best handled by a well placed button fixed to the bottom of the camera screen. Our app’s capture button is connected to the aptly named capturePhoto
Vue method. Let’s break it down.
将WebRTC流连接到<video>
元素并加载元数据后,用户将可以捕获照片。 正如我在“用户旅程”部分中提到的那样,最好通过固定在摄像头屏幕底部的适当放置的按钮来处理此问题。 我们应用程序的捕获按钮已连接到恰当命名的capturePhoto
Vue方法。 让我们分解一下。
First, we initialize a new temporary canvas which uses the exact same height and width as our video stream. The current video image is then drawn to the awaiting canvas.
首先,我们初始化一个新的临时画布,该画布使用与视频流完全相同的高度和宽度。 然后将当前视频图像绘制到等待的画布上。
let video = this.$refs.videolet videoCanvas = document.createElement('canvas')
videoCanvas.height = video.videoHeight
videoCanvas.width = video.videoWidth
let videoContext = videoCanvas.getContext('2d')videoContext.drawImage(video, 0, 0)
For this example app, I’ve decided to scale and crop the captured photo into a 1080x1080 square. To make things easy for myself, I’ve bought in the excellent blueimp JavaScript-Load-Image library’s scaling function.
对于此示例应用程序,我决定将捕获的照片缩放并裁剪为1080x1080正方形。 为使事情变得容易,我购买了出色的blueimp JavaScript-Load-Image库的缩放功能。
this.photo = loadImage.scale(videoCanvas, {
maxHeight: 1080,
maxWidth: 1080,
cover: true,
crop: true,
canvas: true
})
As soon as the photo
variable is updated to this scaled canvas, the download screen will appear thanks to another conditional Vue attribute. We can then hide this screen to get back to the camera by simply setting photo
to null
again.
一旦将photo
变量更新到此缩放画布,由于另一个条件Vue属性,将出现下载屏幕。 然后,我们可以通过简单地将photo
再次设置为null
来隐藏此屏幕以返回到相机。
正在下载照片 (Downloading Photo)
The download arrow button is connected to the downloadPhoto
method on our Vue app. This method calls the toBlob
method on our photo
canvas to generate a JPG blob of the captured photo. We then turn that blob into an object URL, add it to a hidden download link, and then programmatically click()
the link to start the download.
下载箭头按钮已连接到我们Vue应用程序上的downloadPhoto
方法。 此方法在我们的photo
画布上调用toBlob
方法,以生成捕获的照片的JPG blob。 然后,我们将该Blob转换为对象URL,将其添加到隐藏的下载链接中,然后以编程方式click()
链接以开始下载。
this.photo.toBlob(blob => {
let data = window.URL.createObjectURL(blob)
let link = document.createElement('a') link.href = data
link.download = "photo.jpg"
link.click()
}, 'image/jpeg')
配置PWA (Configuring PWA)
For info on configuring the bare minimum meta tags required to get your PWA running as a standalone application, look no further than this excellent Appscope post.
有关配置使PWA作为独立应用程序运行所需的最低限度元标记的信息,请参阅此Appscope优秀文章。
I’ve added all of the suggested meta tags, icons, and launch screen images to the <head>
section of my app by editing the Pen Settings. This can be tested by adding the Debug view to your iOS home screen.
通过编辑笔设置,我已将所有建议的元标记,图标和启动屏幕图像添加到应用程序的<head>
部分。 可以通过将“调试” 视图添加到iOS主屏幕来进行测试。
下一步 (Next Steps)
Now that you understand setting up the base functionality of the camera, it is time to make it your own. You could evolve the capturePhoto
method to filter the captured photo is someway using HTML5 canvas. You can extend the camera screen itself to include a button which switches from the front and back camera by adjusting the facingMode
property of the getUserMedia
options. I decided to bring in TensorFlow for my “CAMERA” to identify objects in capture photos and then use HTML5 to write the object name right on top. Let me know what you end up doing and happy hacking.
现在您已经了解了设置摄像机的基本功能的时候,现在该使它成为您自己的了。 您可以使用HTML5画布来改进capturePhoto
方法来过滤捕获的照片。 您可以扩展摄影机屏幕本身,以包括一个按钮,该按钮可以通过调整getUserMedia
选项的facingMode
属性来从前后摄影机切换。 我决定为我的“ CAMERA”引入TensorFlow ,以识别捕获的照片中的对象,然后使用HTML5在最上面写下对象名称。 让我知道您最终会做什么以及快乐的黑客攻击。
相关故事 (Related Stories)
vue webrtc