Руководство по созданию приложения для виртуальных встреч с помощью 100ms и React

С тех пор как удаленная работа стала предпочтительной для многих людей, возникла острая необходимость в платформах, где команды могли бы встречаться по воздуху для обсуждения таких вещей, как: состояние проекта, реализация функций, необходимые изменения и т.д. Это касается не только команд или людей, работающих удаленно. Друзья и семьи также хотят иметь возможность общаться друг с другом без необходимости преодолевать для этого полмира. Многие платформы, такие как Zoom, Google Meet, Twitch, Agora и т.д., предоставляют эту необходимую услугу.

В этой статье мы рассмотрим, как с помощью 100ms и React создать собственное приложение для виртуальных встреч со встроенными функциями видео, аудио и чата, как в Google Meet или любом другом вашем любимом приложении для виртуальных встреч.

Почему вы должны использовать 100ms?

100ms — это облачная платформа, которая позволяет вам встроить видео- и аудиоконференции в ваше приложение, используя мощные Rest API и SDK, что дает вам возможность создать полнофункциональные сервисы связи в реальном времени в кратчайшие сроки. Это означает, что вам не придется изобретать колесо, создавая приложение с нуля.

Он предоставляет вам приборную панель для того, чтобы вы могли настроить приложение по своему вкусу и оптимизировать его для достижения наилучшей производительности.

Вот другие проекты React, которые вы можете создать с помощью 100ms

  • Создание клона Twitch
  • Создание клона Google meet
  • Создание клона Slack huddle
  • Создание канала сцены Discord

Основная концепция

В 100ms есть несколько терминов, с которыми вы должны быть знакомы, прежде чем приступить к этому руководству:

  • Room: Комната — это основной объект, который 100ms SDK возвращает при успешном подключении. Он содержит ссылки на пиров, треки и все, что нужно для рендеринга живого приложения a/v.

  • Peer: Peer — это объект, возвращаемый 100ms SDKs, который содержит всю информацию о пользователе — имя, роль, видео трек и т.д.

  • Track: Трек представляет собой аудио или видео, которое публикует пэр.

  • Роль: Роль определяет, кого может видеть/слушать собеседник, в каком качестве он публикует свое видео, есть ли у него разрешения на публикацию видео/скриншот, отключение звука, изменение роли.

  • Шаблон: Шаблон — это набор ролей, настроек комнаты, записи и настроек RTMP (если используется), которые используются SDK для решения, к какой географии подключаться, какие треки возвращать клиенту, включать ли запись при создании комнаты и т.д. Каждая комната связана с шаблоном.

  • Запись: Запись используется для сохранения аудио/видео звонков для автономного просмотра. 100ms поддерживает 2 вида записи — запись в SFU и запись в браузере.

  • RTMP: Потоковая передача RTMP используется для прямой трансляции ваших приложений для видеоконференций на такие платформы, как YouTube, Twitch, Facebook, MUX и т.д.

  • Webhooks: Webhook — это конечная точка HTTP(S), используемая для отправки уведомлений в ваше приложение. Он будет вызываться серверами 100ms для уведомления о событиях в вашей комнате.

Особенности, которые будут рассмотрены в этом учебнике

  • Создание комнаты, к которой могут присоединиться и участвовать в ней коллеги
  • Отключение и отключение звука и видео.
  • Функция чата
  • Выход из комнаты/завершение разговора.

Требования

Чтобы иметь возможность следовать этому руководству, вам необходимо иметь следующее:

  • Учетная запись 100ms. Нам нужно будет создать комнату на приборной панели и получить room id для интеграции в наше приложение.

  • Знание React и JavaScript.

  • Nodejs, установленный на вашей машине.

  • Любой редактор кода, который вы предпочитаете.

