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

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

  1. Возможности: Ищите платформы прямых трансляций, которые предлагают функции, необходимые для создания высококачественных трансляций. Например, вам может понадобиться платформа, которая поддерживает несколько ракурсов камеры, позволяет вам делиться своим экраном или позволяет использовать несколько вещателей.
  2. Интеграция: интеграция платформы потокового вещания должна быть простой и быстрой.
  3. Бюджет: хотя платформы для потокового вещания стоят дорого, важно выбрать платформу, которая соответствует вашему бюджету.

Почему стоит выбрать Video SDK?

Video SDK — идеальный выбор для тех, кто ищет платформу для прямых трансляций, которая предлагает необходимые функции для создания высококачественных потоков. Платформа поддерживает совместное использование экрана, обмен сообщениями в режиме реального времени, позволяет вещателям приглашать зрителей на сцену и поддерживает более 100 000 000 участников, гарантируя, что ваши прямые трансляции будут интерактивными и увлекательными. С помощью Video SDK вы также можете использовать собственный шаблон макета для прямых трансляций.

Что касается интеграции, Video SDK предлагает простой и быстрый процесс интеграции, позволяющий легко интегрировать прямую трансляцию в ваше приложение. Это гарантирует, что вы сможете пользоваться преимуществами прямой трансляции без каких-либо технических трудностей или длительных процессов внедрения.

Кроме того, Video SDK является бюджетным, что делает его доступным вариантом для предприятий любого размера. Вы можете пользоваться преимуществами многофункциональной платформы для прямых трансляций, не разоряя банк, что делает ее идеальным выбором для стартапов и малого бизнеса.

5 шагов для создания живого потокового приложения React Native

Следующие шаги дадут вам всю информацию для быстрого создания приложения интерактивной прямой трансляции. Пожалуйста, внимательно следите за новостями, а если у вас возникнут трудности, сразу сообщите нам об этом в Discord, и мы будем рады вам помочь.

Предпосылки

Прежде чем продолжить, убедитесь, что ваша среда разработки соответствует следующим требованиям:

  • Учетная запись разработчика Video SDK (еще нет? Следите за Панель управления Video SDK)
  • Базовое понимание React Native.
  • Node.js v12+
  • NPM v6+ (поставляется с более новыми версиями Node)
  • Android Studio или Xcode установлены

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

Архитектура приложения

Это приложение будет содержать два экрана:

  1. Join Screen : Этот экран позволяет SPEAKER создать студию или присоединиться к предварительно определенной студии и VIEWER присоединиться к предварительно определенной студии.
  2. Speaker Screen : Этот экран в основном содержит список выступающих и некоторые элементы управления студией, такие как «Включить/отключить микрофон и камеру» и «Покинуть студию».
  3. Viewer Screen : Этот экран в основном содержит проигрыватель прямых трансляций, в котором зритель будет воспроизводить трансляцию.

Начало работы с кодом!​

Создать приложение

Создайте новое реагирующее приложение, применив приведенные ниже команды.

npx react-native init AppName

Для реактивной установки вы можете следовать Официальным документам.

Установка видео SDK​

Установите Video SDK, выполнив следующую команду. Перед запуском этой команды убедитесь, что вы находитесь в каталоге проекта.
Для NPM:

npm install "@videosdk.live/react-native-sdk"

Для пряжи:

yarn add "@videosdk.live/react-native-sdk"

Структура проекта​

root
   ├── node_modules
   ├── android
   ├── ios
   ├── App.js
   ├── api.js
   ├── index.jsCopy

Настройка Android

Шаг 1. Добавьте необходимое разрешение в файл AndroidManifest.xml.

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.cool.app"
>
    <!-- Give all the required permissions to app -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- Needed to communicate with already-paired Bluetooth devices. (Legacy up to Android 11) -->
    <uses-permission
        android:name="android.permission.BLUETOOTH"
        android:maxSdkVersion="30" />
    <uses-permission
        android:name="android.permission.BLUETOOTH_ADMIN"
        android:maxSdkVersion="30" />

    <!-- Needed to communicate with already-paired Bluetooth devices. (Android 12 upwards)-->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
