声网 Web UIKit:只需 5 行代码就能给网站添加视频聊天/直播推流功能

用声网搭建视频直播推流/视频会议网站可能会有点慢,但如果使用声网 Web UIKit,只需五行代码就能轻松给网站添加视频通话功能!而且声网 Web UIKit 功能齐全,支持扩展和自定义,是不是跃跃欲试呢?


一、功能特色

  • 支持视频会议和直播推流
  • 即插即用,没有水印和商标
  • 具有适用于电脑桌面和移动设备的响应式布局
  • 使用 React 自定义 UI 和功能
  • 自动管理令牌(用双击服务器部署)
  • 双流模式和说话人自动识别
  • 由可重组的模块化功能组件搭建
  • 支持 TypeScript,没有第三方依赖
  • 可作为 Web 组件使用
  • 每月有 10,000 分钟的免费使用时间

声网  Web UIKit 必须在 React 框架中使用。如果你的网站用的是 JavaScript 或其他框架(如:Svelte、Vue 或 Angular),可以把 UIKit 当做 web 组件使用(请直接跳到本文最后一部分开始阅读)。


二、前期准备


三、设置

首先,在 GitHub 上找到这个示例的代码,然后使用 Typescript 创建一个 React 项目,打开一个终端并执行:

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


大家也可以用自己的项目,从 NPM 里安装声网 Web UIKit:

npm i agora-react-uikit

注意:截止2022年1月27日, agora-react-uikit 的最新版本是 v0.0.5 , agora-rtc-sdk-ng 的最新版本是 is v4.8.1 。

设置完成后,运行 npm start 来启动 React 服务器,并访问 localhost:3000 上的 hello world 应用。


四、添加视频推流功能

声网 Web UIKit 中包含了一个高级组件 AgoraUIKit ,AgoraUIKit 组件负责处理实时视频体验的逻辑和 UI,我们向这个组件传递道具来进行行为和功能的自定义。首先,我们清除 App.tsx 文件,然后编写代码,搭建一个视频聊天应用:

import React, { useState } from 'react'
import AgoraUIKit, { PropsInterface } from 'agora-react-uikit'

const App: React.FunctionComponent = () => {
  const [videocall, setVideocall] = useState(true)
  const props: PropsInterface = {
    rtcProps: {
      appId: '<Your Agora App ID>',
      channel: 'test',
      token: null, // pass in channel token if the app is in secure mode
    },
    callbacks: {
      EndCall: () => setVideocall(false)
    }
  }
...


然后,我们从 agora-react-uikit 包中导入 AgoraUIKit 组件。App 组件内有一个状态变量 videoCall ,当该变量为“true”时,我们对 UIKit 组件进行渲染;当该变量为“false”时,UIKit 组件会被卸载。我们在 rtcProps 对象中定义声网 App ID、频道名和用户角色,同一频道的用户可以互相交流。频道名可以由任何字母数字字符串组成。

注意:如果你的应用处于安全模式,可以从声网控制台生成一个令牌来进行测试。我们稍后会仔细讨论令牌的使用方法。

callbacks 对象中的 RTC 事件是密钥,回调函数是值——我们使用 EndCall 事件来更新状态并卸载 AgoraUIKit 组件。

...
  return (
    <div style={styles.container}>
      {videocall ? (
        <AgoraUIKit
          rtcProps={props.rtcProps}
          callbacks={props.callbacks} />
      ) : (
        null
      )}
    </div>
  )
}

const styles = {
  container: { width: '100vw', height: '100vh', display: 'flex', flex: 1},
}

export default App


在返回语句中,我们用 rtcProps 和 callbacks 对象来渲染 AgoraUIKit 组件(卸载声网Agora UIKit 组件后会自动执行清理工作)。

UIKit 组件还兼容 styleProps 道具,这个道具可以编写 React 样式从而自定义应用的外观。我们可以用自定义的样式覆盖 UIKit 的默认样式(如按钮、视频和容器)。


五、直播推流

现在,我们要把一个视频会议网站转变成一个直播推流应用,用户可以以主持人或观众的角色加入,主持人可以向频道中的所有用户分享音视频,而观众只能从主持人那里接收音视频。

...
import AgoraUIKit, { PropsInterface, layout } from 'agora-react-uikit'