Настройка проекта

  • Создайте приложение React. Для использования команды create-react-app выполните команду npx create-react-app <appname>.

  • Установите 100ms React SDK. Выполните npm install --save @100mslive/react-sdk.

  • Получите учетные данные: Получите token_endpoint и room_id из раздела разработчика на приборной панели.

  • Создайте роли: Создайте роли зрителя и сцены и определите разрешения для зрителей — аудио, видео, отключение звука, снятие звука и т.д.

В конце этого урока наше приложение для виртуальных встреч будет выглядеть следующим образом:

Создание учетной записи 100ms и получение учетных данных

Мы не можем создать наше приложение для виртуальных встреч без предварительного создания учетной записи 100ms.
После регистрации перейдите на приборную панель, чтобы получить token_endpoint и room_id, которые нам понадобятся при создании нашего приложения.

Выполните следующие шаги, чтобы создать и настроить ваше новое приложение:

  • Создайте новое приложение в приборной панели

  • Выберите шаблон

Вы можете выбрать любой шаблон, который наилучшим образом соответствует вашим потребностям. Вы также можете «создать свой собственный». В данном руководстве мы выбрали шаблон «Виртуальные события».

  • Создайте роли: Роль определяет, кого видит или слышит собеседник, в каком качестве он публикует свое видео, есть ли у него разрешение публиковать видео/обмениваться видео на экране, отключать звук, изменять чью-то роль.

Виртуальное приложение, которое мы создаем, будет иметь следующие роли:

  • Stage: может говорить, отключать и выключать звук, а также разделять экран. Чтобы создать эту роль, включите все стратегии публикации, затем отключите все разрешения, кроме возможности завершить текущую сессию комнаты и удалить всех участников.

  • Viewer: может только слушать сцену. Чтобы создать эту роль, отключите все стратегии публикации.

  • Создайте комнату: пользователи, присоединяющиеся к звонку, считаются присоединившимися к комнате. Чтобы создать комнату, нажмите на Rooms на приборной панели, затем создайте комнату.

Теперь, когда мы все настроили, давайте перейдем к созданию нашего приложения.

Создание нашего приложения

В 100ms-react-sdk, который мы ранее установили в наше приложение React, есть два хука, с которыми нам нужно ознакомиться:

Теперь, когда мы это знаем, давайте замажем руки, написав несколько кодов.

Начнем с getToken.js в папке utils нашего проекта.

getToken.js