​
  <application>
   <meta-data
      android:name="live.videosdk.rnfgservice.notification_channel_name"
      android:value="Meeting Notification"
     />
    <meta-data
    android:name="live.videosdk.rnfgservice.notification_channel_description"
    android:value="Whenever meeting started notification will appear."
    />
    <meta-data
    android:name="live.videosdk.rnfgservice.notification_color"
    android:resource="@color/red"
    />
    <service android:name="live.videosdk.rnfgservice.ForegroundService" android:foregroundServiceType="mediaProjection"></service>
    <service android:name="live.videosdk.rnfgservice.ForegroundServiceTask"></service>
  </application>
</manifest>

Шаг 2. Свяжите пару зависимостей внутренней библиотеки в файле android/app/build.gradle

dependencies {
    compile project(':rnfgservice') 
    compile project(':rnwebrtc') 
    compile project(':rnincallmanager')
  }

Включить зависимости в android/settings.gradle

include ':rnwebrtc'
project(':rnwebrtc').projectDir = new File(rootProject.projectDir, '../node_modules/@videosdk.live/react-native-webrtc/android')

include ':rnincallmanager'
project(':rnincallmanager').projectDir = new File(rootProject.projectDir, '../node_modules/@videosdk.live/react-native-incallmanager/android')

include ':rnfgservice'
project(':rnfgservice').projectDir = new File(rootProject.projectDir, '../node_modules/@videosdk.live/react-native-foreground-service/android')

Обновите MainApplication.java, чтобы использовать InCallManager и запускать некоторые службы переднего плана.

import live.videosdk.rnfgservice.ForegroundServicePackage;
import live.videosdk.rnincallmanager.InCallManagerPackage;
import live.videosdk.rnwebrtc.WebRTCModulePackage;

public class MainApplication extends Application implements ReactApplication {
  private static List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          /* Initialise foreground service, incall manager and webrtc module */
          new ForegroundServicePackage(),
          new InCallManagerPackage(),
          new WebRTCModulePackage(),
      );
  }
}

Некоторые устройства могут столкнуться с проблемой WebRTC. Чтобы решить эту проблему, обновите файл android/gradle.properties, указав следующее.

/* This one fixes a weird WebRTC runtime problem on some devices. */
android.enableDexingArtifactTransform.desugaring=falseCopy

Если вы используете proguard, внесите указанные ниже изменения в файл android/app/proguard-rules.pro (это необязательно)

-keep class org.webrtc.** { *; }

Шаг 3. Обновите файл colors.xml новыми цветами для внутренних зависимостей.

<resources>
    <item name="red" type="color">#FC0303</item>
    <integer-array name="androidcolors">
    <item>@color/red</item>
    </integer-array>
</resources>

Настройка iOS

Шаг 1: Установите react-native-incallmanager

$ yarn add @videosdk.live/react-native-incallmanager

Шаг 2: Убедитесь, что вы используете CocoaPods 1.10 или выше. Чтобы обновить CocoaPods, вы можете просто снова установить гем.

$[sudo] gem install cocoapods

Шаг 3: Связывание вручную (если react-native-incall-manager не связывается автоматически)

  • Перетащите node_modules/@videosdk.live/react-native-incall-manager/ios/RNInCallManager.xcodeproj в раздел ‹your_xcode_project›/Libraries.
  • Выберите ‹your_xcode_project› --› Фазы сборки --› Связать двоичный файл с библиотеками
  • Перетащите Libraries/RNInCallManager.xcodeproj/Products/libRNInCallManager.a, чтобы связать двоичный файл с библиотеками.
  • Выберите ‹your_xcode_project› --› Настройки сборки В пути поиска заголовков добавьте $(SRCROOT)/../node_modules/@videosdk.live/react-native-incall-manager/ios/RNInCallManager

Шаг 4: Измените путь к react-native-webrtc

pod ‘react-native-webrtc’, :path => ‘../node_modules/@videosdk.live/react-native-webrtc’

Шаг 5: Измените версию вашей платформы

  • Вы должны изменить поле платформы подфайла на 11.0 или выше, так как react-native-webrtc не поддерживает платформу IOS ‹ 11: ios, «11.0»

Шаг 6: После обновления версии необходимо установить модули

Pod install

