rn-verto-typescript
Version:
Verto Free Switch with React Native Type Script
261 lines (260 loc) • 9.34 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const FSRTCPeerConnection_1 = __importDefault(require("./FSRTCPeerConnection"));
const react_native_webrtc_1 = require("react-native-webrtc");
const react_native_webrtc_2 = require("react-native-webrtc");
let videoSourceId;
react_native_webrtc_1.mediaDevices.enumerateDevices().then((sourceInfos) => {
for (let i = 0; i < sourceInfos.length; i++) {
const sourceInfo = sourceInfos[i];
if (sourceInfo.kind === 'videoinput' &&
sourceInfo.facing === (false ? 'front' : 'back')) {
videoSourceId = sourceInfo.deviceId;
}
}
});
class VertoRTC {
constructor(options) {
this.options = {
useVideo: null,
userData: null,
localVideo: null,
screenShare: false,
useCamera: 'any',
iceServers: false,
videoParams: {},
audioParams: {},
verto: null,
callbacks: {
onPeerStreaming: () => { },
onPeerStreamingError: () => { },
onICESDP: () => { },
onNewCall: () => { }
},
mediaHandlers: {
playRemoteVideo: null,
stopRemoteVideo: null,
playLocalVideo: null,
stopLocalVideo: null,
},
...options,
};
this.mediaData = {
SDP: null,
profile: {},
candidateList: [],
};
if (this.options.useVideo && !this.options.screenShare) {
if (this.options.mediaHandlers && this.options.mediaHandlers.stopRemoteVideo) {
this.options.mediaHandlers.stopRemoteVideo();
}
}
}
useVideo(obj, local) {
if (obj) {
this.options.useVideo = obj;
this.options.localVideo = local;
}
else {
this.options.useVideo = null;
this.options.localVideo = null;
}
}
answer(sdp, onSuccess, onError) {
const sessionDescription = new react_native_webrtc_2.RTCSessionDescription({ sdp, type: 'answer' });
this.peer.addAnswerSDP(sessionDescription, onSuccess, onError);
}
stopPeer() {
if (this.peer) {
this.peer.stop();
}
}
onRemoteStream(stream) {
const { options: { useAudio, useVideo }, } = this;
const element = useVideo || useAudio;
if (element) {
this.options.verto.callbacks.onPlayRemoteVideo(stream);
if (this.options.mediaHandlers && this.options.mediaHandlers.playRemoteVideo) {
this.options.mediaHandlers.playRemoteVideo(stream);
}
}
}
stop() {
const { options: { useVideo, localVideo }, peer, localStream, } = this;
if (useVideo) {
if (this.options.mediaHandlers && this.options.mediaHandlers.stopRemoteVideo) {
this.options.mediaHandlers.stopRemoteVideo();
}
}
if (localVideo) {
if (this.options.mediaHandlers && this.options.mediaHandlers.stopLocalVideo) {
this.options.mediaHandlers.stopLocalVideo();
}
}
if (localStream) {
localStream.getTracks().forEach((track) => track.stop());
}
if (peer) {
peer.stop();
}
}
getAudioConstraint() {
const { useMic, audioParams, screenShare } = this.options;
if (screenShare) {
return false;
}
if (useMic === 'none') {
return false;
}
if (useMic === 'any') {
return audioParams;
}
return {
...audioParams,
deviceId: { exact: useMic },
};
}
// TODO Refactor this function, espacially dimension member
// TODO Set return type as an interface
getVideoConstraint() {
const { videoParams, useCamera, useVideo } = this.options;
if (!useVideo) {
return false;
}
if (this.options.screenShare) {
return this.getScreenConstraint();
}
if (useCamera === 'none') {
return false;
}
const dimensions = {
width: {},
height: {}
};
const { minWidth, maxWidth } = videoParams;
if (minWidth !== undefined && maxWidth !== undefined) {
dimensions.width = { min: minWidth, max: maxWidth };
}
const { minHeight, maxHeight } = videoParams;
if (minHeight !== undefined && maxHeight !== undefined) {
dimensions.height = { min: minHeight, max: maxHeight };
}
if (useCamera === 'any') {
return { ...dimensions };
}
return { ...dimensions, deviceId: useCamera };
}
getScreenConstraint() {
const { videoParams: screenParams, useCamera: useScreen } = this.options;
return {
mandatory: screenParams,
optional: useScreen ? [{ sourceId: useScreen }] : [],
};
}
getMediaParams() {
return {
audio: this.getAudioConstraint(),
video: this.getVideoConstraint(),
};
}
onICE(candidate) {
this.mediaData.candidate = candidate; // TODO it can be redundant
this.mediaData.candidateList.push(this.mediaData.candidate);
}
onICESDP(sdp) {
this.mediaData.SDP = sdp.sdp;
this.options.callbacks.onICESDP();
}
createAnswer({ useCamera, sdp }) {
const { options } = this;
const { useVideo, localVideo, iceServers } = options;
this.type = 'answer';
this.options.useCamera = useCamera;
const mediaConstraints = this.getMediaParams();
react_native_webrtc_1.mediaDevices
.getUserMedia(mediaConstraints)
.then((stream) => {
this.peer = new FSRTCPeerConnection_1.default({
type: 'answer',
attachStream: stream,
offerSDP: { sdp, type: 'offer' },
constraints: this.getPeerConstraints(),
onPeerStreamingError: this.options.callbacks.onPeerStreamingError,
onICE: this.onICE.bind(this),
onRemoteStream: this.onRemoteStream.bind(this),
onICESDP: (iceSdp) => this.onICESDP(iceSdp),
onAnswerSDP: (answerSDP) => {
// this.answer.SDP = answerSDP.sdp; // TODO Check this refactoring
this.answer(answerSDP.sdp);
},
iceServers,
});
if (useVideo && localVideo) {
this.options.verto.callbacks.onPlayLocalVideo(stream);
}
this.options.callbacks.onPeerStreaming(stream);
})
.catch(error => {
this.traceMediaError(mediaConstraints, error);
});
}
switchCamera(localVideoTrack) {
if (localVideoTrack) {
localVideoTrack._switchCamera();
}
}
getPeerConstraints() {
return {
offerToReceiveAudio: this.options.useSpeak !== 'none',
offerToReceiveVideo: !!this.options.useVideo,
};
}
inviteRemotePeerConnection() {
this.type = 'offer';
const mediaConstraints = this.getMediaParams();
const screen = this.options.videoParams && this.options.screenShare;
const screenPeerConstraints = {
offerToReceiveVideo: false,
offerToReceiveAudio: false,
offerToSendAudio: false,
};
const handleStream = (stream) => {
this.localStream = stream;
this.peer = new FSRTCPeerConnection_1.default({
type: this.type,
attachStream: stream,
onICESDP: this.onICESDP.bind(this),
onPeerStreamingError: this.options.callbacks.onPeerStreamingError,
constraints: screen ? screenPeerConstraints : this.getPeerConstraints(),
iceServers: this.options.iceServers,
onICE: this.onICE.bind(this),
onRemoteStream: (remoteStream) => !screen && this.onRemoteStream(remoteStream),
onOfferSDP: (sdp) => {
this.mediaData.SDP = sdp.sdp;
},
});
this.options.callbacks.onPeerStreaming(stream);
if (this.options.verto.callbacks.onPlayLocalVideo) {
this.options.verto.callbacks.onPlayLocalVideo(stream);
}
};
if (!mediaConstraints.audio && !mediaConstraints.video) {
handleStream(null);
}
else {
react_native_webrtc_1.mediaDevices
.getUserMedia(mediaConstraints)
.then(handleStream)
.catch(error => {
this.traceMediaError(mediaConstraints, error);
});
}
}
traceMediaError(constraints, error) {
console.log('User media error', 'Constraints:', constraints, 'Error:', error);
}
}
exports.default = VertoRTC;