GithubHelp home page GithubHelp logo

100mslive / 100ms-react-native Goto Github PK

View Code? Open in Web Editor NEW
76.0 7.0 29.0 86.58 MB

React Native Live Streaming, Video Conferencing SDK & Sample App

Home Page: https://www.100ms.live/

License: MIT License

Java 1.39% JavaScript 3.87% Swift 8.79% C 0.01% Objective-C 1.36% Ruby 0.44% TypeScript 74.83% Starlark 0.10% Kotlin 8.65% Shell 0.04% Makefile 0.05% C++ 0.23% Objective-C++ 0.24%
audio conference hls live react-native rtmp streaming video webrtc ffmpeg hacktoberfest player typescript react

100ms-react-native's Introduction

100ms-svg

npm Build license quality collaborators Documentation Discord Firebase TestFlight Activity Register

100ms React Native SDK

Integrate Real Time Audio and Video conferencing, Interactive Live Streaming, and Chat in your apps with 100ms React Native SDK.

With support for HLS and RTMP Live Streaming and Recording, Picture-in-Picture (PiP), one-to-one Video Call Modes, Audio Rooms, Video Player and much more, add immersive real-time communications to your apps.

Package Version
@100mslive/react-native-room-kit npm
@100mslive/react-native-hms npm
@100mslive/react-native-video-plugin npm

๐Ÿ“– Read the Complete Documentation here: https://www.100ms.live/docs/react-native/v2/foundation/basics

๐Ÿƒ Example App

๐Ÿ“ฒ Download the Example iOS app here: https://testflight.apple.com/join/v4bSIPad

๐Ÿค– Download the Example Android app here: https://appdistribution.firebase.dev/i/7b7ab3b30e627c35

To get a better understanding of how the example app is structured, what to do on onJoin, onTrack and onPeer listeners, creating PeerTrackNodes, how to use Redux, and what type of layouts and sorting you can implement in your app, checkout Example App's README

To run the Example app on your system, follow these steps -

  1. In the project root, run npm install
  2. Go to the example folder, cd example
  3. In the example folder, run npm install
  4. To run on Android, run npx react-native run-android
  5. To run on iOS, first install the pods in iOS folder, cd ios; pod install. Then, set the Correct Development Team in Xcode Signing & Capabilities section. Then, in example folder, run npx react-native run-ios

Troubleshooting Guide for resolving issues in running the Example app is available here.

โ˜๏ธ Minimum Configuration

  • Support for React Native 0.64.4 or above
  • Support for Java 8 or above
  • Support for Android API level 24 or above
  • Xcode 13 or above
  • Support for iOS 12 or above

๐Ÿค Recommended Configuration

  • React Native 0.68.0 or above
  • Java 11 or above
  • Android API level 33 or above
  • Xcode 14 or above
  • iOS 16 or above

๐Ÿ“ฑ Supported Devices

  • The Android SDK supports Android API level 21 and higher. It is built for armeabi-v7a, arm64-v8a, x86, and x86_64 architectures. Devices running Android OS 11 or above is recommended.

  • iPhone & iPads with iOS version 12 or above are supported. Devices running iOS 16 or above is recommended.

Installation

npm install @100mslive/react-native-hms --save

๐Ÿ“ฒ Download the Sample iOS App here: https://testflight.apple.com/join/v4bSIPad

๐Ÿค– Download the Sample Android App here: https://appdistribution.firebase.dev/i/7b7ab3b30e627c35

More information about Integrating the SDK is available here.

๐Ÿ” Permissions

๐Ÿ“ฑ For iOS Permissions

Add following lines in Info.plist file

<key>NSCameraUsageDescription</key>
<string>Please allow access to Camera to enable video conferencing</string>
<key>NSMicrophoneUsageDescription</key>
<string>Please allow access to Microphone to enable video conferencing</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Please allow access to network usage to enable video conferencing</string>

๐Ÿค– For Android Permissions

Add following permissions in AndroidManifest.xml

<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

You will also need to request Camera and Record Audio permissions at runtime before you join a call or display a preview. Please follow Android Documentation for runtime permissions.

We suggest using react-native-permission to acquire permissions from both platforms.

More information about Audio Video Permission on iOS & Android is available here.

The package exports all the classes and a HMSSDK class that manages everything.

First invoke the build method which returns an instance of HMSSDK. Save this instance to perform all actions related to 100ms.

import { HMSSDK } from "@100mslive/react-native-hms";

/**
 * create HMSSDK instance using the build method & save it for further usage
 *
 * Important Note: Don't build new `HMSSDK` instance before destroying the previous one.
 * for more info checkout {@link https://www.100ms.live/docs/react-native/v2/how--to-guides/install-the-sdk/hmssdk#what-does-destroy-method-do}
 */
const hmsInstance = await HMSSDK.build();

