This project is in BETA and does not provide full API-parity from the Mobile SDKs, at the moment.
React Native Component with Multiple Streams.
Note: The
R5VideoView
React Native Component/Module library may be more beneficial to your project requirements: https://github.com/infrared5/react-native-red5pro
You will need a Red5 Pro SDK License and a Red5 Pro Server in order to use this component.
Sign up for a free trial!
The R5MultiStreamView
React Native Component provides a single component to assign multiple stream instances (both broadcaster and consumer(s)) through.
This project started as a Proof of Concept (POC) to demonstrate the ability to have multiple desperate broadcasters each playing back a single stream with Video+Audio and multiple streams with just Audio.
The goals of the R5MultiStreamView
Component are:
- To provide a single component on which to broadcast and consume multiple streams.
- Control layout and size of each stream within the native component.
This library differs from the react-native-red5pro
React Native Component/Module project (found at https://github.com/infrared5/react-native-red5pro) with regards to its design and intent.
The goals of the react-native-red5pro
project are:
- As Component: Provide a way to define a single UI view for each stream (broadcaster and consumer).
- As Module: Provide a way to decouple the underlying stream from the UI view to maintain open and active streams during re-rendering.
Find out more at https://github.com/infrared5/react-native-red5pro.
Install the react-native-red5pro-multistream
component:
$ npm i --save https://github.com/infrared5/react-native-red5pro-multistream/tarball/master
If you intend to use the live broadcasting capabilities of the Red5 Pro SDK, install the react-native-permissions
module that will present to the user the permissions dialogs for Camera and Microphone:
$ npm i --save react-native-permissions
More information about react-native-permissions
Finally, run the following to link the libraries into your projects:
$ react-native link
After running react-native link
, the react-native-red5pro-multistream
library - and optionally the react-native-permissions
library - will be added to the Libraries of your iOS project:
If the libraries were not added using react-native link
, you can drag them in manually. For the react-native-red5pro-multistream
library:
- Open a file browser and navigate to the react-native-red5pro-multistream install in node_modules.
- Within the node_modules/react-native-red5pro-multistream directory, locate the
R5MultiStreamView.xcodeproj
under ios/R5MultiStreamView. - Drag the
R5MultiStreamView.xcodeproj
file into your Xcode project and under theLibraries
Group.
The react-native-red5pro-multistream
library should now be installed and available.
Follow similar instructions for react-native-permissions
, if needed.
Review the iOS Example included in this repository.
Add the following to your Podfile:
pod 'ReactNativePermissions', :path => '../node_modules/react-native-permissions'
pod 'R5MultiStreamView', :path => '../node_modules/react-native-red5pro-multistream'
Then issue a pod install as you would with any other project:
$ pod install
$ react-native link
After running react-native link
, the react-native-red5pro-multistream
library will be added your Android project:
If the react-native-red5pro-multistream
library was not added using react-naive link
, you can add them manually for Android by doing the follow in your project:
- Locate and open the
settings.gradle
for your Android app. - Add
:react-native-red5pro-multistream
to theinclude
and define the library project location:
rootProject.name = 'Red5ProMultiStreamViewExample'
include ':app',
':react-native-red5pro-multistream'
project(':react-native-red5pro-multistream').projectDir = new File(rootProject.projectDir, '../../android')
Now locate the build.gradle
for your Android app, and add the following to the dependencies
:
compile project(':react-native-red5pro-multistream')
Review the Android Example included in this repository.
It is assumed that you have used the create-react-native CLI tool to bootstrap your projects. If you have used other means to set up your projects, some instructions may be different.
In addition to adding the react-native-red5pro-multistream
library - and optionally react-native-permissions
library - as described above, there are additional project settings required, including the addition of the Red5 Pro Mobile SDK.
This section will describe how to setup your projects to integrate the Red5 Pro Mobile SDK so you can use the react-native-red5pro-multistream
library to display a video view for broadcasting and subscribing to a live stream.
You will need a Red5 Pro SDK License and a Red5 Pro Server in order to use this component. Sign up for a free trial!
After linking in the react-native-red5pro-multistream
library as described in the previous section, you will need to install the Red5 Pro iOS SDK and update the permissions for you project.
To integrate the Red5 Pro iOS SDK:
- Download the latest Red5 Pro iOS SDK from your account. If you don't have an account yet, Sing up for a free trial!.
- Unpack the Red5 Pro iOS SDK into a location on your local machine - there will be a
R5Streaming.framework
file. This is the Red5 Pro iOS SDK. - Within your Xcode project panel, determine if you already have a
Frameworks
Group available for your project. If not, follow to step #4; if you have one, follow to step #5. - Right-Click on the top-level project, select
New Group
and when it is generated for the project, click onNew Group
to make it editable and name ifFrameworks
. - Drag the
R5Streaming.framework
file from a file browser into the Xcode project and under theFrameworks
Group. - In the following dialog, select to
Copy items...
and ensure that your project is selected to add it to. - Click
Finish
.
The R5Streaming.framework
should now be located within the Frameworks
Group of your project. Select it and make note of its location (Full Path) in the Identities Panel of your Xcode project.
The react-native-red5pro-multistream
library is not shipped with the Red5 Pro SDK. As such, we need to point the react-native-red5pro-multistream
library point to the R5Streaming.framework
dependency:
- Locate the
R5VideoView.xcodeproj
under theLibraries
Group of the Project Panel of Xcode. - Select the Target
R5VideoView
, and clickBuild Settings
. - Search for "frameworks" (sans quotes), and navigate to the
Framework Search Paths
. - Click on the Value field and add the path to the
R5Streaming.framework
file (either relative or full path).
- Locate the
Pods
project in your generatedxcworkspace
and select to open the project settings in Xcode. - Click on
Build Settings
- Search for "frameworks" (sans quotes), and navigate to the
Framework Search Paths
. - Click on the Value field and add the path to the
R5Streaming.framework
file (either relative or full path).
The Red5 Pro iOS SDK requires a few additional dependencies in order to properly broadcast and consume live streams. Add the following libraries and frameworks to your project under the General > Linked Frameworks and Libraries panel:
libc++.1.tbd
libiconv.2.4.0.tbd
libbz2.1.0.tbd
libz.tbd
GLKit
QuartzCore
OpenAL
CoreFoundation
VideoToolbox
If you intend to use the react-native-red5pro-multistream
to broadcast live streams, you will need to add Privacy permissions for Camera and Microphone access on the device. To do so:
- Locate the
Info.plist
file for your project in Xcode. - Click to Add an entry (using the
+
icon), and add aPrivacy - Camera Usage Description
entry. - Provide a String Value of the message you want to present to your User(s) - e.g.,
Camera access required for publishing.
- Add a similar entry and String value for
Privacy - Microphone Usage Description
.
Your app should now be available for broadcasting and subscribing to live streams!
- You may bew required to set the
Enable Bitcode
Build Setting to a value ofNo
in order to use the SDK.
After linking in the react-native-red5pro-multistream
library as described in the previous section, you will need to install the Red5 Pro Android SDK and update the permissions for you project.
To integrate the Red5 Pro Android SDK:
- Download the latest Red5 Pro Android SDK from your account. If you don't have an account yet, Sing up for a free trial!.
- Unpack the Red5 Pro Android SDK into a location on your local machine - there will be a
red5streaming.jar
file and a folder labelledjniLibs
. This is the Red5 Pro Android SDK. - Drag the
red5streaming.jar
file into the app/libs folder of your Android app project in Android Studio. - Drag the
jniLibs
holder under the app/src/main folder of your Android app project in Android Studio.
The react-native-red5pro-multistream
library is not shipped with the Red5 Pro SDK. As such, we need to point the react-native-red5pro-multistream
library point to the red5streaming.jar
dependency:
- Expand the
react-native-red5pro-multistream
library in the Project Panel of Android Studio. - Locate the
build.gradle
file and open it in the editor. - Add the path to the
red5streaming.jar
as a dependency. e.g.,
dependencies {
provided "com.facebook.react:react-native:${_reactNativeVersion}"
compile files("../example/android/app/libs/red5streaming.jar")
}
Now that the Red5 Pro Android SDK is a dependency for the react-native-red5pro-multistream
library and is referenced from the parent project, we need to make sure we exclude it from being compiled in twice:
- Locate the
build.gradle
for your Android app and open it in the editor. - Define the
red5sreaming.jar
as an exclusion for the libs dependencies.
The dependencies
definition in the build.gradle
of the app should look similar to the following:
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"], excludes: ["red5streaming.jar"])
compile "com.android.support:appcompat-v7:27.1.1"
compile "com.facebook.react:react-native:+" // From node_modules
compile project(':react-native-red5pro-multistream')
}
- Open you main
ReactApplication
implementation file. - Within the
getPackages()
override, add a new instance ofR5MultiStreamPackage
to the list, e.g.,:
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new R5MultiStreamPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "index.android";
}
};
If you intend to use the react-native-red5pro-multistream
to broadcast live streams, you will need to add Privacy permissions for Camera and Microphone access on the device. To do so:
- Open the
AndroidManifest.xml
file and add the following to theuses-permissions
:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- With the
AndroidManifest.xml
still open, under theuses-permissions
, add the followinguses-feature
s:
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
Your app should now be available for broadcasting and subscribing to live streams!
The following describe the API available for the react-native-red5pro-multistream
Native Component library, R5MultiStreamView
.
Key | Type | Default | Description | Publisher | Subscriber |
---|---|---|---|---|---|
showDebugView | boolean | false | Displays the debug information for a broadcast and playback stream. | x | x |
logLevel | int | 3 | Enumerated value of R5LogLevel. | x | x |
bitrate | int | 750 | The video bitrate to broadcast at. | x | |
framerate | int | 15 | The video framerate to broadcast at. | x | |
useAdaptiveBitrateController | boolean | false | Use of adaptive bitrate streaming for broadcasting. | x | |
licenseKey | string | REQUIRED |
The SDK license key provided with your registered Red5 Pro account. | ||
bundleID | string | REQUIRED |
A unique (typically inversed domain name) descriptor for you app. Required for some stores. | ||
bufferTime | number | 0.5 | Default buffer. | ||
streamBufferTime | number | 4 | Default buffer for subscribers to allow on the server in sending packets. |
The component methods are driven using a node handle ref and the associated streamName
you want to manipulate using the method.
As an example:
- You have established a broadcast session using the
publish
method and provided a uniquestreamName
. - At a later point you want to swap the camera being used to the backfacing camera.
- You invoke the
swapCamera
method using the uniquestreamName
associated with the broadcast session.
The following methods are available:
import {
subscribe,
unsubscribe,
publish,
unpublish,
swapCamera,
updateScaleSize,
sendToBackground,
returnToForeground,
setPermissionsFlag,
shutdown
} from 'react-native-red5pro-multistream'
Name | Arguments | Description | Publisher | Subscriber |
---|---|---|---|---|
subscribe | <ref> , streamName , host address , context , withVideo , audioMode |
Request to start subscribing to stream. | x | |
unsubscribe | <ref> , streamName |
Request to stop playback of stream. | x | |
publish | <ref> , streamName , host address , context , withVideo , cameraWidth , cameraHeight , streamType |
Request to start broadcasting stream with unique name and type (0: live , 1: record , 2 : append). |
x | |
unpublish | <ref> , streamName |
Request to stop broadcast. | x | |
swapCamera | <ref> , streamName |
Request to swap camera on device, from front-facing to back-facing and vice-versa. | x | |
updateScaleSize | <ref> , streamName , width , height , screenWidth , screenHeight |
Request to change publish or playback view and layout scale based on screen size. | x | x |
sendToBackground | <ref> , streamName |
Request to detach associated subscriber stream from the view. | x | |
returnToForeground | <ref> , streamName |
Request to re-attach associated subscriber stream to the view. | x | |
setPermissionsFlag | <ref> , flag |
Define the user acceptance of permissions. | - | - |
shutdown | <ref> |
Request to stop each opened stream session. | - | - |
The following callbacks are available:
Name | Event Object | Description | Publisher | Subscriber |
---|---|---|---|---|
onConfigured | {streamName , key : <configuration.key provided> } |
Notification of configuration being completed. | x | x |
onMetaData | {streamName , metadata : <server provided info about stream> } |
Notification of stream metadata. | x | |
onPublisherStreamStatus | {streamName , status : refer to status section} |
Notification of stream status for a Publisher. | x | |
onSubscriberStreamStatus | {streamName , status : refer to status section} |
Notification of stream status for a Subscriber. | x | |
onUnsubscribeNotification | none | Notification of stop of playback. | x | |
onUnpublishNotification | none | Notification of stop of broadcast. | x |
The Publishers and Subscribers receive status events during the lifecycle of broadcasting and consuming a stream, respectively. The following properties are available in the status object:
Key | Description |
---|---|
code | The enumerated code of the event. |
name | The associated name of the event. |
message | The human readable, optional, message associated with the event. |
streamName | The associated stream. |
- The enumerated list of statuses on iOS https://www.red5pro.com/docs/static/ios-streaming/protocol_r5_stream_delegate-p.html
- The enumerated list of statuses on Android https://www.red5pro.com/docs/static/android-streaming/enumcom_1_1red5pro_1_1streaming_1_1event_1_1_r5_connection_event.html
You will need to have a Red5 Pro SDK license and access to a deployed Red5 Pro Server in order to use the following example.
import React from 'react'
import { findNodeHandle, View, Button, StyleSheet } from 'react-native'
import { R5MultiStreamView } from 'react-native-red5pro-multistream'
import { R5LogLevel, R5PublishType } from 'react-native-red5pro-multistream'
import { publish,
unpublish,
swapCamera } from 'react-native-red5pro-multistream'
export default class App extends React.Component {
constructor (props) {
super(props)
this.state = {
publisher: {
configuration: {
streamName: 'publisher-stream',
host: 'your.red5pro.deploy', // IP or Fully Qualified Domain Name
context: 'live',
withVideo: true,
cameraWidth: 640,
cameraHeight: 360,
streamType: R5PublishType.LIVE
}
}
bundleID: 'com.red5pro.example',
licenseKey: 'YOUR-LICENSE-KEY',
showDebugView: true,
logLevel: R5LogLevel.DEBUG,
onConfigured: this.onConfigured.bind(this)
onPublisherStreamStatus: this.onPublisherStreamStatus.bind(this),
onUnpublishNotification: this.onUnpublishNotification.bind(this)
}
this.onStop = this.onStop.bind(this)
this.onSwapCamera = this.onSwapCamera.bind(this)
}
render () {
const assignVideoRef = (video) => { this.red5pro_multistream = video }
return (
<View style={styles.container}>
<R5MultiStreamView ref={assignVideoRef} {...this.state} style={styles.video} />
<Button
style={styles.button}
onPress={this.onStop}
title='Stop'
accessibilityLabel='Stop'
/>
<Button
style={styles.button}
onPress={this.onSwapCamera}
title='Swap Camera'
accessibilityLabel='Swap Camera'
/>
</View>
)
}
componentDidMount () {
const {
publisher: {
configuration: {
streamName,
host,
context,
withVideo,
cameraWidth,
cameraHeight,
streamType
}
}
} = this.state
publish(findNodeHandle(this.refs.red5pro_multistream), streamName, host, context, withVideo, cameraWidth, cameraHeight, streamType)
}
onStop () {
const {
publisher: {
configuration: {
streamName
}
}
} = this.state
unpublish(findNodeHandle(this.refs.red5pro_multistream), streamName)
}
onSwapCamera () {
const {
publisher: {
configuration: {
streamName
}
}
} = this.state
swapCamera(findNodeHandle(this.refs.red5pro_multistream), streamName)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center'
},
video: {
flex: 1,
flexDirection: 'row',
justifyContext: 'center',
backgroundColor: 'black'
},
button: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
height: 40,
backgroundColor: 'blue',
color: 'white'
}
})
You will need to have a Red5 Pro SDK license and access to a deployed Red5 Pro Server in order to use the following example.
import React from 'react'
import { findNodeHandle, View, Button, StyleSheet } from 'react-native'
import { R5MultiStreamView } from 'react-native-red5pro-multistream'
import { R5LogLevel, R5ScaleMode } from 'react-native-red5pro-multistream'
import { subscribe,
unsubscribe } from 'react-native-red5pro'
export default class App extends React.Component {
constructor (props) {
super(props)
this.state = {
subscriber: {
configuration: {
streamName: 'publisher-stream',
host: 'your.red5pro.deploy', // IP or Fully Qualified Domain Name
context: 'live',
withVideo: false
},
bundleID: 'com.red5pro.example',
licenseKey: 'YOUR-LICENSE-KEY',
showDebugView: true,
logLevel: R5LogLevel.DEBUG,
scaleMode: R5ScaleMode.SCALE_TO_FILL,
onConfigured: this.onConfigured.bind(this)
}
}
this.onStop = this.onStop.bind(this)
}
render () {
const assignVideoRef = (video) => { this.red5pro_multistream = video }
return (
<View style={styles.container}>
<R5MultiStreamView ref={assignVideoRef} {...this.state} style={styles.video} />
<Button
style={styles.button}
onPress={this.onStop}
title='Stop'
accessibilityLabel='Stop'
/>
</View>
)
}
componentDidMount () {
const {
subscriber: {
configuration: {
streamName,
host,
context,
withVideo
}
}
} = this.state
subscribe(findNodeHandle(this.refs.red5pro_multistream), streamName, host, context, widthVideo)
}
onStop () {
subscriber: {
configuration: {
streamName
}
}
} = this.state
unsubscribe(findNodeHandle(this.refs.red5pro_multistream), streamName)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center'
},
video: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
backgroundColor: 'black'
},
button: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
height: 40,
backgroundColor: 'blue',
color: 'white'
}
})
For more in-depth examples, please refer to the examples included in this repository.