# BytePlus React Native SDK

## Introduction

BytePlus React Native SDK is the audio and video call SDK provided by BytePlus for React Native.

## Minimum Requirements

Require Node >= 18.

| Platform | Version      |
| -------- | ------------ |
| Android  | 6.0 (API 23) |
| iOS      | 13.4         |

## Install

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

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

## Attention

- In Android/iOS scenarios, the screen sharing method is slightly different. For details, please refer to [Android screen sharing](https://docs.byteplus.com/en/docs/byteplus-rtc/docs-124176) and [iOS screen sharing](https://docs.byteplus.com/en/docs/byteplus-rtc/docs-124177).
- Not support debug in iOS simulator, using real device instead.
- **If you need 16KB page size supported in Android or React Native New arch supported, please contact us for help, we will provide an offline sdk package.**

## Basic Example

### RTC Core Definition

`@/core/index.ts`

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

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

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

  /** Engine related */
  async createEngine({appID}: ICreateRTCEngineOptions) {
    this.engine = await this.manager!.createRTCEngine({appID});
  }
  setExtensionConfig() {
    if (Platform.OS === 'ios') {
      // https://docs.byteplus.com/en/docs/byteplus-rtc/docs-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;
  }

  /** Room related */
  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();
```

### JoinRoom Page

`@/page/login.tsx`

Mainly focus on the usage of `NativeViewComponent`. Note that after the component is registered, call `setLocalVideoCanvas` in `onLoad` to set the local rendering view. The same applies to remote users.

```typescript
import { Platform } from 'react-native';
import { request, PERMISSIONS } from 'react-native-permissions';
import { NativeViewComponent, StreamIndex, RenderMode } from '@byteplus/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 () => {
        /** Fetch user's device permission */
        await requestDevicePermission();

        /** Engine Initialization */
        await RTCClient.createEngine({
            appID: 'Your appId',
        });

        if (Platform.OS === 'ios') {
            /** Invoke `setExtensionConfig`, if you need to use screen sharing */
            RTCClient.setExtensionConfig();
        }

        /** Set relative callbacks */
        RTCClient.setRTCVideoEventHandler(...Your custom events);

        /** Set local stream renderer  */
        RTCClient.setLocalVideoCanvas(
            StreamIndex.STREAM_INDEX_MAIN,
            {
                viewId,
                renderMode: RenderMode.ByteRTCRenderModeFit,
            },
        );
        /** Create room instance */
        RTCClient.createRoom(roomId!);
        /** Set relative callbacks */
        RTCClient.setRTCRoomEventHandler(roomEventListeners);

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

        /** Capture local streams */
        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;
```