Fetch token using room-code method (Recommended)

We can get the authentication token using room-code from meeting URL.

Let's understand the subdomain and code from the sample URL

In this sample url: http://100ms-rocks.app.100ms.live/meeting/abc-defg-hij

  • Subdomain is 100ms-rocks
  • Room code is abc-defg-hij

Now to get the room-code from meeting URL, we can write our own logic or use the getCode method from here

To generate token we will be using getAuthTokenByRoomCode method available on HMSSDK instance. This method has roomCode as a required parameter and userId & endpoint as optional parameter.

Let's checkout the implementation:

/**
 * `getAuthTokenByRoomCode` returns a promise which is resolved with "auth token"
 * checkout {@link https://www.100ms.live/docs/react-native/v2/how--to-guides/install-the-sdk/hmssdk#what-does-destroy-method-do}
 */
const token = await hmsInstance.getAuthTokenByRoomCode("YOUR_ROOM_CODE");

/**
 * Create `HMSConfig` with the above auth token and username
 */
const hmsConfig = new HMSConfig({
  authToken: token,
  username: "John Appleseed",
});

Get temporary token from dashboard

To test audio/video functionality, you need to connect to a 100ms Room. Please check the following steps for the same -

  1. Navigate to your 100ms dashboard or create an account if you don't have one.
  2. Use the Video Conferencing Starter Kit to create a room with a default template assigned to it to test this app quickly.
  3. Go to the Rooms page in your dashboard, click on the Room Id of the room you created above, and click on the Join Room button on the top right.
  4. You will see 100ms demo URLs for the roles created when you deployed the starter kit; you can click on the 'key' icon to copy the token and update the AUTH_TOKEN variable in "App.js" file.

    Token from 100ms dashboard is for testing purposes only, For production applications you must generate tokens on your own server. Refer to the Management Token section in Authentication and Tokens guide for more information.

Add Event Listeners to get notified about actions happening in the 100ms Room.

The most commonly used Events are onJoin, onPeerUpdate & onTrackUpdate. All the available actions can be found in the HMSUpdateListenerActions class.

The Event Listeners are to be used for handling any update happening in 100ms Room.

const hmsInstance = await HMSSDK.build();

// instance acquired from build() method
hmsInstance.addEventListener(
  HMSUpdateListenerActions.ON_JOIN,
  joinSuccess, // function that will be called Joining a Room is successful
);

The detailed QuickStart Guide is available here.

To interact with peers in audio or video call, the user needs to Join a Room.

When user indicates that they want to join the room, your app should have -

  1. User Name - The name which should be displayed to other peers in the room.

  2. Authentication Token - The Client side Authentication Token generated by the Token Service. Details about how to create Auth Tokens are available here.

Additionally, you can also pass these fields while Joining a Room -

  1. Track Settings - Such as joining a Room with Muted Audio or Video using the HMSTrackSettings object. More information is available here.

  2. Peer Metadata - This can be used to pass any additional metadata associated with the user using metadata of HMSConfig object. For Eg: user-id mapping at the application side. More information is available here.

NOTE: ON_JOIN Event Listener must be attached before calling join function to receive the event callback.

// create HMSSDK instance using the build function
const hmsInstance = await HMSSDK.build();

// Generate 100ms Auth Token by Room Code
const token = await hmsInstance.getAuthTokenByRoomCode("abc-defg-hij"); // Sample Room Code

// You'll need to add Event Listeners for HMSUpdateListenerActions, which are invoked to notify about updates happening in the room like a peer joins/leaves, a track got muted/unmuted, any errors that occur, etc.
hmsInstance.addEventListener(HMSUpdateListenerActions.ON_JOIN, onJoinSuccess);
hmsInstance.addEventListener(
  HMSUpdateListenerActions.ON_PEER_UPDATE,
  onPeerUpdate,
);
hmsInstance.addEventListener(
  HMSUpdateListenerActions.ON_TRACK_UPDATE,
  onTrackUpdate,
);
hmsInstance.addEventListener(HMSUpdateListenerActions.ON_ERROR, onError);

// Next, create an object of HMSConfig class using the available joining configurations.
let config = new HMSConfig({
  authToken: token, // client-side token generated by `getAuthTokenByRoomCode` method
  username: "John Appleseed",
});

// Now, we are primed to join the room. All you have to do is calling join by passing the config object
hmsInstance.join(config);

More information about Joining a Room is available here.

Basic Mechanism of using 100ms APIs

For invoking any actions simply use the HMSSDK instance created in above steps. Few common examples of using it are as follows -

// To Mute Audio of local peer - other peers will stop hearing audio
hmsInstance?.localPeer?.localAudioTrack()?.setMute(true);

// To Mute Video of local peer - other peers will stop seeing video
hmsInstance?.localPeer?.localVideoTrack()?.setMute(true);