const App: React.FunctionComponent = () => {
  const [videocall, setVideocall] = useState(true)
  const [isHost, setHost] = useState(false)
  const [isPinned, setPinned] = useState(false)
...


首先,我们需要添加两个新的状态变量:isHost 和 isPinned 。我们用 isHost 变量追踪用户的角色,确定用户是主持人还是观众,用 isPinned 变量在两个预建的布局之间进行切换:

...
  const props: PropsInterface = {
    rtcProps: {
      appId: '<Your Agora App ID>',
      channel: 'test',
      role: isHost ? 'host' : 'audience',
      layout: isPinned ? layout.pin : layout.grid,
    },
    callbacks: {
      EndCall: () => setVideocall(false)
    },
    styleProps: {
      localBtnContainer: {backgroundColor: 'blueviolet'}
    }
  }
...


我们可以用自己的状态来定义 rtcProps ,rtcProps 开关中添加了在主持人和观众之间切换(默认角色是主持人)的角色道具。UIKit 道具是动态的,如果我们更新了状态,该状态作为道具传递,UIKit 会随之变化(与标准的 React 设计模式类似)。我们正在使用 styleProps 改变底栏的背景颜色:

...
return (
    <div style={styles.container}>
        {videocall ? (<>
          <div style={styles.nav}>
            <p style={{ fontSize: 20, width: 200 }}>You're {isHost ? 'a host' : 'an audience'}</p>
            <p style={styles.btn} onClick={() => setRole(!isHost)}>Change Role</p>
            <p style={styles.btn} onClick={() => setPinned(!isPinned)}>Change Layout</p>
          </div>
          <AgoraUIKit
            rtcProps={props.rtcProps}
            callbacks={props.callbacks}
            styleProps={props.styleProps} /></>
        ) : (
          <h3 style={styles.btn} onClick={() => setVideocall(true)}>Start Call</h3>
        )}
      </div>
    </div>
  )
}
...


接下来,我们会更新 UI,添加切换状态的按钮,把 styleProps 添加到 UIKit 中。 如果视频呼叫状态为 false,不要返回 null,添加一个 h3 标签,通过更新状态在上一次呼叫结束后立即再次呼叫。

这里有很多可供参考的样式:

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

export default App


六、用 RtcProps 自定义功能

我们可以用 RtcProps 对象自定义 UIKit 的工作方式,还可以选择功能和布局,现在 RtcProps 自定义的使用范围越来越广。


七、令牌管理

如果大家使用声网 Web UIKit 搭建生产级应用,我们强烈建议使用令牌来保护应用。有两种使用令牌的方法:如果大家已经设置了令牌服务器,可以通过令牌属性手动给 UIKit 提供一个令牌。

如果没有令牌服务器,可以使用 tokenUrl 属性,该属性可以自动为频道获取一个新的访问令牌,而且会在令牌快要过期时自动更新。请求新令牌的功能需要令牌符合 GitHub上预建的 Golang 令牌服务器中的 URL 方案:AgoraIO-Community/agora-token-service. 你可以使用这个链接双击鼠标把它部署到 Heorku 上。


八、在非 React 框架中使用 Web UIKit

声网 Web UIKit 也可作为 Web 组件,用于用原生 JavaScript 或 Angular、Vue 和 Avelte 等框架搭建的网站。要在这样的网站上添加视频通话功能,只需将声网 Web UIKit 作为脚本导入,然后,通过传递声网 App ID 和频道名在 DOM 中使用声网 Web UIKit。

...
  <body>
    <script src="agora-uikit.js"></script>
    <agora-react-web-uikit
      style="width: 100%; height: 100vh; display: flex;"
      appId=''
      channel='test'
    />
    <script>
      // select web component
      const el = document.querySelector('agora-react-web-uikit');
      
      // alternatively you can do this to pass props
      // el.appId = '<Your App ID>'
      
      // Add event listener and subscribe to custom event
      el.addEventListener('agoraUIKitEndcall', (e) => {
        console.log('hello from html')
        // handle endcall event
        el.remove();
      });
    </script>
...


我们可以在 JS 中访问 Web 组件元素并更新对象属性,这样可以用编程的方式更新道具,比如,这样做更有利于在直播推流应用中搭建更新用户角色的按钮。我们可以为结束通话按钮添加事件监听器,如果用户点击结束通话按钮,事件监听器就会处理所有工作。我们非常期待大家的反馈,希望大家可以打开功能请求,这样我们就可以给 Web 组件版本添加更多的 RTC 事件。

虽然目前 Web 组件还有局限性,但本文中提到的都可以实现。我们会根据大家的反馈,在 react 版本之外,持续给这个版本的 UIKit 添加功能和支持。


九、高级:重组 UIKit

如果你需要更精细的控件,或者想为应用搭建一个自定义布局,但 AgoraUIKit 组件不支持,你可以提取和使用组成 UIKit 的单个组件进行重组,建立自己的自定义解决方案,并且不用管理 SDK。

UIKit 并不局限于使用 AgoraUIKit 组件,它是一个由几个模块化组件组成的高级组件,所以用起来非常方便。你可以导入并使用单个部件来组成你的应用。


十、RtcConfigure

RtcConfigure 组件包含视频通话的所有逻辑,它处理所有的 SDK 事件并维护应用的状态。你可以在 RtcConfigure 组件内封装其他 UIKit 组件以获得对用户对象的访问。

它还设置了 RtcContext 用来访问 Web SDK 客户端对象以及包含远端音轨和本地音轨的 mediaStore (以及用于改变状态的调度函数)。


十一、TracksConfigure

