Giter VIP home page Giter VIP logo

dolbyio / comms-sdk-react-native Goto Github PK

View Code? Open in Web Editor NEW
8.0 11.0 0.0 4.25 MB

Dolby.io Communications SDK for React Native

Home Page: https://www.npmjs.com/package/@dolbyio/comms-sdk-react-native

License: MIT License

Kotlin 29.16% Java 1.36% JavaScript 2.18% Shell 0.11% TypeScript 46.03% C 0.01% Objective-C 2.97% Swift 17.66% Ruby 0.52%
android dolbyio ios react-native sdk screen-sharing spatial-audio video-chat voice voice-chat webrtc

comms-sdk-react-native's Introduction

Dolby.io Communications SDK for React Native

This guide explains how to create a basic audio video conference application for mobile with React Native. It starts with importing the Dolby.io Communications SDK for React Native and guides you through the steps to launch a conference call.

Prerequisites

Make sure that you have:

  • A Dolby.io account
  • An iOS or Android device to run the application on, or the device emulator
  • React Native 0.66+ (including Expo projects)

For reference, see the GitHub sample repository.

Please review Supported Environments for more information on iOS and Android requirements.

Please see the documentation for a complete list of available services and methods.

Create a new project

1. Create a new React Native project:

npx react-native init DolbyIoGettingStarted

It will take a minute or two to download the template and install the different components needed for the project to run.

2. Once the project is created, go to the newly created folder:

cd DolbyIoGettingStarted

Installation

1. Install the Dolby.io Communications SDK for React Native using npm or yarn:

npm install @dolbyio/comms-sdk-react-native --save
yarn add @dolbyio/comms-sdk-react-native

2. Complete the installation:

For iOS, install native dependencies via CocoaPods:

pod install --repo-update --project-directory=ios/

For Android, add the following line to your android/build.gradle file, in the allprojects, repositories section:

maven { url("https://android-sdk.voxeet.com/release") }

and also add following lines to your android/app/build.gradle file:

packagingOptions {
    pickFirst '**/armeabi-v7a/libc++_shared.so'
    pickFirst '**/x86/libc++_shared.so'
    pickFirst '**/arm64-v8a/libc++_shared.so'
    pickFirst '**/x86_64/libc++_shared.so'
}

Getting started

Replace the content of your App.js with the following:

import React, { useEffect, useState } from 'react';
import {
    SafeAreaView,
    ScrollView,
    StatusBar,
    StyleSheet,
    Text,
    useColorScheme,
    View,
    Button,
    TextInput,
    Platform,
    PermissionsAndroid,
} from 'react-native';

import {
    Colors,
} from 'react-native/Libraries/NewAppScreen';


const Section = ({children, title}) => {
    const isDarkMode = useColorScheme() === 'dark';
    return (
        <View style={styles.sectionContainer}>
          <Text
              style={[
                  styles.sectionTitle,
                  {
                      color: isDarkMode ? Colors.white : Colors.black,
                  },
              ]}>
              {title}
          </Text>
          <Text
              style={[
                  styles.sectionDescription,
                  {
                      color: isDarkMode ? Colors.light : Colors.dark,
                  },
              ]}>
              {children}
          </Text>
        </View>
    );
};

const App = () => {
    const [conferenceAlias, setConferenceAlias] = useState("react-native");
    const [streamingUsers, setStreamingUsers] = useState([]);

    const joinConference = async () => {
    };

    const isDarkMode = useColorScheme() === 'dark';

    const backgroundStyle = {
        backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
    };

    return (
        <SafeAreaView style={backgroundStyle}>
            <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
            <ScrollView
                contentInsetAdjustmentBehavior="automatic"
                style={backgroundStyle}>
                <View
                    style={{
                        backgroundColor: isDarkMode ? Colors.black : Colors.white,
                    }}>
                    <Section title="Conference">
                        <Text>Alias:</Text>
                        <TextInput
                            style={styles.textInput}
                            onChangeText={setConferenceAlias}
                            value={conferenceAlias} />
                        <Button onPress={joinConference} title="Join the conference" />
                    </Section>

                    <Section title="Videos" style={{backgroundColor: 'black'}}>
                        {streamingUsers.map(({ participant, stream }) => (
                            <VideoView
                                key={`video-${participant.id}`}
                                style={{height: 200, width: 180, borderWidth: 1}}
                                ref={async element => {
                                    try {
                                        await element.attach(participant, stream);
                                    } catch (error) {
                                        console.error(error);
                                    }
                                }}
                            />
                        ))}
                    </Section>
                </View>
            </ScrollView>
        </SafeAreaView>
    );
};