// Switch Camera from Front to Back or vice-versa
hmsInstance?.localPeer?.localVideoTrack()?.switchCamera();

// Leave the ongoing Room (async function)
await hmsInstance?.leave();

// To send a Chat Message to all peers in Room
await hmsInstance?.sendBroadcastMessage("Hello Everyone! ๐Ÿ‘‹");

More information about using HMSSDK APIs is available here.

It all comes down to this. All the setup so far has been done so that we can show Live Streaming Video in our beautiful apps.

100ms React Native SDK provides HmsView component that renders the video on the screen. You can access HmsView from the HMSSDK instance created in above steps.

We simply have to pass a Video Track's trackId to the HmsView to begin automatic rendering of Live Video Stream.

We can also optionally pass props like key, scaleType, mirror to customize the HmsView component.

// get HmsView from the HMSSDK instance created earlier
const HmsView = hmsInstance.HmsView;

<HmsView trackId={videoTrackId} key={videoTrackId} style={styles.hmsView} />;

const styles = StyleSheet.create({
  hmsView: {
    height: "100%",
    width: "100%",
  },
});
  • One HmsView component can only be connected with one video trackId. To display multiple videos you have to create multiple instances of HmsView component.

  • It's recommended to always pass the key property while creating HmsView. If a null or undefined trackId is passed in HmsView you will have to unmount and remount with the new trackId. Using the key prop and passing trackId to it automatically achieves this.

  • HmsView component requires width and height in style prop to set bounds of the tile that will show the video stream.

  • Once the requirement of that HmsView is finished it should ALWAYS be disposed.

  • Recommended practice is to show maximum of 3 to 4 HmsView on a single page/screen of the app. This avoids overloading network data consumption & video decoding resources of the device.

More information about Rendering Videos is available here.

Always use ON_PEER_UPDATE and ON_TRACK_UPDATE listeners, these listeners get updated localPeer and remotePeers whenever there is any event related to these values. The following code snippet shows a simple example of attaching Track Updates Event Listener & using it to show a Video.

// In this example code snippet, We are keeping things very simple.
// You will get an overview of how to render `HMSView`s for list of `trackId`s and how to keep that list up to date.
// We don't need `ON_PEER_UPDATE` event listener for keeping track of only `trackId`s.
// So, we have registered only `ON_TRACK_UPDATE` event listener here

const [trackIds, setTrackIds] = useState<string[]>([]);

const onTrackListener = (data: { peer: HMSPeer; track: HMSTrack; type: HMSTrackUpdate }) => {
  // We will only consider Video tracks for this example
  if (data.track.type !== HMSTrackType.VIDEO) return;

  // If Video track is added, add trackId to our list
  if (data.type === HMSTrackUpdate.TRACK_ADDED) setTrackIds(prevTrackIds => [...prevTrackIds, data.track.trackId]);

  // If Video track is removed, remove trackId from our list
  if (data.type === HMSTrackUpdate.TRACK_REMOVED) setTrackIds(prevTrackIds => prevTrackIds.filter(prevTrackId => prevTrackId !== data.track.trackId));
};

hmsInstance.addEventListener(
  HMSUpdateListenerActions.ON_TRACK_UPDATE,
  onTrackListener
);

// Render multiple HMSView for trackIds inside FlatList
// Note: HMSView will render blank if video track of peer is muted, Make sure video of peers is not muted.
<FlatList
  data={trackIds} // trackIds is an array of trackIds of video tracks
  keyExtractor={(trackId) => trackId}
  renderItem={({ item }) => <HMSView key={item} trackId={item} style={{ width: '100%', height: 300 }} {...} />}
  {...}
/>

More information about Rendering Videos is available here.

In the 100ms Example App we have shown how to set up the various listeners, what data to store in Redux and what all features you can implement.

We have also implemented multiple views which are commonly used. Checkout the videos & relevant code in the Example app.

๐Ÿ“– Read the Complete Documentation here: https://www.100ms.live/docs/react-native/v2/foundation/basics

100ms-react-native's People

Contributors

decoder07 avatar dependabot[bot] avatar govindmaheshwari2 avatar gzerad avatar lavi-moolchandani avatar moolchandani-lavi avatar samarthjain10 avatar shankulkarni avatar stanwolverine avatar ygit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

100ms-react-native's Issues

Create wrapper class for HMSRoom

@objcMembers public class HMSRoom : NSObject {

    public let id: String

    public let name: String

    public let metaData: String?

    public var peers: [HMSSDK.HMSPeer]
}

Implement Preview APIs

public func preview(config: HMSConfig, delegate: HMSPreviewListener)

@objc public protocol HMSPreviewListener: AnyObject {
    @objc(onPreview:localTracks:) func onPreview(room: HMSRoom, localTracks: [HMSTrack])
    @objc(onError:) func on(error: HMSError)
}

