# 火山引擎 React Native SDK

## 简介

火山引擎 React Native SDK 是火山引擎提供的 React Native 端音视频通话 SDK。

## 最低要求

要求 Node >= 18。

| 端      | 最低版本     |
| ------- | ------------ |
| Android | 6.0 (API 23) |
| iOS     | 13.4         |

## 安装

```shell
npm install @volcengine/react-native-rtc
```

```shell
yarn add @volcengine/react-native-rtc
```

## 注意

- 在 Android/iOS 场景中, 屏幕共享的方式略有不同, 详情可参考 [Android 屏幕共享](https://www.volcengine.com/docs/6348/124176) 和 [iOS 屏幕共享](https://www.volcengine.com/docs/6348/124177)。
- iOS 暂不支持在模拟器中运行, 请使用真机进行调试。
- SDK 自 1.2.0 版本起, Android 支持 16KB, 且 1.1.x -> 1.2.0 有部分 BreakChange, 可参考 [1.2.0 版本变更内容](https://bytedance.larkoffice.com/docx/Eal3drV40oEitIxPDUncRRURnQd) 进行修改。
- SDK 自 1.3.0 版本起支持新架构，推荐使用 React Native 0.77.3+ 版本。

## 基础示例

### 核心调用定义

`@/core/index.ts`

```typescript
import {
  RTCManager,
  IEngine,
  IRoom,
  RTCVideoEventHandler,
  RTCRoomEventHandler,
  IJoinRoomProps,
  ICreateRTCEngineOptions,
} from '@volcengine/react-native-rtc';

class RTCClient {
  manager?: RTCManager;
  engine?: IEngine | null;
  room?: IRoom | null;

  constructor() {
    this.manager = new RTCManager();
  }

  /** 引擎相关 */
  async createEngine({appID}: ICreateRTCEngineOptions) {
    this.engine = await this.manager!.createRTCEngine({appID});
  }
  setExtensionConfig() {
    if (Platform.OS === 'ios') {
      // https://www.volcengine.com/docs/6348/125721
      return this.engine?.ios_setExtensionConfig("Your iOS App's Group ID");
    }
  }
  setRTCVideoEventHandler(handlers: RTCVideoEventHandler) {
    this.engine?.setRtcVideoEventHandler(handlers);
  }
  setRTCRoomEventHandler(handlers: RTCRoomEventHandler) {
    this.room?.setRTCRoomEventHandler(handlers);
  }
  startAudioCapture() {
    return this.engine?.startAudioCapture();
  }
  startVideoCapture() {
    return this.engine?.startVideoCapture();
  }
  destroyEngine() {
    this.leaveRoom();
    this.room?.destroy();
    this.room = null;
    this.manager!.destroyRTCEngine();
    this.engine = null;
  }

  /** 房间相关 */
  joinRoom(params: IJoinRoomProps) {
    return this.room?.joinRoom({
      token: 'Your token',
      ...params,
    });
  }
  leaveRoom() {
    this.effectPlayerUnloadAll();
    this.stopScreenCapture();
    this.room?.leaveRoom();
  }
  createRoom(roomId: string) {
    this.room = this.engine?.createRTCRoom(roomId);
    return this.room;
  }
}

export default new RTCClient();
```

### 基础加房页面

`@/page/login.tsx`

主要关注 `NativeViewComponent` 的使用方式, 须注意组件注册完成后，在 `onLoad` 中调用 `setLocalVideoCanvas` 设置本地渲染视图，远端用户同理。

```typescript
import { Platform } from 'react-native';
import { request, PERMISSIONS } from 'react-native-permissions';
import { NativeViewComponent, StreamIndex, RenderMode } from '@volcengine/react-native-rtc';
import RTCClient from '@/core';

const viewId = 'my-view';

const Login = () => {

    const requestDevicePermission = async () => {
        if (Platform.OS === 'ios') {
            await request(PERMISSIONS.IOS.CAMERA);
            await request(PERMISSIONS.IOS.MICROPHONE);
        } else {
            await request(PERMISSIONS.ANDROID.CAMERA);
            await request(PERMISSIONS.ANDROID.RECORD_AUDIO);
        }
    };

    const handleViewLoad = async () => {
        /** 获取权限 */
        await requestDevicePermission();

        /** 初始化引擎 */
        await RTCClient.createEngine({
            appID: 'Your appId',
        });

        if (Platform.OS === 'ios') {
            /** 按需调用, 如果有屏幕共享需求, 需调用此方法 */
            RTCClient.setExtensionConfig();
        }

        /** 设置相关回调函数 */
        RTCClient.setRTCVideoEventHandler(...Your custom events);

        /** 设置本地渲染视图 */
        RTCClient.setLocalVideoCanvas(
            StreamIndex.STREAM_INDEX_MAIN,
            {
                viewId,
                renderMode: RenderMode.ByteRTCRenderModeFit,
            },
        );
        /** 创建房间实例 */
        RTCClient.createRoom(roomId!);
        /** 设置相关回调函数 */
        RTCClient.setRTCRoomEventHandler(roomEventListeners);

        /** 加入房间 */
        RTCClient.joinRoom({
            token: 'Your RTC Token',
            userId: localUser.userId,
            roomConfigs: {
                isAutoPublishVideo: true,
                isAutoPublishAudio: true,
                isAutoSubscribeAudio: true,
                isAutoSubscribeVideo: true,
            },
        });

        /** 采集本地流 */
        RTCClient.startVideoCapture();
        RTCClient.startAudioCapture();
    }

    return (
        <KeyboardAvoidingView
            behavior={Platform.OS === "ios" ? "padding" : "height"}
        >
            <NativeViewComponent
                viewId={viewId}
                onLoad={handleViewLoad}
                kind={
                    Platform.select({
                        android: 'TextureView',
                        ios: 'UIView',
                    })!
                }
            />
        </KeyboardAvoidingView>
    );
};

export default Login;
```