TrackConfigure 组件负责为应用创建音频和视频轨道。


十二、控件

UIKit输出了一个 LocalControls 组件,该组件封装了 LocalAudioMute 、LocalVideoMute 和 EndCall 按钮组件。资源库里有一个 RemoteAudioMute 、一个 RemoteVideoMute 和一个 SwapUser (把用户与 maxUser 交换)按钮。这些组件接收用户对象作为一个道具。


注意:远端控件只能在本地对远程用户的音频和视频进行静音。通话中的其他人不会被静音。


十三、视频视图

我们用 MaxVideoView 和 MinVideoView 这两个组件来渲染用户的视频。这两个组件都用用户对象作为道具。用户数据被划分为两个不同的数组:MaxUser 和 MinUser 。MaxUser 数组通常只包含一个用户,其他用户则在 MinUser 数组中。布局固定的情况下,我们可以用一个数组来渲染大视图,用另一个数组来渲染视频列表,不需要直接与状态进行交互。例如,如果你想替换一个用户,可以使用 SwapUser 按钮,直接从内部改变状态。

如果你不想使用视图搭建自己的布局,可以使用 gridLayout 和 pinnedLayout 组件。


十四、道具背景

PropsContext 使用 React Context API,能访问提供者和消费者组件,然后你可以访问组件树其他地方传递给这个组件的道具。资源库用它来传递组件数上的 rtcProps 、styleProps 和 callbacks 。


十五、用户上下文

我们可以用 MaxUidContext 在 MaxView (浮动布局中的主视图)中访问包含用户对象的一个数组,用 MinUidContext 在 MinView (浮动布局的顶部浮动视图)中访问包含用户对象的一个数组,用 LocalUserContext 访问本地用户的状态。


十六、重组示例

我们通过搭建高级组件来查看这些组件的作用,下面的示例省略了一些细节(如定义道具和样式),如果你需要更多信息,可以查看 AgoraUIKit 组件。

import React, { useContext } from 'react'
import RtcConfigure from './RTCConfigure'
import PropsContext, { PropsProvider, PropsInterface } from './PropsContext'
import LocalControls from './Controls/LocalControls'
import TracksConfigure from './TracksConfigure'
import { MaxUidContext, MaxVideoView, MinUidContext } from './'
import RtcContext from './RtcContext'

const AgoraUIKit: React.FC<PropsInterface> = () => {
  const rtcProps = {
    // define your props
  }

  return (
    <PropsProvider value={rtcProps}>
      {rtcProps.role === 'audience' ? (
        <VideocallUI />
      ) : (
        <TracksConfigure>
          <VideocallUI />
        </TracksConfigure>
      )}
    </PropsProvider>
  )
}

const VideocallUI = () => {
  const { rtcProps } = useContext(PropsContext)

  return (
    <RtcConfigure callActive={rtcProps.callActive}>
      <RenderVideos />
      <LocalControls />
    </RtcConfigure>
  )
}

const RenderVideos = () => {
  const max = useContext(MaxUidContext)
  const min = useContext(MinUidContext)
  const users = [...max, ...min]

  // you can access the Web SDK client and tracks here
  const { client, localVideoTrack } = useContext(RtcContext)
  console.log(client.getRTCStats())
  console.log(localVideoTrack?.getCurrentFrameData())

  return (
    <div>
      {users.map((user) => (
        <MaxVideoView user={user} key={user.uid} />
      ))}
    </div>
  )
}

export default AgoraUIKit


我们将应用包裹在 <PropsProvider> 中,让其他组件可以访问道具。如果用户是主持人,我们将 <VideoCallUI> 封装在 <TracksConfigure> 组件中,该组件创建并传递麦克风和摄像头轨道。

<VideoCallUI> 封装在 <RtcConfigure> 中,<RtcConfigure> 中包含了视频通话/直播推流的所有逻辑,也设置了本地或远端用户的状态。我们用 <LocalControls> 来渲染控件底栏,旁边的 <RenderVideos> 组件访问用户上下文,并使用 <MaxVideoView> 组件对每个用户进行映射从而渲染视频。


总结

我们期待能收到大家的反馈,如果大家有任何功能请求,请打开拉动请求。我们也欢迎大家在 GitHub 问题中报告 bug。另外,我们还有 Android、iOS、React Native 和 Flutter 版本的 UIKit,欢迎查看哦~

如果你在使用 Web UIKit 时遇到问题,可以在 GitHub Repo 上提出功能请求或报告bug。


原文作者:Ekaansh Arora
原文链接:Adding Video Chat or Live Streaming to Your Website in 5 lines of Code Using the Agora Web UIKit
请 注册 或 登录 后评论
    // 作者
    声网技术社区 发布于 声网开发者社区
    • 0
    // 本帖子
    关键词
    // 相关帖子
    Coming soon...
    • 0
    声网 Web UIKit:只需 5 行代码就能给网站添加视频聊天/直播推流功能声网技术社区 发布于 声网开发者社区