使用 React Hooks 构建视频聊天应用程序

2025-06-07

使用 React Hooks 构建视频聊天应用程序

使用 React Hooks API 可以轻松使用函数式组件。在本教程中,我们将使用RTC React Video SDK在 React.js 中构建视频通话应用。

更新 1 - 2021 年 12 月 28 日:参考新视频系列React Video Chat App with Video SDK

视频 SDK React JS SDK 让您轻松构建实时视频会议应用程序。视频 SDK 兼容所有浏览器,可扩展至 5,000 名参与者,并实现低延迟。

视频 SDK RTC React JS SDK 支持许多功能,例如

  • 每月免费 10,000 分钟
  • 完全低代码和无服务器。
  • 具有实时音频、视频和数据流的视频 API
  • 5,000+ 名参与者的支持
  • 富媒体聊天支持。
  • 高清和全高清屏幕共享。
  • 在会议中播放实时视频
  • 将其与 Facebook、Youtube 等社交媒体连接(RTMP 输出支持)。
  • 智能音箱开关
  • 在云端记录您的会议
  • 根据您的需要定制 UI。

指数

  1. 在 Video SDK 上创建帐户
  2. 设置服务器
  3. 项目结构
  4. 开始编写代码

1. 在 Video SDK 上创建账户

在videosdk.live上启动项目
在 Video SDK 上创建帐户

导航到开始项目按钮并使用 Google 帐户或 Github 注册。

先决条件

节点 >= 10.16
Npm >= 5.6
React ≥ 16.8

2. 设置服务器

服务器需要通过 JWT 令牌执行身份验证。我们将使用官方的Node JS服务器示例。

  • 克隆以下存储库并运行服务器。


$ git clone https://github.com/videosdk-live/videosdk-rtc-nodejs-sdk-example
$ cd nodejs


Enter fullscreen mode Exit fullscreen mode

注意:您还可以在同一个 repo 中找到其他后端语言示例。

按照Node JS 服务器设置指南运行服务器。

3. 项目结构

您可以使用react-scripts生成项目模板或任何其他反应样板。

使用 create-react-app 创建新项目



npx create-react-app videosdk-react-app-v1


Enter fullscreen mode Exit fullscreen mode

您的项目目录应该是这样的



.
├── node_modules
├── public
├── .env
├── src
 └── api.js
 └── App.jsx
 └── index.css
 └── index.jsx
├── package.json
...
.


Enter fullscreen mode Exit fullscreen mode

配置环境变量

在编写代码之前,配置.env变量。

.env



REACT_APP_SERVER_URL="http://localhost:9000"


Enter fullscreen mode Exit fullscreen mode

注意:对于生产环境,您必须托管此服务器并需要更改 URL。

安装官方 React JS 包

在跳到其他任何内容之前,请安装 videosdk react js sdk。



yarn add @videosdk.live/react-sdk


Enter fullscreen mode Exit fullscreen mode

4.开始编写代码

我们将首先设置 API 调用,然后开始编写代码。

调用 API 生成授权tokenmeetingId

我们将开始使用 编写代码api.js。在开始任何会议之前,您必须生成身份验证tokenmeetingId

api.js



const API_BASE_URL = process.env.REACT_APP_SERVER_URL;

// API call to generate authentication token
export const getToken = async () => {
  const res = await fetch(`${API_BASE_URL}/get-token`, {
    method: "GET",
  });

  const { token } = await res.json();
  return token;
};

// API call to create meeting
export const createMeeting = async ({ token }) => {
  const res = await fetch(`${API_BASE_URL}/create-meeting`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ token }),
  });

  const { meetingId } = await res.json();
  return meetingId;
};



Enter fullscreen mode Exit fullscreen mode

从...开始App.jsx

首先,在处理视频通话视图之前,让我们设置令牌生成和 meetingId 逻辑。

应用程序组件



import logo from './logo.svg';
import './App.css';
import React, { useEffect, useRef, useState } from "react";
import {
  MeetingProvider,
  MeetingConsumer,
  useMeeting,
  useParticipant,
} from "@videosdk.live/react-sdk";
import { getToken, validateMeeting, createMeeting } from "./api";