Шаг 7: Затем добавьте «libreact-native-webrtc.a в Link Binary с библиотеками. В целевой папке основного проекта.»

Шаг 8: Теперь добавьте следующие разрешения в info.plist (папка проекта/IOS/имя проекта/info.plist):

<key>NSCameraUsageDescription</key>
<string>Camera permission description</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone permission description</string>

Регистрация службы

Зарегистрируйте службы Video SDK в корневом файле index.js для службы инициализации.

import { register } from '@videosdk.live/react-native-sdk';
import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';
import App from './src/App.js';
​
// Register the service
register();
AppRegistry.registerComponent(appName, () => App);

Начните писать свой код прямо сейчас

Шаг 1. Начните работу с API.js

Прежде чем переходить к чему-либо еще, мы должны написать API для создания уникального идентификатора встречи. Вам потребуется токен авторизации, вы можете сгенерировать его либо с помощью videosdk-rtc-api-server-examples, либо сгенерировать его из Video SDK Dashboard для разработчика.

// Auth token we will use to generate a meeting and connect to it
export const authToken = "<Generated-from-dashbaord>";

// API call to create meeting
export const createMeeting = async ({ token }) => {
  const res = await fetch(`https://api.videosdk.live/v1/meetings`, {
    method: "POST",
    headers: {
      authorization: `${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ region: "sg001" }),
  });

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

Шаг 2: Wireframe App.js со всеми компонентами

Чтобы создать каркас App.js, мы будем использовать хуки Video SDK и поставщики контекста. Video SDK предоставляет перехватчики MeetingProvider, MeetingConsumer, useMeeting и useParticipant. Давайте разберемся в каждом из них.

Сначала мы рассмотрим Context Provider и Consumer. Контекст в основном используется, когда некоторые данные должны быть доступны многим компонентам на разных уровнях вложенности.

  • MeetingProvider. Это поставщик контекста. Он принимает значения config и token в качестве реквизита. Компонент Provider принимает свойство value для передачи потребляющим компонентам, которые являются потомками этого Provider. Один провайдер может быть подключен ко многим потребителям. Провайдеры могут быть вложены друг в друга, чтобы переопределять значения, расположенные глубже в дереве.
  • MeetingConsumer : это потребитель контекста. Все потребители, которые являются потомками провайдера, будут перерисовываться всякий раз, когда изменяется свойство значения провайдера.
  • useMeeting : это API-интерфейс ответного хука для встречи. Он включает в себя всю информацию, связанную с собранием, такую ​​как присоединение, выход, включение/отключение микрофона или веб-камеры и т. д.
  • useParticipant : это API-интерфейс хука участника. Хук useParticipant отвечает за обработку всех событий и реквизитов, связанных с одним конкретным участником, таких как имя, webcamStream, micStream и т. д.

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

Давайте начнем с изменения пары строк кода в App.js.

import React, { useState, useMemo, useRef, useEffect } from "react";
import {
  SafeAreaView,
  TouchableOpacity,
  Text,
  TextInput,
  View,
  FlatList,
  Clipboard,
} from "react-native";
import {
  MeetingProvider,
  useMeeting,
  useParticipant,
  MediaStream,
  RTCView,
  Constants,
} from "@videosdk.live/react-native-sdk";
import { createMeeting, authToken } from "./api";

// Responsible for either schedule new meeting or to join existing meeting as a host or as a viewer.
function JoinScreen({ getMeetingAndToken, setMode }) {
  return null;
}

// Responsible for managing participant video stream
function ParticipantView(props) {
  return null;
}

// Responsible for managing meeting controls such as toggle mic / webcam and leave
function Controls() {
  return null;
}

// Responsible for Speaker side view, which contains Meeting Controls(toggle mic/webcam & leave) and Participant list
function SpeakerView() {
  return null;
}

// Responsible for Viewer side view, which contains video player for streaming HLS and managing HLS state (HLS_STARTED, HLS_STOPPING, HLS_STARTING, etc.)
function ViewerView() {
  return null;
}

// Responsible for managing two view (Speaker & Viewer) based on provided mode (`CONFERENCE` & `VIEWER`)
function Container(props) {
  return null;
}

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

  //State to handle the mode of the participant i.e. CONFERNCE or VIEWER
  const [mode, setMode] = useState("CONFERENCE");

  //Getting MeetingId from the API we created earlier

  const getMeetingAndToken = async (id) => {
    const meetingId =
      id == null ? await createMeeting({ token: authToken }) : id;
    setMeetingId(meetingId);
  };


  return authToken && meetingId ? (
    <MeetingProvider
      config={{
        meetingId,
        micEnabled: true,
        webcamEnabled: true,
        name: "C.V. Raman",
        //These will be the mode of the participant CONFERENCE or VIEWER
        mode: mode,
      }}
      token={authToken}
    >
      <Container />
    </MeetingProvider>
  ) : (
    <JoinScreen getMeetingAndToken={getMeetingAndToken} setMode={setMode} />
  );
}

export default App;

Шаг 3: Реализуйте экран присоединения

Экран присоединения будет работать как средство планирования новой встречи или присоединения к существующей встрече в качестве организатора или зрителя.

У них будет 3 кнопки:

  1. Присоединиться как организатор: при нажатии этой кнопки человек присоединится к введенному `meetingId` как `HOST`.
  2. Присоединиться как зритель: при нажатии этой кнопки человек присоединится к введенному `meetingId` как `ПРОСМОТРИТЕЛЬ`.
  3. Создать комнату-студию: при нажатии этой кнопки человек присоединится к новой встрече как «ХОЗЯИН».
function JoinScreen({ getMeetingAndToken, setMode }) {
  const [meetingVal, setMeetingVal] = useState("");

  const JoinButton = ({ value, onPress }) => {
    return (
      <TouchableOpacity
        style={{
          backgroundColor: "#1178F8",
          padding: 12,
          marginVertical: 8,
          borderRadius: 6,
        }}
        onPress={onPress}
      >
        <Text style={{ color: "white", alignSelf: "center", fontSize: 18 }}>
          {value}
        </Text>
      </TouchableOpacity>
    );
  };
  return (
    <SafeAreaView
      style={{
        flex: 1,
        backgroundColor: "black",
        justifyContent: "center",
        paddingHorizontal: 6 * 10,
      }}
    >
      <TextInput
        value={meetingVal}
        onChangeText={setMeetingVal}
        placeholder={"XXXX-XXXX-XXXX"}
        placeholderTextColor={"grey"}
        style={{
          padding: 12,
          borderWidth: 1,
          borderColor: "white",
          borderRadius: 6,
          color: "white",
          marginBottom: 16,
        }}
      />
      <JoinButton
        onPress={() => {
          getMeetingAndToken(meetingVal);
        }}
        value={"Join as Host"}
      />
      <JoinButton
        onPress={() => {
          setMode("VIEWER");
          getMeetingAndToken(meetingVal);
        }}
        value={"Join as Viewer"}
      />
      <Text
        style={{
          alignSelf: "center",
          fontSize: 22,
          marginVertical: 16,
          fontStyle: "italic",
          color: "grey",
        }}
      >
        ---------- OR ----------
      </Text>

      <JoinButton
        onPress={() => {
          getMeetingAndToken();
        }}
        value={"Create Studio Room"}
      />
    </SafeAreaView>
  );
}

Шаг 4: Реализуйте компонент-контейнер

  • Следующим шагом является создание контейнера, который будет управлять компонентами Join screen, SpeakerView и ViewerView на основе mode.
  • Мы проверим режим localParticipant, если это CONFERENCE, мы покажем SpeakerView, иначе мы покажем ViewerView.
function Container() {
  const { join, changeWebcam, localParticipant } = useMeeting({
    onError: (error) => {
      console.log(error.message);
    },
  });

  return (
    <View style={{ flex: 1 }}>
      {localParticipant?.mode == Constants.modes.CONFERENCE ? (
        <SpeakerView />
      ) : localParticipant?.mode == Constants.modes.VIEWER ? (
        <ViewerView />
      ) : (
        <View
          style={{
            flex: 1,
            justifyContent: "center",
            alignItems: "center",
            backgroundColor: "black",
          }}
        >
          <Text style={{ fontSize: 20, color: "white" }}>
            Press Join button to enter studio.
          </Text>
          <Button
            btnStyle={{
              marginTop: 8,
              paddingHorizontal: 22,
              padding: 12,
              borderWidth: 1,
              borderColor: "white",
              borderRadius: 8,
            }}
            buttonText={"Join"}
            onPress={() => {
              join();
              setTimeout(() => {
                changeWebcam();
              }, 300);
            }}
          />
        </View>
      )}
    </View>
  );
}

// Common Component which will also be used in Controls Component
const Button = ({ onPress, buttonText, backgroundColor, btnStyle }) => {
  return (
    <TouchableOpacity
      onPress={onPress}
      style={{
        ...btnStyle,
        backgroundColor: backgroundColor,
        padding: 10,
        borderRadius: 8,
      }}
    >
      <Text style={{ color: "white", fontSize: 12 }}>{buttonText}</Text>
    </TouchableOpacity>
  );
};

Шаг 5: Реализуйте SpeakerView

Следующим шагом является создание компонентов SpeakerView и Controls для управления такими функциями, как присоединение, выход, отключение и включение звука.

  1. Мы получим все participants из хука useMeeting и отфильтруем их для режима, установленного на CONFERENCE, чтобы на экране отображались только динамики.
function SpeakerView() {
  // Get the Participant Map and meetingId
  const { meetingId, participants } = useMeeting({});

  // For getting speaker participant, we will filter out `CONFERENCE` mode participant
  const speakers = useMemo(() => {
    const speakerParticipants = [...participants.values()].filter(
      (participant) => {
        return participant.mode == Constants.modes.CONFERENCE;
      }
    );
    return speakerParticipants;
  }, [participants]);

  return (
    <SafeAreaView style={{ backgroundColor: "black", flex: 1 }}>
      {/* Render Header for copy meetingId and leave meeting*/}
      <HeaderView />

      {/* Render Participant List */}
      {speakers.length > 0 ? (
        <FlatList
          data={speakers}
          renderItem={({ item }) => {
            return <ParticipantView participantId={item.id} />;
          }}
        />
      ) : null}

      {/* Render Controls */}
      <Controls />
    </SafeAreaView>
  );
}

function HeaderView() {
  const { meetingId, leave } = useMeeting();
  return (
    <View
      style={{
        flexDirection: "row",
        padding: 16,
        justifyContent: "space-evenly",
        alignItems: "center",
      }}
    >
      <Text style={{ fontSize: 24, color: "white" }}>{meetingId}</Text>
      <Button
        btnStyle={{
          borderWidth: 1,
          borderColor: "white",
        }}
        onPress={() => {
          Clipboard.setString(meetingId);
          alert("MeetingId copied successfully");
        }}
        buttonText={"Copy MeetingId"}
        backgroundColor={"transparent"}
      />
      <Button
        onPress={() => {
          leave();
        }}
        buttonText={"Leave"}
        backgroundColor={"#FF0000"}
      />
    </View>
  );
}

function Container(){
  ...

  const mMeeting = useMeeting({
    onMeetingJoined: () => {
      // We will pin the local participant if he joins in CONFERENCE mode
      if (mMeetingRef.current.localParticipant.mode == "CONFERENCE") {
        mMeetingRef.current.localParticipant.pin();
      }
    },
    ...
  });

  // We will create a ref to meeting object so that when used inside the
  // Callback functions, meeting state is maintained
  const mMeetingRef = useRef(mMeeting);
  useEffect(() => {
    mMeetingRef.current = mMeeting;
  }, [mMeeting]);

  return <>...</>;
}

2. Мы создадим ParticipantView, чтобы показать участникам медиа. Для этого будет использоваться webcamStream из хука useParticipant для воспроизведения мультимедиа участника.

function ParticipantView({ participantId }) {
  const { webcamStream, webcamOn } = useParticipant(participantId);
  return webcamOn && webcamStream ? (
    <RTCView
      streamURL={new MediaStream([webcamStream.track]).toURL()}
      objectFit={"cover"}
      style={{
        height: 300,
        marginVertical: 8,
        marginHorizontal: 8,
      }}
    />
  ) : (
    <View
      style={{
        backgroundColor: "grey",
        height: 300,
        justifyContent: "center",
        alignItems: "center",
        marginVertical: 8,
        marginHorizontal: 8,
      }}
    >
      <Text style={{ fontSize: 16 }}>NO MEDIA</Text>
    </View>
  );
}

3. Мы добавим компонент Controls, который позволит динамику переключать медиа и запускать/останавливать HLS.

function Controls() {
  const { toggleWebcam, toggleMic, startHls, stopHls, hlsState } = useMeeting(
    {}
  );

  const _handleHLS = async () => {
    if (!hlsState || hlsState === "HLS_STOPPED") {
      startHls({
        layout: {
          type: "SPOTLIGHT",
          priority: "PIN",
          gridSize: 4,
        },
        theme: "DARK",
        orientation: "portrait",
      });
    } else if (hlsState === "HLS_STARTED" || hlsState === "HLS_PLAYABLE") {
      stopHls();
    }
  };

  return (
    <View
      style={{
        padding: 24,
        flexDirection: "row",
        justifyContent: "space-between",
      }}
    >
      <Button
        onPress={() => {
          toggleWebcam();
        }}
        buttonText={"Toggle Webcam"}
        backgroundColor={"#1178F8"}
      />
      <Button
        onPress={() => {
          toggleMic();
        }}
        buttonText={"Toggle Mic"}
        backgroundColor={"#1178F8"}
      />
      {hlsState === "HLS_STARTED" ||
      hlsState === "HLS_STOPPING" ||
      hlsState === "HLS_STARTING" ||
      hlsState === "HLS_PLAYABLE" ? (
        <Button
          onPress={() => {
            _handleHLS();
          }}
          buttonText={
            hlsState === "HLS_STARTED"
              ? `Live Starting`
              : hlsState === "HLS_STOPPING"
              ? `Live Stopping`
              : hlsState === "HLS_PLAYABLE"
              ? `Stop Live`
              : `Loading...`
          }
          backgroundColor={"#FF5D5D"}
        />
      ) : (
        <Button
          onPress={() => {
            _handleHLS();
          }}
          buttonText={`Go Live`}
          backgroundColor={"#1178F8"}
        />
      )}
    </View>
  );
}

Шаг 6: Реализуйте ViewerView

Когда ХОЗЯИН (участник режима «КОНФЕРЕНЦИЯ») запускает прямую трансляцию, зритель сможет ее увидеть.

Для реализации просмотра плеера мы будем использовать react-native-video. Будет полезно воспроизвести HLS-поток.

Давайте сначала добавим этот пакет.

Для NPM:

npm install react-native-video

Для пряжи:

yarn add react-native-video

С установленным react-native-video мы получим hlsUrls и isHlsPlayable из хука useMeeting, который будет использоваться для воспроизведения HLS в плеере.

//Add imports
// imports react-native-video
import Video from "react-native-video";

function ViewerView({}) {
  const { hlsState, hlsUrls } = useMeeting();

  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: "black" }}>
      {hlsState == "HLS_PLAYABLE" ? (
        <>
          {/* Render Header for copy meetingId and leave meeting*/}
          <HeaderView />

          {/* Render VideoPlayer that will play `downstreamUrl`*/}
          <Video
            controls={true}
            source={{
              uri: hlsUrls.downstreamUrl,
            }}
            resizeMode={"stretch"}
            style={{
              flex: 1,
              backgroundColor: "black",
            }}
            onError={(e) => console.log("error", e)}
          />
        </>
      ) : (
        <SafeAreaView
          style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
        >
          <Text style={{ fontSize: 20, color: "white" }}>
            HLS is not started yet or is stopped
          </Text>
        </SafeAreaView>
      )}
    </SafeAreaView>
  );
}

Запустите свой код сейчас

//for android
npx react-native run-android

//for ios
npx react-native run-ios

Застрял где-нибудь? Посмотрите этот пример кода на GitHub

Заключение

Благодаря этому мы успешно создали приложение React Native Live Streaming, используя видео SDK в React-Native. Если вы хотите добавить такие функции, как обмен сообщениями в чате и совместное использование экрана, вы всегда можете ознакомиться с нашей документацией. Если у вас возникнут трудности с реализацией, вы можете связаться с нами в нашем дискорд-сообществе.

Ресурсы