使用WebRTC在浏览器上自己建一个“Snapchat”

作者:Adam Ullman(原文链接

翻译:刘通

 

snapchat1

         最近Snapchat首次公开募股,我就想到了如果使用WebRTC自己建一个跟Snapchat差不多的应用肯定是一件特别有意思的事情。好消息是感谢现在浏览器(Firefox和Chrome)的一些新的特性,我们完全可以自己写一个自己的“Snapchat”。

         在这个网页上可以看到我的demo,http://aullman.github.io/snapchat-killer. 你也可以在这里看到源代码,https://github.com/aullman/snapchat-killer

 

特点

     首先让我们来看看这个像Snapchat的应用有什么特点?在我的应用中,我希望你能够:

1 拍摄快照(点击拍摄按钮)

2 录制小视频(持续按住拍摄按钮)

3 自己在图片/视频上加滤镜

 

拍快照

         当你在应用中单击了拍摄按钮之后,我们想要能够通过摄像头拍摄一张你的照片,然后将其打上图片标签。你需要进行一些稍微有点复杂的设置才能通过摄像头拍照,下面是流程图。

snapchat2

         首先我们使用getUserMedia()从摄像头获取到视频流,然后我们将其传到视频元素中,随后进行播放。

snapchat3

         然后,当用户点击拍摄按钮的时候,我们将视频标签中的当前帧画到画布上,使用的是drawImage()函数。

snapchat4

        现在我们可以创建一个图片标签,并且使用toDataURL()函数将画布上的内容设置为标签的源(src)。

snapchat5

 

录制小视频

         当你按住Snapchat里的按钮的时候就会拍摄视频。我们也想在我们的应用中照搬这个功能,使用的是全新的MediaRecorder API。这个MediaRecorder API可以让你录制任何媒体流

         我们通过创建一个新的MediaRecorder项,并且传到我们从getUserMedia()获得的MediaStream中,来开始进行视频录制。然后我们开始监听“dataavailable”事件,并且收集录制到的数据块—也就是每个10ms的视频段。

snapchat6

         然后为了回放这段视频,我们创建一个视频元素,并且设定recordedBlobs作为视频的源(src)

snapchat7

 

下载图片和视频

         心在我们已经有了包含快照的图像标签,以及包含小视频的视频标签,但是我们应该如何让用户下载它们呢?我们可以通过创建一个锚定标签,将视频和图像的src设定成href。然后我们设定这个锚定标签的下载属性来设置默认的文件名。最后我们以程序的方式打开这个链接,就会提示用户下载文件。

snapchat8

 

添加滤镜

snapchat9

         现在我们到了有趣的部分了。我们并不想要只是拍摄一些无聊的快照和视频。我们想要做一些滤镜让我们的照片变的更好玩。所以我们需要对上文的视频处理流程图进行一些小改动,把滤镜过程加到其中。

snapchat10

         我们还是把视频内容画到画布上,但是现在我们要获取画布以外的图像数据。图像数据是一个包含画布上每个像素的rgba数值的数组。在我们把他们画到下一张画布上之前,通过改变这些数值,我们就可以进行肆意更改来得到想要得到的图像了。

snapchat11

         现在有很多的库可以帮助我们来编写自己的滤镜库。我用的是tracking.js来完成的,但是你甚至可以只用CSS滤镜来得到相同的效果。我在这篇博文中对如何创建自己的滤镜进行了更加详细的分析。

         为了能够录制添加了滤镜的视频,我们需要获取到过滤后的MediaStream。所以我们用requestAnimationFrame()来不断的在画布上画各个帧的内容。我们可以使用新的捕捉数据流的函数(captureStream)来获取MediaStream,我们可以把它传给我们的MediaRecorder。我们还想要保留音频,所以我们需要把原始MediaStream里的音轨提取出来再加到新的画布流中去。

snapchat12

         现在我们的MediaRecorder就可以录制添加滤镜后的视频流了。

 

面部识别

snapchat13

         Snapchat的滤镜使用了所有种类的面部识别来塑造你的脸部。好消息是有JavaScript库我们可以用来做同样的事。我所使用的库是clmtrackr

         Clmtrackr跟踪人脸的位置,并且将其以数组的形式反馈给你。你可以使用这个数组来进行处理,比如在脸上加一个看起来蠢蠢的眼镜。我们通过寻找眼睛的位置和角度,以及在过滤后的画布上的正确位置画上一个卡通眼镜,来完成这项工作。

snapchat14

snapchat15

         这只是一个简单卡通眼镜的例子,但是使用同样的方法,也可以做一个动态的彩虹从一个人的嘴里吐出来。Clmtrakr也有其他关于实时面部变形面部替换例子

 

结语

         显然,Snapchat拥有的功能要比我这个简单的app拥有的多太多了。但是我们很兴奋地看到现在的浏览器有这些API可以用来做这么一个app。希望在未来,我们还会看到有更多的这类社交软件是基于WebRTC和其他浏览器技术所搭建的。

填写常用邮箱,接收社区更新

WebRTC 中文社区由

运营