【CSDN 编者按】最近很火的AI换脸来啦,本文具体操作步骤已献上,快来get一下吧。
作者 | 峰华
出品 | CSDN(ID:CSDNnews)
过去一年,线上视频会议软件异军突起,成为了在家办公的主要沟通渠道。而最近抖音中能够让照片张嘴唱歌的“蚂蚁呀嘿”特效也突然火了起来,那我就想了想能不能在视频会议的时候换张脸活跃下气氛?
在 GitHub 上一番搜寻之后发现还真有办法,有一个开源的 Python 人工智能换脸的库,那正好趁着这个机会研究一下前端 WebRTC 实现视频通话功能,外加换脸操作。
先看一下效果吧:
因为有涉及到一点点的后台,所以项目分成了两部分,一个是用于存放前端代码的 frontend 项目,另一部分是存放后端代码的 backend 项目:
项目根目录? ?|--?backend |-- frontend
另外这个视频需要电脑上有摄像头,没有的话可以想办法把手机当作电脑的摄像头。
注意:本教程中的代码仅供展示 AI 换脸技术的应用,不可以用于获取其他人隐私或其他任何非法目的。
编写页面
因为是前端实现,首先肯定是编写页面。这个页面比较简单,就是一个视频组件、显示用户 ID 的文本、呼叫对方视频的输入框和按钮,视频组件默认显示自己的视频,当视频接通之后就会显示对方的视频,而自己的视频会缩小到右上角。
HTML
在 frontend 目录下新建 index.html、style.css 和 index.js 文件。首先看一下 HTML 结构,index.html 中主要的代码如下:
<!--?frontend/index.html?--><head> <!-- 其他代码 --> <link rel="stylesheet" href="style.css" /></head><body> <main> <div id="container"> <div class="videos"> <video id="myVideo" class="videoSize" autoplay></video> <video id="peerVideo" class="videoSize" autoplay></video> </div> <p id="idText"></p> <div class="call"> <input type="text" id="peerIdInput" placeholder="请输入对方 id" /> <button id="joinBtn">视频通话</button> </div> </div> </main> <script src="index.js"></script></body>
每个标签的作用是:
-
<main />
用于设置页面背景,把所有组件居中对齐。 -
<div class="videos">
里边分别放了显示自己视频#myVideo
和对方视频#peerVideo
的<video />
组件,并设置为自动播放,以便于在加载摄像头后立刻开始播放画面。 -
<p id="idText">
在页面打开时显示自己的用户 ID,相当于是电话号码。 -
<div class="call">
里是输入对方 ID 的文本框#peerIdInput
和呼叫按钮#joinBtn
。 -
最后在
<head />
中引入样式文件 style.css,在 结束前引入index.js。我们将主要在 index.js 中编写代码。
CSS
CSS 的代码都比较简单,基本就是设置一下样式,这里介绍一下重要的部分,剩余的可以在源代码中查看。因为自己的视频要在视频接通时移动到右上角,那么就需要把 <div class="videos">
容器设置为相对定位,把我的视频和对方的视频设置成一样的宽高,然后先隐藏对方视频,当视频接通时,利用 JavaScript 加上接通后,我的视频的样式,把我的视频设置为绝对定位,宽高调小,放到右上角:
/*?frontend/style.css?*/videos { position: relative;}
.videoSize { width: 500px; height: 600px; object-fit: cover; /* 让视频按比例占满整个空间 */}
.rightTop { /* 以下是通话中的样式 */ position: absolute; width: 150px; height: 180px; right: 0; top: 0;}
#peerVideo { display: none;}
其他组件基本只是设置了下 Grid 布局、宽高、大小、阴影、背景、字体,没有什么特殊的,可以直接查看源代码。样式中所用到的图标在 frontend/icons
目录下。
访问摄像头
接下来我们先熟悉一下访问摄像头的代码。在 JavaScript 中访问用户的摄像头主要使用navigator.mediaDevices.getUserMedia()
方法, 它接收一个对象作为参数,用于指定要获取的设备,例如视频或音频,然后返回一个 Promise,在 Promise 完成之后它会传递给我们一个 Stream 流,我们把它放到 <video />
标签的 srcObject
属性中就可以了,是不是很简单?代码如下:
//?frontend/index.jsconst myVideo = document.getElementById("myVideo");
navigator.mediaDevices.getUserMedia({video: true, audio: true}).then((stream) => { myVideo.srcObject = stream;});
在这段代码中:
-
获取了
#myVideo
这个<video />
组件。 -
使用
navigator.mediaDevices.getUserMedia()
并给它传递了一个对象,对象的 video 和 audio 属性都设置为了 true,表示要访问摄像头和音频设备。
这时,使用 VS Code 的 Live Server 插件运行项目(没有的话安装一下,很简单),在 index.html 文件里右击,选择 Open with Live Server,打开之后,浏览器可能会提示此网站需要访问摄像头和音频设备,点击允许,就能看到自己的视频了。
编写后台
要实现视频通话,需要使用 WebRTC 技术,这个技术牵扯的概念和 API 过于庞大和复杂,不过有开源的库来帮我们简化了 WebRTC 的操作,这里使用一个叫做 Peer.js(https://peerjs.com/)的库,它封装了 WebRTC 杂乱的 API,提供了完整的、可配置的、易于使用的 API。