const styles = StyleSheet.create({
    sectionContainer: {
        marginTop: 32,
        paddingHorizontal: 24,
    },
    sectionTitle: {
        fontSize: 24,
        fontWeight: '600',
    },
    sectionDescription: {
        marginTop: 8,
        fontSize: 18,
        fontWeight: '400',
    },
    textInput: {
        height: Platform.OS == 'android' ? 40 : 20,
        margin: 12,
        borderWidth: 1,
        padding: 10,
        lineHeight: 14,
    },
});

export default App;

Permissions

For iOS, establish privacy permissions by adding two new keys in Info.plist:

  • Privacy - Microphone Usage Description.
  • Privacy - Camera Usage Description.

For Android, the application must request permissions to access the microphone and camera. When the application component loads, we will request the permissions. In the const App = () => { }; add the following code:

const requestPermissions = async () => {
    try {
        const cameraGranted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.CAMERA,
            {
                title: "Camera Permission",
                message:"This App needs access to your camera",
                buttonNeutral: "Ask Me Later",
                buttonNegative: "Cancel",
                buttonPositive: "OK"
            }
        );

        if (cameraGranted === PermissionsAndroid.RESULTS.GRANTED) {
            console.log("You can use the camera");
        } else {
            console.log("Camera permission denied");
        }

        const micGranted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
            {
                title: "Microphone Permission",
                message: "This App needs access to your microphone so you can talk to people.",
                buttonNeutral: "Ask Me Later",
                buttonNegative: "Cancel",
                buttonPositive: "OK"
            }
        );

        if (micGranted === PermissionsAndroid.RESULTS.GRANTED) {
            console.log("You can use the microphone");
        } else {
            console.log("Camera permission denied");
        }
    } catch (error) {
        console.warn(error);
    }
};

useEffect(async () => {
    async function initialize() {
        if (Platform.OS === 'android') {
            // Request the permissions to access the camera and the microphone
            // required for Android only
            await requestPermissions();
        }

        // Initialization of the SDK...
    }

    initialize();
}, []);

Initialization

1. Import the SDK to the application by adding the following line at the top of the App.js file:

import CommsAPI, { VideoView } from '@dolbyio/comms-sdk-react-native';

