使用声网 Web UIKit 为视频聊天网站添加虚拟背景

声网 SDK 引入了虚拟背景扩展,可以对视频通话中的通话背景应用颜色、图像或背景模糊。本文将教大家通过声网 Web UIKit 中使用这个扩展。如果没有 UIKit,可以使用文末的代码片段使用该扩展。


前期准备


设置

你可以直接使用 GitHub 上的示例代码,也可以自行创建一个 React 项目。然后,打开终端并执行下列代码:

npx create-react-app demo --template typescript
cd demo

安装声网 React UIKit 和虚拟背景扩展:

npm i agora-react-uikit agora-extension-virtual-background

*说明:撰写本文时,agora-react-uikit 的最新版本是 v1.1.0

设置完成后,执行 npm start 来启动 localhost 上的 web 服务器。


构建直播推流

使用 UIKit 可以访问 <AgoraUIKit> 高级组件,我们可以用这个高级组件渲染整个视频通话或直播推流。

我们使用模块化组件来组成视频通话并添加虚拟背景功能。

清除 App.tsx 文件:

import React, { CSSProperties, useState } from 'react'
import { PropsContext, GridVideo, LocalControls, RtcConfigure, TracksConfigure, RtmConfigure, RemoteMutePopUp, LocalUserContext } from 'agora-react-uikit'
import VirtualBackground from './VirtualBackground'
import 'agora-react-uikit/dist/index.css'

const App: React.FunctionComponent = () => {
  const [videocall, setVideocall] = useState(true)

  return (
    <div style={styles.container}>
      <h1 style={styles.heading}>Agora React Web UI Kit</h1>
      {videocall ? (
        <>
          <PropsContext.Provider value={{
            rtcProps: {
              appId: '<Agora App ID>',
              channel: 'test',
              token: null, // add you channel token if using secured mode
            },
            callbacks: {
              EndCall: () => setVideocall(false),
            }
          }} >
...

创建一个名为 videocall 的状态变量,当此状态变量为 true 时,我们将渲染 videocall;当它为 false 时,我们将渲染一个按钮,用来切换应用程序的状态并启动推流。

为了构建视频通话,我们用 PropsContext 组件进行封装,这样可以将用户道具传递给 UIKit。然后,把声网 App ID、频道名称和 token 等道具添加到 rtcProps 中。 当用户点击结束通话按钮时,我们把 videocall 的状态切换为 false。

注意:建议所有处于生产环境的 RTE 应用使用 Token 认证。如果想了解更多关于声网平台 Token 认证的信息,请参阅本指南: https://docs.agora.io/en/Video/token?platform=All%20Platforms。

...  
            <TracksConfigure>
              <RtcConfigure>
                <LocalUserContext>
                  <RtmConfigure>
                    <VirtualBackground />
                    <RemoteMutePopUp />
                    <GridVideo />
                    <LocalControls />
                  </RtmConfigure>
                </LocalUserContext>
              </RtcConfigure>
            </TracksConfigure>
          </PropsContext.Provider>
        </>
      ) : (
        <div style={styles.nav}>
          <h3 style={styles.btn} onClick={() => setVideocall(true)}>Start Call</h3>
        </div>
      )}
    </div>
  )
}

const styles = {
  container: { width: '100vw', height: '100vh', display: 'flex', flex: 1, backgroundColor: '#007bff22', flexDirection: 'column' } as CSSProperties,
  heading: { textAlign: 'center' as const, marginBottom: 0 },
  nav: { display: 'flex', justifyContent: 'space-around' },
  btn: { backgroundColor: '#007bff', cursor: 'pointer', borderRadius: 5, padding: 5, color: '#ffffff', fontSize: 20 }
}

export default App

我们使用 UIKit 的内置组件来封装应用程序,这些组件可以帮助我们访问 UIKit 的数据,还可以处理大量视频通话逻辑。我们使用 TrackConfigure 来访问本地音轨,使用 RtcConfigure 来处理呼叫逻辑,使用 LocalUserContext 处理本地用户状态,使用 RtmConfigure 处理信令逻辑。

在 UIKit 中渲染这些组件:

RemoteMutePopup: 显示静音请求弹出窗口;

GridVideo: 渲染网格中的用户视频;

LocalControls: 渲染本地音轨的静音/取消静音控件。

另外,我们还会添加一个新的 VirtualBackground 组件。


使用声网虚拟背景扩展

