2.9.1 代码结构

本例包含3个文件:index.html、processor.js和beach.jpg。

  • index.html是页面文件,定义页面样式和页面元素。
  • processor.js是JavaScript文件,使用ES6语法实现了一个ChromaKey类。
  • beach.jpg是背景图片,用于实时替换白色背景。

在index.html文件里,我们定义了两个video元素,ID为camera的元素用于展示摄像头拍摄到的视频;ID为camera-chroma的元素用于展示替换背景后的视频。index.html的主要内容如代码清单2-60所示。

代码清单2-60 index.html文件代码

<body>
  <div>
    <video id="camera" autoplay playsinline controls/>
  </div>
  <div>
    <video id="camera-chroma" autoplay playsinline controls/>
  </div>
<script type="text/javascript" src="processor.js"></script>
</body>

processor.js文件的主要流程如下。

  • 使用getUserMedia()方法获取摄像头媒体流,我们在约束需求里指明了只获取视频流,不获取音频流。
  • 在ID为camera的video元素里播放视频流。
  • 获取图片beach.jpg的RGB像素数据并保存到imageFrame中,我们后续将使用这些数据替换白色像素。
  • 将ID为camera的视频画面渲染到名为c1的canvas中,并从c1获取RGB像素数据。对该像素数据的RGB值进行判断,如果RGB值接近白色,则将该像素替换为对应的imageFrame值。
  • 替换后的像素重新渲染到名为c2的canvas中。
  • 调用canvas.captureStream()方法从c2中捕获视频流,在ID为camera-chroma的视频元素中播放该视频流。

请注意上文对canvas的使用,在整个流程中我们分别在以下3个地方用到了canvas。

  • 提取图片的RGB数据。
  • 提取摄像头的RGB数据。
  • 渲染修改后的RGB数据。

因为我们使用canvas处理图像数据,所以没有在index.html页面中包含canvas元素,而是在Javascript代码中进行动态创建。