2. Initialize the SDK with the Dolby.io credentials found in your dashboard. Replace the APP_KEY and the APP_SECRET with your application key and secret. Insert the following code after requesting the permissions for the microphone and camera (look for // Initialization of the SDK...):

// WARNING: It is best practice to use the initializeToken function to initialize the SDK.
// Please read the documentation at:
// https://docs.dolby.io/communications-apis/docs/rn-client-sdk-references-commsapi#initializetoken
await CommsAPI.initialize(APP_KEY, APP_SECRET);

3. Add the following code after the SDK initialization to automatically open a session after initializing the SDK. The session will open with a random user name.

const rand = Math.round(Math.random() * 10000);
await CommsAPI.session.open({ name: `user-${rand}` });

Create and join a conference

Locate the function joinConference in the code and replace it with the following to add a button to create and join a conference:

const joinConference = async () => {
    try {
        const conferenceOptions = {
            alias: conferenceAlias,
            params: {},
        };

        // Create the conference
        const conference = await CommsAPI.conference.create(conferenceOptions);
        console.log(`Conference ${conference.id} created`);

        const joinOptions = {
            constraints: {
                audio: true,
                video: true,
            }
        };

        // Join the conference with Audio and Video on
        await CommsAPI.conference.join(conference, joinOptions);
        console.log('Conference joined');
    } catch (error) {
        console.error(error);
    }
};

Integrate video

Use the onStreamsChange event handler provided by the conference object of the SDK to integrate video into your application. This event is triggered when a participant video stream changes, for example, a new video stream coming in or the video is stopped. Add the following code to create VideoView objects and insert them into the videoElements dictionary. The videoElements dictionary is used to generate the UI within the function getVideoElements.

1. Add the following import statement at the top of your document:

import { VideoView } from '@dolbyio/comms-sdk-react-native';

2. Insert the following code in your App component:

useEffect(() => {
    const unsubscribe = CommsAPI.conference.onStreamsChange((data, type) => {
        if (type === 'EVENT_CONFERENCE_STREAM_REMOVED') {
            // Remove the users without a video stream
            setStreamingUsers(usr => usr.filter(d => d.participant.id !== data.participant.id));
            return;
        }

        if (
            !streamingUsers
            .map(d => d.participant.id)
            .includes(data.participant.id) &&
            data?.stream?.videoTracks?.length > 0
        ) {
            setStreamingUsers(sp => [...sp, data]);
        }
    });

    return () => unsubscribe();
}, []);

Run the application

On iOS, run the application:

npx react-native run-ios

On Android, run the application:

npx react-native run-android

SDK License agreement

The Dolby.io Communications SDK for React Native and its repository are licensed under the MiT License.

Before using the latest version of the @dolbyio/comms-sdk-react-native, please review and accept the Dolby Software License Agreement.

Third Party licenses

Direct licenses can be found here

© Dolby, 2021

comms-sdk-react-native's People

Contributors

aamq avatar arkadiuszkrykm avatar codlab avatar dependabot[bot] avatar dzfill avatar fabienlavocat avatar graduad avatar gruszczakmq avatar kbetl-dlb avatar kdrob-dolby avatar krzysztof-drobek avatar mateuszglapiak avatar mateuszglapiak-dolby avatar mgruszczakmq avatar mhelf-dolby avatar michalgruszczak avatar mpozy avatar msobo1 avatar pczaj avatar ppolus-dolby avatar ppolus-miquido avatar romansavka-mq avatar vincentsong avatar yganu avatar yuriymiquido avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

comms-sdk-react-native's Issues

Unable to use @dolbyio/comms-sdk-react-native, @millicast/sdk and react-native-webrtc together

I am using the following packages in an Expo managed project:

  • "@dolbyio/comms-sdk-react-native": "^3.7.0-beta.1",
  • "@millicast/sdk": "^0.1.35",
  • "react-native-webrtc": "^106.0.0-beta.7",,

When trying to create an expo - EAS build I get a lot of Duplicate class errors:
image

I need to use both SDK's in my app, is this supported? If yes, what tweaks to the native code do I need to make to get this working?

Callback for recording in React Native SDK

There are events to listen to in order to get the recording status like RecordingStatusUpdatedEvent on android and similar on other platforms. But React Native SDK doesn't provide a similar callback. Having this callback will enable the developer to show the recording status to the participants.

Some streams have blank IDs

Some Stream Removed events have a blank ID which means we don't know which Stream to remove from the app.

Object is not a function error when trying to call any UnsubscribeFunction

I'm trying to integrate this SDK but am running into an issue when trying to unsubscribe from an event handler.
When I navigate to one of my screens I can successfully view the incoming video. However when going to the previous screen I get an error when calling the UnsubscribeFunction. This results in the event handler functions not being disposed which means if you keep going back and forth between screens you will have multiple event handlers active while there should only be one.

I can consistenly reproduce this with the following code, you don't need to have called any other Dolby function:

useEffect(() => {
    logger.debug("~~~~~~~~ subscribing to onStreamsChange");
    const unsubscribe = CommsAPI.conference.onStreamsChange((data, type) => {
      logger.debug("~~~~~~~~ onStreamsChange", type);
    });

    return () => {
      logger.debug("~~~~~~~~ unsubscribing from onStreamsChange");
      try {
        unsubscribe();
        logger.debug("~~~~~~~~ unsubscribing from onStreamsChange");
      } catch (e) {
        logger.error("~~~~~~~~ error unsubscribing", e);
      }
    };
  }, []);

Note: it happens for any onX handler, not just onStreamsChange

Logs after toggling between screens a few times:
image

Full logs for completeness sake:
image

Incorrect values in ParticipantType enum

The values in the ParticipantType enum seem to be incorrect.
When I log (await CommsAPI.conference.current()).participants whilst in a conference. I get back the following data:
image

The enum indicates it is "user" while it should be "USER". I have not verified this but I think this might be the case for some of the other enums as well.

export enum ParticipantType {
/** A participant who cannot send any audio or video stream during a conference. */
LISTENER = 'listener',
/** A participant who can send and receive audio and video during the conference. */
USER = 'user',

It's also possible to receive the type "UNKNOWN" which should be added to the enum.
image

When joining a conference as a listener while a screenshare is ongoing an error is thrown

whilst testing #156 I found another issue with the screenshare.

When you join a call as a listener while the call is ongoing and screenshare is on we encountered this error:

Error: Unable set remote SDP for Peer: 70198506-3b32-3efe-aa9b-f80b54200574 :: Failed to set remote offer sdp: Failed to set remote video description send parameters for m-section with mid='screenshare'.
Error: Unable set remote SDP for Peer: 70198506-3b32-3efe-aa9b-f80b54200574 :: Failed to set remote offer sdp: Failed to set remote video description send parameters for m-section with mid='screenshare'.

A couple of conferences where we reproduced this issue:

ID: 259844d3-2271-40de-9435-fcb5afc801b9
Alias: Stage|9fcbfcfa-2933-4010-87dd-04d4609f5970|6410ec1e-aab8-43d7-b16d-920df262c161

ID: 4833935a-e938-4ec8-b037-6600caf1461c
Alias: Stage|9fcbfcfa-2933-4010-87dd-04d4609f5970|43729424-51cd-4feb-a023-9419669fc56f

Update to 3.8 native SDKs

Update the Dolby.io React Native SDK to use the 3.8 native SDKs.

Tasks:

  • Update the Android part of Dolby.io React Native SDK
  • Update the iOS part of Dolby.io React Native SDK

Unable to view network requests in the debugger.

Network requests do not show up in flipper which makes it difficult to debug issues. I believe this is due to this SDK calling the android/ios specific SDKs to make network requests.

Is there any way to view these requests and responses without going into android/ios specific tooling?

Missing AvatarUrl on Active Participant Event

Active Participant Event is missing avatarUrl after setting it with SessionService.updateParticipantInfo.

On Participant object returned by Active Participant Event we get an info object which is missing avatarUrl but we can see the set url in other events.

From our testing it looks like it's not included in a response from the backend.
It's possible to reproduce on iOS and Android.

Multiple stream events received when changing camera

It has been noticed that when a participant is sharing video from their camera, but then changes to a different video device, several events are being received, with one of the intermediate events containing no video streams. This means that there is a short gap between the old and new video streams.

Unable to import any enum type

When trying to import any enum you get the following error:
image

This happens for every enum defined in a .d.ts file that you try to import.

pods installation issue in react native ios

[!] CocoaPods could not find compatible versions for pod "VoxeetSDK":
In Podfile:
react-native-comms-sdk (from ../comms-sdk-react-native-latest) was resolved to 3.8.0-beta.1, which depends on
VoxeetSDK (~> 3.8.0)

Specs satisfying the VoxeetSDK (~> 3.8.0) dependency were found, but they required a higher minimum deployment target.

participitant added and left notifications are missing

When we add a new listener how we can check or know the new user is came?? so please tell me the way because these two type of notifications are not available in react native if these are available then we can identify using these notifications

CommsAPI.session.isOpen returns the wrong type

isOpen returns a Boolean instead of a boolean, the primitive type should always be returned as otherwise you need to call valueOf to unwrap the actual value. This was probably a typo as this seems to be the only instance where Boolean is used instead of boolean.

Current code:

const isOpen = await CommsAPI.session.isOpen();
if (isOpen.valueOf()) {}

Expected code:

const isOpen = await CommsAPI.session.isOpen();
if (isOpen) {}

public async isOpen(): Promise<Boolean> {
return this._nativeModule.isOpen();
}

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.