为保证虚拟背景的性能,声网使用了 WebAssembly(WASM) 模块,因此我们需要托管 WASM 文件——可以通过 CDN 单独托管,或者将其与网站捆绑。现在,我们来创建 VirtualBackground 组件:

import VirtualBackgroundExtension, { IVirtualBackgroundProcessor } from "agora-extension-virtual-background";
import AgoraRTC from 'agora-rtc-sdk-ng';
import { TracksContext } from 'agora-react-uikit';
import { useContext, useEffect, useState, useRef } from 'react';

const VirtualBackground = () => {
  const [extensionActive, setExtensionActive] = useState(false);
  const { localVideoTrack } = useContext(TracksContext)
  const ext = useRef(new VirtualBackgroundExtension())
  const processor = useRef<IVirtualBackgroundProcessor>();
...

首先,我们需要创建一个状态变量 extensionActive 来启用/禁用虚拟背景。

然后,通过 TracksContext 访问 localVideoTrack,创建一个 VirtualBackgroundExtension 实例,命名为 ext,再创建一个 ref 来存储背景处理器。

...
  useEffect(() => {
    const initExtension = async () => {
      AgoraRTC.registerExtensions([ext.current]);
      processor.current = ext.current.createProcessor()
      await processor.current.init('<Path to WASM module>')
    }
    initExtension()
  }, [])
...

接下来,在 useEffect 中调用 registerExtensions 方法初始化扩展,然后调用 createProcessor 方法,并将其分配给处理器 ref,然后用 WASM 文件的路径调用 init 方法,可以是绝对的 URL,也可以是相对的。

...
  const enableBackground = async () => {
    if (processor.current && localVideoTrack) {
      localVideoTrack.pipe(processor.current).pipe(localVideoTrack.processorDestination);
      processor.current.setOptions({ type: 'color', color: '#ff00ff' });
      await processor.current.enable();
      setExtensionActive(true)
    }
  }

  const disableBackground = async () => {
    if (processor.current && localVideoTrack) {
      localVideoTrack.unpipe()
      await processor.current.disable()
      setExtensionActive(false)
    }
  }
...

然后,创建 enableBackground,把 localVideoTrack 输送到 processorprocessor 会被传递到 track 的processorDestination

使用 setOptions 方法来定义虚拟背景,本示例使用的是粉红色,你也可以使用模糊效果或图像。接下来,启用处理器并更新状态。

对于 disableBackground 函数,我们只需在更新状态前解除本地音轨的频道,并禁用处理器。

...
  return (
    <div style={btn} onClick={() => {
        extensionActive ? disableBackground() : enableBackground()
    }}>
      {extensionActive ? 'Disable Virtual Background' : 'Enable Virtual Background'}
    </div>
  )
}

const btn = { backgroundColor: '#007bff', cursor: 'pointer', borderRadius: 5, padding: 5, color: '#ffffff', fontSize: 16, margin: 'auto', paddingLeft: 50, paddingRight: 50, marginBottom: 20, marginTop: 10}

export default VirtualBackground;

对于用户界面,我们会渲染一个 div 元素,调用正确的方法并根据我们的状态来切换效果。

如果你不使用 UIKit,可以使用下面的代码:

import AgoraRTC, {ILocalVideoTrack} from 'agora-rtc-sdk-ng';
import VirtualBackgroundExtension from 'agora-extension-virtual-background';

const enableVirtualBackground = async (videoTrack: ILocalVideoTrack) => { 
    const extension = new VirtualBackgroundExtension();
    AgoraRTC.registerExtensions([extension]);
    const processor = extension.createProcessor();
    await processor.init("<Path to WASM module>");
    videoTrack.pipe(processor).pipe(videoTrack.processorDestination);
    processor.setOptions({type: 'color', color: '#00ff00'});
    await processor.enable();
}


总结

以上就是使用声网 Web UIKit 中和基于 WebAssembly 的声网 Extension 实现虚拟背景的步骤。如果你想了解更多关于如何定制 UIKit 的设计和功能(例如,你可以用它来直播),可以查看这篇文章

如果你在使用这个项目或声网 Web UIKit 时有问题,欢迎加入声网开发者社区,在社区中交流提问。



原文作者:Ekaansh Arora
原文链接:https://www.agora.io/en/blog/use-virtual-backgrounds-in-your-video-chat-website-with-the-agora-web-uikit/
推荐阅读
相关专栏
SDK 教程
167 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。