Create wrapper class for HMSConfig

@objcMembers public class HMSConfig : NSObject {

    /// the name that the user wants to be displayed while in the room
    public let userName: String

    public let userID: String

    public let roomID: String

    /// the auth token to be used
    public let authToken: String

    public let shouldSkipPIIEvents: Bool

    /// any json string or metadata that can be passed while joining
    public let metaData: String?

    /// to override the default endpoint (advanced)
    public let endpoint: String?

    public init(userName: String = "iOS User", userID: String, roomID: String, authToken: String, shouldSkipPIIEvents: Bool = false, metaData: String? = nil, endpoint: String? = nil)
}

Create wrapper class for HMSPeer

@objcMembers public class HMSPeer : NSObject {

    public let peerID: String

    public var name: String

    public let isLocal: Bool

    public var role: HMSSDK.HMSRole?

    public let customerUserID: String?

    public var customerDescription: String?

    public var audioTrack: HMSAudioTrack?

    public var videoTrack: HMSVideoTrack?

    public var auxiliaryTracks: [HMSTrack]?
}

React Native fixes needed

error Cannot find module 'metro-config/src/defaults/blacklist'

Fix
const blacklist = require('metro-config/src/defaults/exclusionList');

error: Error: Unable to resolve module ../screens/Home

Fix
Rename the /screens/home.js to Home.js

But still ended up continuous errors while trying to run the example project. Is there any working version available?

Sample app bugs - P3 priority

  • 1. Getting Join a meeting popup every time even after entering my name. Leave meeting and then try to re-join.
  • 2. No camera/mic icon on tile
  • 3. No iPad support
  • 4. No avatar for blank tiles
  • 5. No message notification
  • 6. Tiles are still scrollable.
  • 7. Leave button on right extreme

Implement Role Change APIs

In HMSSDK

    /// Requests a change of role for specified peer.
    /// - Parameters:
    ///   - peer: The peer whose role should be changed.
    ///   - role: The target role.
    ///   - force: False if the peer should be prompted to accept the new role. true if their role should be changed without a prompt.
    ///   - completion: The completion handler to be invoked when the request succeeds or fails with an error.
    public func changeRole(for peer: HMSPeer, to role: HMSRole, force: Bool = false, completion: ((Bool, HMSError?) -> Void)? = nil)

    /// Call to accept the role change request sent to the current peer.
    /// Once this method is called, the peer's role will be changed to the requested one.
    /// - Parameters:
    ///   - request The request that the SDK had sent to this peer (in HMSUpdateListener.onRoleChangeRequest).
    ///   - completion: The completion handler to be invoked when the request succeeds or fails with an error.
    public func accept(changeRole request: HMSRoleChangeRequest, completion: ((Bool, HMSError?) -> Void)? = nil)

    /// To change the mute status of a remote HMSTrack.
    /// - Parameters:
    ///   - remoteTrack: The HMSTrack whose mute status needs to be changed.
    ///   - mute: True if the track needs to be muted, false otherwise.
    ///   - completion: The completion handler to be invoked when the request succeeds or fails with an error.
    public func changeTrackState(for remoteTrack: HMSTrack, mute: Bool, completion: ((Bool, HMSError?) -> Void)? = nil)
In UpdateListener

    /// This is called when a role change request arrives
    /// - Parameter roleChangeRequest: the request for role change info
    @objc(roleChangeRequest:) optional func on(roleChangeRequest: HMSRoleChangeRequest)

    /// This is called when a change track state request arrives
    /// - Parameter changeTrackStateRequest: the request for changing track state
    @objc(changeTrackStateRequest:) optional func on(changeTrackStateRequest: HMSChangeTrackStateRequest)

Create wrapper class for HMSTrack

// HMSTrack

open class HMSTrack : NSObject {

    open var trackId: String { get }

    open var kind: HMSTrack! { get }

    open var source: Int32 { get }

    open var trackDescription: String { get }
    
    open func isMute() -> Bool
}

Create wrapper class for HMSRole

public struct HMSRole : Codable {

    public let name: String

    public let publishSettings: HMSPublishSettings

    public let subscribeSettings: HMSSubscribeSettings

    public let permissions: HMSPermissions

    public let priority: Int

    public let generalPermissions: [String : String]?

    public let internalPlugins: [String : String]?

    public let externalPlugins: [String : String]?
}

Implement HMSUpdateListener Callback Wrappers

The callbacks to be included are -

  1. func on(join room: HMSRoom)
  2. func on(room: HMSRoom, update: HMSRoomUpdate)
  3. func on(peer: HMSPeer, update: HMSPeerUpdate)
  4. func on(track: HMSTrack, update: HMSTrackUpdate, for peer: HMSPeer)
  5. func on(error: HMSError)
  6. func on(message: HMSMessage)
  7. func on(updated speakers: [HMSSpeaker])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.