DEV Community

Cover image for WebRTC and React-Native
José Muñoz
José Muñoz

Posted on

WebRTC and React-Native

It is a strange time to be a developer, with most countries going into lock-down, the need for communication technologies has sparked.

One of the technologies that has been readily available for web developers to create this solutions is the WebRTC API which web browsers have implemented almost across the board. The next step for these kind of technologies is to make a jump to mobile, either with PWA or a Native application. The former could be considered already viable but the features that the public expects with video apps has only become more and more complex.

For React-Native Developers the WebRTC solutions have historically had a high barrier of entry. Expo has not yet (as of May 2020) integrated the react-native-webrtc native module into their framework despite having demand for it. Of course it is not Expo's responsibility to implement the things that we claim for, that is not how open source works.

If you want to have WebRTC on your React-Native project you must go with the official npx react-native CLI.

The Setup

react-native-webrtc's documentation has been neglected by the community, as it is one of the least favourite parts of a developer's tasks, but an essential task nonetheless. You can follow the installation guides for both Android and iOS but in this post I will try to guide you through a much much simpler process that is made possible thanks to the auto-linking features that came with react-native@0.60

Starting From Scratch

My purpose here is to lower the entrance barrier for people to explore WebRTC technologies, for this reason I will approach this from the perspective of a greenfield project, the typical npx react-native init myApp will do.

Once you have a boilerplate project we need add react-native-webrtc as a dependency:

npm install --save react-native-webrtc
Enter fullscreen mode Exit fullscreen mode

From here on our next step is going to be to integrate react-native-webrtc with each platform.

The high-level overview of this setup is:

  • glue the native module to each platform
  • ask for the necessary permissions

I highly recommend you use a physical device to debug.

iOS

The iOS integration is the simplest one because cocoapods will do most of the legwork.

On the project's root, locate the podfile under ./ios/podfile, the first line is where we set the platform version, we will change this to version 10:

platform :ios, '10.0'

On the podfile, locate your project's target pods and add the following line:

pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'

Once you've made these changes save everything and open a terminal on your project's root and run npx pod-install

Now that you've completed the first step, it's time to ask (nicely) for some permissions, locate the info.plist file under ./ios/myApp and add the following lines after the first <dict>:

<key>NSCameraUsageDescription</key>
<string>Camera Permission</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone Permission</string>
Enter fullscreen mode Exit fullscreen mode

And that completes the iOS setup portion, easy right? If you only care about the iOS platform then all you need to do now is to run the project on an iPhone.

Android

The setup process for Android is inherently more complex but we will try to keep it as simple as possible.

On the project's root locate graddle settings under ./android/settings.graddle and replace the last line with the following:

include ':WebRTCModule', ':app'
project(':WebRTCModule').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
Enter fullscreen mode Exit fullscreen mode

In the ideal world we would add permissions and be done with it, but bear with me

Locate the project's graddle properties under ./android/graddle.properties and add the following line:

android.enableDexingArtifactTransform.desugaring=false

Locate Android's build properties under ./android/build.graddle and look for the buildscript dependencies, make sure the tooling is on version 3.5.2:

classpath("com.android.tools.build:gradle:3.5.2")

On different build properties located under ./android/app/build.graddle locate the dependencies and add the following line within its scope:

compile project(':WebRTCModule')

Go into the project's Android MainApplication.java located at ./android/app/src/java/com/all/the/things/ and add the namespace for react-native-webrtc by adding the following import:

import com.oney.WebRTCModule.WebRTCModulePackage; 
Enter fullscreen mode Exit fullscreen mode

Finally we can ask (nicely) for permissions, locate the project's AndroidManifest.xml under ./android/app/src/main and add the permissions on the same scope as the <application> tag with the following lines:

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_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.WAKE_LOCK" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.CAMERA" />
 <uses-feature android:name="android.hardware.camera" />
 <uses-feature android:name="android.hardware.camera.autofocus"/>
Enter fullscreen mode Exit fullscreen mode

Once this is in place we are ready to run the project on a device for testing.

Conclusion

react-native-webrtc's installation guides while not completely up-to-date, they have valuable information that is still useful for some people. I've made a template application that has been setup for WebRTC broadcasting and includes a simple socket implementation of a signaling server (required to start the Peer Connections), The sample itself is written using hooks and its linked below:

GitHub logo jdmg94 / react-native-webrtc-example

An example app for `react-native-webrtc` using React 0.60 or newer

What do you think about video broadcasting technologies? What other uses could Real Time Communication technologies be applied to? Have you baked bread during this quarantine yet? Thanks for reading!

Top comments (10)

Collapse
 
klever34 profile image
Lanre Adedara

Hi, I keep getting this error =>
[!] CocoaPods could not find compatible versions for pod "react-native-webrtc":
In Podfile:
react-native-webrtc (from ../node_modules/react-native-webrtc)

Specs satisfying the react-native-webrtc (from../node_modules/react-native-webrtc) dependency were found, but they required a higher minimum deployment target.

Collapse
 
josemunoz profile image
José Muñoz

Hi Lanre,

Please make sure the podfile is on version 10, replace the first line with:

platform :ios, '10.0'

And give it another try

Collapse
 
klever34 profile image
Lanre Adedara

Thanks for your reply.
I just created this project and added some plugins too. This is what my podfile contains =>

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '10.0'

target 'oncopadi' do
config = use_native_modules!

use_react_native!(:path => config["reactNativePath"])
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
pod 'BVLinearGradient', :path => '../node_modules/react-native-linear-gradient'
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
target 'oncopadiTests' do
inherit! :complete
# Pods for testing
end

# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable these next few lines.
use_flipper!
post_install do |installer|
flipper_post_install(installer)
end
end

target 'oncopadi-tvOS' do
# Pods for oncopadi-tvOS

target 'oncopadi-tvOSTests' do
inherit! :search_paths
# Pods for testing
end
end

Collapse
 
vilmes21 profile image
VM

ios 10 no longer works. Minimum must be ios 11.0. According to: github.com/react-native-webrtc/rea...

Thread Thread
 
josemunoz profile image
José Muñoz

thanks I'll try to update the repo over the weekend!

Collapse
 
klever34 profile image
Lanre Adedara

Hi José, still facing this issue. Any help?

npx: installed 1 in 4.316s
Scanning for pods...
1.9.3

pod install
Analyzing dependencies
[!] CocoaPods could not find compatible versions for pod "react-native-webrtc":
In Podfile:
react-native-webrtc (from ../node_modules/react-native-webrtc)

Specs satisfying the react-native-webrtc (from../node_modules/react-native-webrtc) dependency were found, but they required a higher minimum deployment target.

Aborting run
An unexpected error was encountered. Please report it as a bug:
Error
at CocoaPodsPackageManager._installAsync (/Users/user/.npm/_npx/24037/lib/node_modules/pod-install/build/index.js:2:76001)
at process._tickCallback (internal/process/next_tick.js:68:7)

Collapse
 
vilmes21 profile image
VM

Thanks for the nice blog! When the signalling server is running on my computer during development, how do I test my React Native webRTC app? Simulator camera won't work. So do I have to use 2 cables to connect 2 real phones?

Collapse
 
josemunoz profile image
José Muñoz

you can test with a single physical device but that has to be the host so you can use the physical camera, the viewer can be a simulator as long as they are both reachable on the same network

Collapse
 
k3beros profile image
K3beros

Awesome article Jose. Helped giving me headway in a blocker I had regarding disabling audio in the localstream.

Collapse
 
thangle18 profile image
ThangLe18

I run app success but it just display video by my camera
how can i call between 2 device