function MeetingGrid() {
  return <h1>Meeting Grid</h1>
}

function JoinScreen() {
  return <h1>Join Screen</h1>
}

function ParticipantView(props){
  return <h1>Participant View</h1>
}

function App() {
  const [token, setToken] = useState(null);
  const [meetingId, setMeetingId] = useState(null);

  const getMeetingAndToken = async () => {
    const token = await getToken();
    const meetingId = await createMeeting({ token });

    setToken(token);
    setMeetingId(meetingId);
  };

  useEffect(getMeetingAndToken, []);
  return token && meetingId ? (
    <MeetingProvider
      config={{
        meetingId,
        micEnabled: true,
        webcamEnabled: false,
        name: "Participant Name",
      }}
      token={token}
    >
      <MeetingConsumer>
        {() => <MeetingGrid />}
      </MeetingConsumer>
    </MeetingProvider>
  ) : (
    <JoinScreen />
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

React JS SDK 提供了两个重要的 hooks API:

  • useMeeting:负责处理会议环境。
  • useParticipant:负责处理

此外,React Provider 和 Consumer 可以监听会议环境的变化。

实现加入屏幕

我们将从加入屏幕开始,用户可以在其中创建会议或使用会议 ID 加入。

它包含两个简单的功能:

  1. 创建新会议
  2. 加入会议

JoinScreen 组件



function JoinScreen() {
  <div>
    <input type="text" placeholder="Enter Meeting Id" onChange={(e) => {setMeetingId(e.target.value)}}  />
    <button  onClick={getMeetingAndToken}>
      Join
    </button>
    <button  onClick={getMeetingAndToken}>
      Create Meeting
    </button>
  </div>
}


Enter fullscreen mode Exit fullscreen mode

实施会议网格

会议网格将包含整个会议界面。它将负责:

  1. 打开和关闭麦克风
  2. 打开和关闭网络摄像头
  3. 参与者视图


const {
   join, 
   leave,  
   toggleMic,
   toggleWebcam,
   toggleScreenShare
} = useMeeting();


Enter fullscreen mode Exit fullscreen mode

让我们开始逐一实现它。hookuseMeeting将帮助您执行joinleavetoggleMic

会议网格组件



// Helper function for participant loop.
const chunk = (arr) => {
  const newArr = [];
  while (arr.length) newArr.push(arr.splice(0, 3));
  return newArr;
};

function MeetingGrid(props) {
  const [joined, setJoined] = useState(false)
  const {
    join, 
    leave,  
    toggleMic,
    toggleWebcam,
    toggleScreenShare
  } = useMeeting()
  const { participants } = useMeeting();
  const joinMeeting = () => {
    setJoined(true)
    join()
  }
  return (
    <div>
      <header>Meeting Id: {props.meetingId}</header>
      {joined ? 
      (
        <div >
          <button  onClick={leave}>
            Leave
          </button>
          <button  onClick={toggleMic}>
            toggleMic
          </button>
          <button  onClick={toggleWebcam}>
            toggleWebcam
          </button>
          <button  onClick={toggleScreenShare}>
            toggleScreenShare
          </button> 
        </div>
      ) 
      : (<button  onClick={joinMeeting}>
        Join
      </button>)}
      <div
        className="wrapper"
      >
        {chunk([...participants.keys()]).map((k) => (
          <div className="box" key={k} style={{ display: "flex" }}>
            {k.map((l) => (
              <ParticipantView key={l} participantId={l} />
            ))}
          </div>
        ))}
      </div>

    </div>
  )
}


Enter fullscreen mode Exit fullscreen mode

实施参与者视图

为了实现参与者网格,我们将使用react-simple-flex-grid。这将有助于维护视频网格。

我们首先添加这个包。



yarn add react-simple-flex-grid


Enter fullscreen mode Exit fullscreen mode

在 App 组件中导入 react-simple-flex-grid



import { Row, Col } from 'react-simple-flex-grid';
import "react-simple-flex-grid/lib/main.css";


Enter fullscreen mode Exit fullscreen mode

参与者视图将包括三个主要功能:

  1. 启用/禁用网络摄像头
  2. 启用/禁用麦克风
  3. 共享您的屏幕。

让我们逐一探索。在开始之前,我们必须了解useRef音频、视频和屏幕共享元素



const webcamRef = useRef(null);
const micRef = useRef(null);
const screenShareRef = useRef(null);


Enter fullscreen mode Exit fullscreen mode

除此之外,useParticipanthook 还可以帮助您处理麦克风、网络摄像头和屏幕共享。



 const {
    displayName,
    webcamStream,
    micStream,
    screenShareStream,
    webcamOn,
    micOn,
    screenShareOn
  } = useParticipant(props.participantId);


Enter fullscreen mode Exit fullscreen mode

获取流后,您可以使用MediaStreamAPI 添加轨道。例如,查看以下代码以添加对 WebCam 的引用



 const mediaStream = new MediaStream();
 mediaStream.addTrack(webcamStream.track);

 webcamRef.current.srcObject = mediaStream;
 webcamRef.current
   .play()
   .catch((error) =>
     console.error("videoElem.current.play() failed", error));


Enter fullscreen mode Exit fullscreen mode

在组件的加载状态中添加引用后,您可以

ParticipantView 组件



function ParticipantView(props) {
  const webcamRef = useRef(null);
  const micRef = useRef(null);
  const screenShareRef = useRef(null);

  const {
    displayName,
    webcamStream,
    micStream,
    screenShareStream,
    webcamOn,
    micOn,
    screenShareOn
  } = useParticipant(props.participantId);

  useEffect(() => {
    if (webcamRef.current) {
      if (webcamOn) {
        const mediaStream = new MediaStream();
        mediaStream.addTrack(webcamStream.track);

        webcamRef.current.srcObject = mediaStream;
        webcamRef.current
          .play()
          .catch((error) =>
            console.error("videoElem.current.play() failed", error)
          );
      } else {
        webcamRef.current.srcObject = null;
      }
    }
  }, [webcamStream, webcamOn]);

  useEffect(() => {
    if (micRef.current) {
      if (micOn) {
        const mediaStream = new MediaStream();
        mediaStream.addTrack(micStream.track);

        micRef.current.srcObject = mediaStream;
        micRef.current
          .play()
          .catch((error) =>
            console.error("videoElem.current.play() failed", error)
          );
      } else {
        micRef.current.srcObject = null;
      }
    }
  }, [micStream, micOn]);

  useEffect(() => {
    if (screenShareRef.current) {
      if (screenShareOn) {
        const mediaStream = new MediaStream();
        mediaStream.addTrack(screenShareStream.track);

        screenShareRef.current.srcObject = mediaStream;
        screenShareRef.current
          .play()
          .catch((error) =>
            console.error("videoElem.current.play() failed", error)
          );
      } else {
        screenShareRef.current.srcObject = null;
      }
    }
  }, [screenShareStream, screenShareOn]);


  return (
    <div key={props.participantId} >
      <audio ref={micRef} autoPlay />
      {webcamRef ||  micOn ? (<div>
      <h2>{displayName}</h2>
      <video
        height={"100%"}
        width={"100%"}
        ref={webcamRef}
        autoPlay
      />
      </div>) : null }
      {screenShareOn ? (
      <div>
        <h2>Screen Shared</h2>
        <video
          height={"100%"}
          width={"100%"}
          ref={screenShareRef}
          autoPlay
        />
      </div>) : null }
      <br/>
      <span>Mic:{micOn ? "Yes": "No"}, Camera: {webcamOn ? "Yes" : "No"}, Screen Share: {screenShareOn ? "Yes" : "No"}</span>
    </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

您可以参考Video SDK官方指南实现云录制、聊天、白板、社交媒体直播等更多功能。

在videosdk-react-sdk-tutorial-example上查找完整代码

启动:Video SDK React JS

结论

以上就是如何使用 React JS Hooks 集成视频通话 API 的方法。您还可以查看官方示例videosdk-rtc-react-js-example,以扩展此应用的更多精彩功能。

您可以使用这个基本的视频聊天应用程序并更改几行代码来实现实时音频/视频流。

文章来源:https://dev.to/video-sdk/build-video-calling-app-using-react-hooks-1a79
PREV
降低信息系统复杂性的简单方法
NEXT
React 项目中更好的文件结构