Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(WEBRTC): Video Calling with React Native support #15

Merged
merged 1 commit into from May 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 6 additions & 4 deletions LICENSE
@@ -1,3 +1,5 @@
MIT License

Copyright (C) 2005-2017 Anthony Minessale II
Copyright (C) 2018 Seven Du <dujinfang@x-y-t.cn>
Copyright (C) 2018 Xueyun Jiang <jiangxueyun@x-y-t.cn>
Expand All @@ -10,13 +12,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
136 changes: 95 additions & 41 deletions README.md
@@ -1,12 +1,18 @@
# Telnyx WebRTC SDK

## Version v1

To access v1 click [here](https://github.com/team-telnyx/webrtc/tree/v1.0.9)

## Version v2

![npm (scoped)](https://img.shields.io/npm/v/@telnyx/webrtc) <!-- GEN:chromium-version-badge-if-release -->[![Chromium version](https://img.shields.io/badge/chromium-82.0.4057.0-blue.svg?logo=google-chrome)](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge-if-release -->[![Firefox version](https://img.shields.io/badge/firefox-72-blue.svg?logo=mozilla-firefox)](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> [![WebKit version](https://img.shields.io/badge/webkit-13.0.4-blue.svg?logo=safari)](https://webkit.org/) [![Join Slack](https://img.shields.io/badge/join-slack-infomational)](https://joinslack.telnyx.com/)

The Telnyx WebRTC SDK provides all the functionality you need to start making voice calls from a browser to phone numbers or other browsers.

## Requirements

You'll need node 8.6.0 or later.
You'll need node v12.16.1 or later.

You'll also need a Telnyx account in order to authenticate your application. Follow our [quick start guide](https://developers.telnyx.com/docs/v2/sip-trunking/quickstarts/portal-setup) to create a **Connection** with **Credentials Authentication** -- it's simple and quick to get set up with secure credentials that are automatically generated for you.

Expand Down Expand Up @@ -34,56 +40,59 @@ To initialize the JavaScript SDK, you'll need to authenticate using a Telnyx Con
// Initialize the client
const client = new TelnyxRTC({
// Required credentials
credentials: {
// Telnyx Connection Username
username: 'username',
// Telnyx Connection Password
password: 'password',
},
login: username,
password: password,
// Other options
//
// This can be a DOM element, DOM selector, or a function that returns an element.
remoteElement: '#videoOrAudioSelector',
// This file can be a wav/mp3 in your local public folder or you can host it in a CDN and pass just the URL, such as https://cdn.company.com/sounds/call.mp3
ringFile: './sounds/incoming_call.mp3',
useMic: true,
useSpeaker: true,
useCamera: false,
});

// Create a variable to track the current call
let activeCall;

// Attach event listeners
client
.on('socket.connect', () => console.log('socket connected'))
.on('socket.close', () => console.log('socket closed'))
.on('registered', () => console.log('registered'))
.on('unregistered', () => console.log('unregistered'))
.on('telnyx.socket.open', () => console.log('socket open'))
.on('telnyx.socket.close', () => {
console.log('socket closed');
client.disconnect();
})
.on('telnyx.socket.error', (error) => {
console.log('telnyx.socket.error', error);
client.disconnect();
})
.on('telnyx.ready', () => console.log('ready to call'))
.on('telnyx.error', () => console.log('error'))
// Event fired on call updates, e.g. when there's an incoming call
.on('callUpdate', (call) => {
activeCall = call;

switch (call.state) {
// Connecting to a call
case 'connecting':
return;
// Receiving an inbound call
case 'ringing':
return;
// An established and active call
case 'active':
return;
// Call is active but on hold
case 'held':
return;
// Call is over and can be removed
case 'done':
activeCall = null;
// New calls that haven't started connecting yet
case 'new':
default:
return;
.on('telnyx.notification', (notification) => {
activeCall = notification.call;

switch (notification.type) {
case 'callUpdate':
// Call is over and can be removed
if (
notification.call.state === 'hangup' ||
notification.call.state === 'destroy'
) {
activeCall = null;
}
// An established and active call
if (notification.call.state === 'active') {
return;
}
// New calls that haven't started connecting yet
if (notification.call.state === 'new') {
return;
}
// Receiving an inbound call
if (notification.call.state === 'ringing') {
return;
}
// Call is active but on hold
if (notification.call.state === 'held') {
return;
}
break;
}
});

Expand All @@ -104,12 +113,14 @@ To initiate a call from your application:
// You can save this call or wait for `callUpdate` and use the returned `activeCall`
const call = client.newCall({
// Destination is required and can be a phone number or SIP URI
destination: '18004377950',
destinationNumber: '18004377950',
callerName: 'Caller ID Name',
// Caller ID number is optional.
// You can only specify a phone number that you own and have assigned
// to your Connection in the Telnyx Portal
callerNumber: '‬',
audio: true,
video: false, //Used to enable/disable video
});
```

Expand Down Expand Up @@ -139,6 +150,42 @@ call.reject();

---

### HTML

#### Using with React audio call

```Js
if (mediaRef.current && call && call.remoteStream) {
mediaRef.current.srcObject = call.remoteStream;
}

<audio
ref={mediaRef}
id='audioCall'
autoPlay='autoplay'
controls={false}
/>
```

#### Using with vanilla video call

```Js using with vanilla video call
client.remoteElement = 'remoteVideo';
client.localElement = 'localVideo';

<video
id="localVideo"
autoplay="true"
playsinline="true"
/>
<video
id="remoteVideo"
autoplay="true"
playsinline="true"
/>

```

## Examples

We've included a few [examples in React](examples/react) to help you get started. This library is not limited to React and can be used with any JavaScript framework of your choosing.
Expand All @@ -154,6 +201,13 @@ Configuration options for your Telnyx account are available under the [Storybook

---

We've included a few [examples in Javascript(ES6)](examples/vanilla) to help you get started.

```
cd examples/vanilla
open index.html
```

## Contributing

### Development
Expand Down
6 changes: 6 additions & 0 deletions examples/react-native/.buckconfig
@@ -0,0 +1,6 @@

[android]
target = Google Inc.:Google APIs:23

[maven_repositories]
central = https://repo1.maven.org/maven2
4 changes: 4 additions & 0 deletions examples/react-native/.eslintrc.js
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: '@react-native-community',
};
75 changes: 75 additions & 0 deletions examples/react-native/.flowconfig
@@ -0,0 +1,75 @@
[ignore]
; We fork some components by platform
.*/*[.]android.js

; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/

; Ignore polyfills
node_modules/react-native/Libraries/polyfills/.*

; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/warning')
node_modules/warning/.*

; Flow doesn't support platforms
.*/Libraries/Utilities/LoadingView.js

[untyped]
.*/node_modules/@react-native-community/cli/.*/.*

[include]

[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow/

[options]
emoji=true

esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable

module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js

munge_underscores=true

module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation'
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'

suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState

suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError

[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
inexact-spread=warn
unnecessary-invariant=warn
signature-verification-failure=warn
deprecated-utility=error

[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import

[version]
^0.105.0
1 change: 1 addition & 0 deletions examples/react-native/.gitattributes
@@ -0,0 +1 @@
*.pbxproj -text
59 changes: 59 additions & 0 deletions examples/react-native/.gitignore
@@ -0,0 +1,59 @@
# OSX
#
.DS_Store

# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate

# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml

# node.js
#
node_modules/
npm-debug.log
yarn-error.log

# BUCK
buck-out/
\.buckd/
*.keystore
!debug.keystore

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/

*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots

# Bundle artifact
*.jsbundle

# CocoaPods
/ios/Pods/
6 changes: 6 additions & 0 deletions examples/react-native/.prettierrc.js
@@ -0,0 +1,6 @@
module.exports = {
bracketSpacing: false,
jsxBracketSameLine: true,
singleQuote: true,
trailingComma: 'all',
};