const endPoint = "<token_endpoint>";
export default async function GetToken(role) {
    const response = await fetch(`${endPoint}api/token`, {
        method: 'POST',
        body: JSON.stringify({
         user_id: '2234', // a reference user id assigned by you
             role: role, // stage, viewer 
         room_id: "<room_id>" // copied from the dashboard
        }),
    });
    const { token } = await response.json();
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Замените <token_endpoint> на token_endpoint из меню разработчика на вашей приборной панели. Заполните room_id правильным room_id, как показано на приборной панели.

О, подождите! Мы чуть не забыли. Прежде чем 100ms заработает в нашем приложении, нам нужно зайти в наш файл index.js и обернуть компонент <App /> с HMSRoomProvider вот так:

//...
import {HMSRoomProvider} from '@100mslive/react-sdk'
ReactDOM.render(
  <React.StrictMode>
    <HMSRoomProvider>
      <App />

    </HMSRoomProvider>
  </React.StrictMode>,
  document.getElementById('root')
);


Вход в полноэкранный режим Выход из полноэкранного режима

Давайте создадим форму, в которой пользователи смогут заполнить свое имя и выбрать свою роль, чтобы присоединиться к комнате.

joinRoom.js

import React, { useState } from 'react';
import {
    useHMSActions,
    } from "@100mslive/react-sdk";
import GetToken from '../utils/getToken';
import '../App.css';

export default function JoinRoom() {
    const hmsActions = useHMSActions()

    const [name, setName] = useState("")
    const [role, setRole] = useState('stage');



    const handleSelectChange = (e) =>{
        setRole(e.target.value)
    }
    const handleInputChange = (e) =>{

       setName(e.target.value)

    }

    const handleSubmit = () =>{

        GetToken(role)
        .then(token =>{
            return hmsActions.join({
                userName: name,
                authToken: token
            })
        })
        .catch(err => console.log("token error", err))

    }


    return (
    <div className='app'>
        <div className='login'>
        <h2>Join Meeting Room</h2>

            <input type="text" placeholder="name"  
            value={name}
            onChange={handleInputChange}
            name="name"
            required
            />

            <select onChange={handleSelectChange}>
                <option value="stage">Stage</option>
                <option value="viewer">Viewer</option>
            </select>

            <button type='submit' onClick={handleSubmit}> Join</button>

        </div>


    </div>
  )
}


Вход в полноэкранный режим Выход из полноэкранного режима

Функции handleInputChange и handleSelectChange используются для установки состояний name и role соответственно.

Функция handleSubmit вызывает функцию GetToken и использует полученный токен обратного вызова для инициализации объекта hmsAction.join, который принимает два значения — userName и authToken. Они должны быть предоставлены до того, как пользователь сможет присоединиться к комнате.

После этого у вас должно получиться следующее:

Когда пользователь присоединяется к комнате, мы хотим скрыть эту форму и отобразить комнату, к которой присоединился пользователь. Для этого перейдите в файл App.js и добавьте следующие коды


import './App.css';
import {selectIsConnectedToRoom, useHMSStore, useHMSActions} from '@100mslive/react-sdk'
import JoinRoom from './components/joinRoom';
import Conference from './components/conference';
import { useEffect } from 'react';


function App() {
  const isConnected = useHMSStore(selectIsConnectedToRoom)
  const hmsActions = useHMSActions()

  useEffect(() =>{
    window.onunload = () => {
      if(isConnected) hmsActions.leave()
    }
  }, [hmsActions, isConnected])

  return (
    <div className="App">
      {
        isConnected ? <Conference /> : <JoinRoom />
      }
    </div>
  );
}

export default App;


Войти в полноэкранный режим Выйти из полноэкранного режима

const isConnected = useHMSStore(selectIsConnectedToRoom) помогает нам проверить, подключен ли пользователь к комнате. Компонент <Conference /> отображается, если пользователь подключен к комнате, если нет, то отображается компонент <JoinRoom />.

Еще одна интересная вещь, которую мы добавили в файл App.js — hmsActions.leave() внутри хука useEffect. Это сделано для того, чтобы пользователь покидал комнату всякий раз, когда срабатывает обновление браузера или закрытие вкладки. Если этого не сделать, то если пользователь вдруг обновит [или закроет] свою вкладку во время встречи, будет наблюдаться задержка в несколько секунд — это связано с тем, что 100ms подумает, что у него проблемы с сетью, и попытается восстановить соединение.

После того, как пользователь успешно присоединился к комнате, нам нужно отобразить видео, которое будет находиться внутри файла conference.js.

import React from 'react'
import VideoTile from './videoTile'
import {
    useHMSStore, 
    selectPeers

} from "@100mslive/react-sdk"


export default function Conference() {
    const peers = useHMSStore(selectPeers)

  return (
    <div>
        {peers.map(peer =>(
                <VideoTile key={peer.id} peer={peer} />
            ))}


    </div>
  )
}

Войти в полноэкранный режим Выход из полноэкранного режима

Подключенные peers отображаются на компонент <VideoTile />.

Теперь перейдем в файл videoTile, чтобы добавить тег видео, а также настроить наше видео.

const VideoTile = () => {

 const videoRef = useRef(null)
    const hmsActions = useHMSActions();

    const videoTrack = useHMSStore(selectCameraStreamByPeerID(peer.id))
    useEffect(() =>{
        if(videoRef.current && videoTrack){
            if(videoTrack.enabled){
                hmsActions.attachVideo(videoTrack.id, videoRef.current)
            }
            else{
                hmsActions.detachVideo(videoTrack.id, videoRef.current)
            }
        }
    }, [videoTrack, hmsActions])

 return(
  <div> 
      <video className="center-vid"
        ref={videoRef} autoPlay muted playsInline>

     </video>

  </div>
)
}
Вход в полноэкранный режим Выход из полноэкранного режима

Добавим функции переключения

const audioEnabled = useHMSStore(selectIsLocalAudioEnabled)
 const videoEnabled = useHMSStore(selectIsLocalVideoEnabled)

    const toggleAudio = async () =>{
        await hmsActions.setLocalAudioEnabled(!audioEnabled)
    }
    const toggleVideo = async () =>{
        await hmsActions.setLocalVideoEnabled(!videoEnabled)

    }

Войти в полноэкранный режим Выход из полноэкранного режима

Для управления звуком

  {
     audioEnabled ? (
      <img src={unmuteIcon} alt="mute" />
    ) : (

      <img src={muteIcon} alt="unmute" />
    )

  }
Вход в полноэкранный режим Выйти из полноэкранного режима

для элементов управления видео

  {
     videoEnabled? (
      <img src={videoIcon} alt="CloseCamera" />
    ) : (

      <img src={unVideoIcon} alt="OpenCamer" />
    )

  }
Войти в полноэкранный режим Выйти из полноэкранного режима

Чтобы выйти из комнаты

<button
  onClick={() => {
      hmsActions.endRoom(false, "reason") && hmsActions.leave();
  }}
>
     <img src="https://img.icons8.com/color/24/000000/end- call.png" alt="end call"/>
</button>;
Войдите в полноэкранный режим Выйти из полноэкранного режима

Добавление раздела чата

100ms поддерживает чат для каждой созданной вами видео/аудио комнаты.

//broadcast message:

hmsActions.sendBroadcastMessage('I just joined the call!'); 

Войти в полноэкранный режим Выход из полноэкранного режима
//group message:

hmsActions.sendGroupMessage('Yo people!', ['moderator', 'host']);

Войти в полноэкранный режим Выход из полноэкранного режима
//direct message:

hmsActions.sendDirectMessage('I DM for you alone!', peer.id);


Войти в полноэкранный режим Выход из полноэкранного режима

Для целей приложения, которое мы создаем, мы будем добавлять только широковещательные сообщения.

message.js

const Message = () => {
   const broadcastMessages = useHMSStore(selectBroadcastMessages);

   return (
      <div className="message-container">
        <div className="chat-area">

        {broadcastMessages.map(msg =>{
          const {message, senderName} = msg

              return(

                <div key={msg.id}>
                    <p> <span>{senderName }:</span> {message}</p>
                </div>
              )

          })}
        </div>


      <div className="chat" >
        <input 
        placeholder='write chat here' 
        value={chatContent}
        onChange={handleChat}
        >

        </input>
        <button type='submit' onClick={handleChatSubmit}>send</button>
      </div>
    </div>
  )
}

}

Войти в полноэкранный режим Выйти из полноэкранного режима

чтобы отправить чат:

 const handleChatSubmit = () =>{
    hmsActions.sendBroadcastMessage(chatContent)

    setChatContent("")
    }

Войти в полноэкранный режим Выйти из полноэкранного режима

Да! Мы закончили. Я слышал, как вы сказали «легко и быстро»? Да, вы можете сказать это снова. Спасибо 100ms за предоставленный нам фантастический React SDK, который мы использовали. Без него создание приложения для коммуникации в реальном времени с нуля заняло бы несколько дней, если не недель.

Заключение

100ms выделяется тем, что предоставляет множество решений, соответствующих как обычным, так и уникальным случаям использования, с помощью всего нескольких кликов и крючков. Зарегистрируйтесь в 100ms и получите бесплатно 10000 минут. Да! 10000 минут.

Проверьте демо-версию.
Вы можете получить исходный код здесь

Оцените статью
Procodings.ru
Добавить комментарий