mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
fixing connectivity issues
This commit is contained in:
parent
5d229bbef3
commit
99ccd86ac6
469
app/mobile/src/context/REFACTORFAIL
Normal file
469
app/mobile/src/context/REFACTORFAIL
Normal file
@ -0,0 +1,469 @@
|
|||||||
|
import { useEffect, useContext, useState, useRef } from 'react';
|
||||||
|
import { Alert } from 'react-native';
|
||||||
|
import { createWebsocket } from 'api/fetchUtil';
|
||||||
|
import { addContactRing } from 'api/addContactRing';
|
||||||
|
import { addCall } from 'api/addCall';
|
||||||
|
import { keepCall } from 'api/keepCall';
|
||||||
|
import { removeCall } from 'api/removeCall';
|
||||||
|
import { removeContactCall } from 'api/removeContactCall';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ScreenCapturePickerView,
|
||||||
|
RTCPeerConnection,
|
||||||
|
RTCIceCandidate,
|
||||||
|
RTCSessionDescription,
|
||||||
|
RTCView,
|
||||||
|
MediaStream,
|
||||||
|
MediaStreamTrack,
|
||||||
|
mediaDevices,
|
||||||
|
registerGlobals
|
||||||
|
} from 'react-native-webrtc';
|
||||||
|
|
||||||
|
export function useRingContext() {
|
||||||
|
const [state, setState] = useState({
|
||||||
|
ringing: new Map(),
|
||||||
|
callStatus: null,
|
||||||
|
cardId: null,
|
||||||
|
localStream: null,
|
||||||
|
localVideo: false,
|
||||||
|
localAudio: false,
|
||||||
|
remoteStream: null,
|
||||||
|
removeVideo: false,
|
||||||
|
removeAudio: false,
|
||||||
|
});
|
||||||
|
const access = useRef(null);
|
||||||
|
|
||||||
|
const EXPIRE = 3000
|
||||||
|
const RING = 2000
|
||||||
|
const ringing = useRef(new Map());
|
||||||
|
const calling = useRef(null);
|
||||||
|
const ws = useRef(null);
|
||||||
|
const pc = useRef(null);
|
||||||
|
const stream = useRef(null);
|
||||||
|
const accessVideo = useRef(false);
|
||||||
|
const accessAudio = useRef(false);
|
||||||
|
const videoTrack = useRef();
|
||||||
|
const audioTrack = useRef();
|
||||||
|
const candidates = useRef([]);
|
||||||
|
const offers = useRef([]);
|
||||||
|
const processing = useRef(false);
|
||||||
|
const connected = useRef(false);
|
||||||
|
|
||||||
|
const iceServers = [
|
||||||
|
{
|
||||||
|
urls: 'stun:35.165.123.117:5001?transport=udp',
|
||||||
|
username: 'user',
|
||||||
|
credential: 'pass'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
urls: 'turn:35.165.123.117:5001?transport=udp',
|
||||||
|
username: 'user',
|
||||||
|
credential: 'pass'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const constraints = {
|
||||||
|
mandatory: {
|
||||||
|
OfferToReceiveAudio: true,
|
||||||
|
OfferToReceiveVideo: true,
|
||||||
|
VoiceActivityDetection: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateState = (value) => {
|
||||||
|
setState((s) => ({ ...s, ...value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const polite = async () => {
|
||||||
|
if (processing.current || !connected.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
processing.current = true;
|
||||||
|
|
||||||
|
while (offers.current.length > 0) {
|
||||||
|
descriptions = offers.current;
|
||||||
|
offers.current = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (let i = 0; i < descriptions.length; i++) {
|
||||||
|
const description = descriptions[i];
|
||||||
|
stream.current = null;
|
||||||
|
|
||||||
|
if (description == null) {
|
||||||
|
const offer = await pc.current.createOffer(constraints);
|
||||||
|
await pc.current.setLocalDescription(offer);
|
||||||
|
ws.current.send(JSON.stringify({ description: offer }));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (description.type === 'offer' && pc.current.signalingState !== 'stable') {
|
||||||
|
const rollback = new RTCSessionDescription({ type: "rollback" });
|
||||||
|
await pc.current.setLocalDescription(rollback);
|
||||||
|
}
|
||||||
|
const offer = new RTCSessionDescription(description);
|
||||||
|
await pc.current.setRemoteDescription(offer);
|
||||||
|
if (description.type === 'offer') {
|
||||||
|
const answer = await pc.current.createAnswer();
|
||||||
|
await pc.current.setLocalDescription(answer);
|
||||||
|
ws.current.send(JSON.stringify({ description: answer }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
Alert.alert('webrtc error', err.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
processing.current = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const impolite = async () => {
|
||||||
|
if (processing.current || !connected.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
processing.current = true;
|
||||||
|
while (offers.current.length > 0) {
|
||||||
|
descriptions = offers.current;
|
||||||
|
offers.current = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < descriptions.length; i++) {
|
||||||
|
const description = descriptions[i];
|
||||||
|
stream.current = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (description == null) {
|
||||||
|
const offer = await pc.current.createOffer(constraints);
|
||||||
|
await pc.current.setLocalDescription(offer);
|
||||||
|
ws.current.send(JSON.stringify({ description: offer }));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (description.type === 'offer' && pc.current.signalingState !== 'stable') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (description.type === 'answer' && pc.current.signalingState === 'stable') {
|
||||||
|
const offer = await pc.current.createOffer(constraints);
|
||||||
|
await pc.current.setLocalDescription(offer);
|
||||||
|
ws.current.send(JSON.stringify({ description: offer }));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const offer = new RTCSessionDescription(description);
|
||||||
|
await pc.current.setRemoteDescription(offer);
|
||||||
|
|
||||||
|
if (description.type === 'offer') {
|
||||||
|
const answer = await pc.current.createAnswer();
|
||||||
|
await pc.current.setLocalDescription(answer);
|
||||||
|
ws.current.send(JSON.stringify({ description: answer }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
Alert.alert('webrtc error', err.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processing.current = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const connect = async (politePolicy, node, token, clearRing, clearAlive) => {
|
||||||
|
|
||||||
|
// connect signal socket
|
||||||
|
candidates.current = [];
|
||||||
|
connected.current = false;
|
||||||
|
updateState({ remoteVideo: false, remoteAudio: false, remoteStream: null, localVideo: false, localAudio: false, localStream: null });
|
||||||
|
|
||||||
|
pc.current = new RTCPeerConnection({ iceServers });
|
||||||
|
pc.current.addEventListener( 'connectionstatechange', event => {
|
||||||
|
console.log("CONNECTION STATE", event);
|
||||||
|
} );
|
||||||
|
pc.current.addEventListener( 'icecandidate', event => {
|
||||||
|
ws.current.send(JSON.stringify({ candidate: event.candidate }));
|
||||||
|
} );
|
||||||
|
pc.current.addEventListener( 'icecandidateerror', event => {
|
||||||
|
console.log("ICE ERROR");
|
||||||
|
} );
|
||||||
|
pc.current.addEventListener( 'iceconnectionstatechange', event => {
|
||||||
|
console.log("ICE STATE CHANGE", event);
|
||||||
|
} );
|
||||||
|
pc.current.addEventListener( 'negotiationneeded', async (ev) => {
|
||||||
|
offers.current.push(null);
|
||||||
|
if (politePolicy) {
|
||||||
|
policy();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
impolite();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
pc.current.addEventListener( 'signalingstatechange', event => {
|
||||||
|
console.log("ICE SIGNALING", event);
|
||||||
|
} );
|
||||||
|
pc.current.addEventListener( 'track', event => {
|
||||||
|
if (stream.current == null) {
|
||||||
|
stream.current = new MediaStream();
|
||||||
|
updateState({ remoteStream: stream.current });
|
||||||
|
}
|
||||||
|
if (event.track.kind === 'audio') {
|
||||||
|
updateState({ remoteAudio: true });
|
||||||
|
}
|
||||||
|
if (event.track.kind === 'video') {
|
||||||
|
updateState({ remoteVideo: true });
|
||||||
|
}
|
||||||
|
stream.current.addTrack(event.track, stream.current);
|
||||||
|
} );
|
||||||
|
|
||||||
|
videoTrack.current = false;
|
||||||
|
audioTrack.current = false;
|
||||||
|
accessVideo.current = false;
|
||||||
|
accessAudio.current = false;
|
||||||
|
try {
|
||||||
|
const stream = await mediaDevices.getUserMedia({
|
||||||
|
video: false,
|
||||||
|
audio: true,
|
||||||
|
});
|
||||||
|
accessAudio.current = true;
|
||||||
|
updateState({ localAudio: true });
|
||||||
|
for (const track of stream.getTracks()) {
|
||||||
|
if (track.kind === 'audio') {
|
||||||
|
audioTrack.current = track;
|
||||||
|
}
|
||||||
|
pc.current.addTrack(track);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.current = createWebsocket(`wss://${node}/signal`);
|
||||||
|
ws.current.onmessage = async (ev) => {
|
||||||
|
// handle messages [impolite]
|
||||||
|
try {
|
||||||
|
const signal = JSON.parse(ev.data);
|
||||||
|
if (signal.status === 'connected') {
|
||||||
|
clearRing();
|
||||||
|
updateState({ callStatus: "connected" });
|
||||||
|
if (!politePolicy) {
|
||||||
|
connected.current = true;
|
||||||
|
impolite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (signal.status === 'closed') {
|
||||||
|
ws.current.close();
|
||||||
|
}
|
||||||
|
else if (signal.description) {
|
||||||
|
offers.current.push(signal.description);
|
||||||
|
impolite();
|
||||||
|
}
|
||||||
|
else if (signal.candidate) {
|
||||||
|
if (pc.current.remoteDescription == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const candidate = new RTCIceCandidate(signal.candidate);
|
||||||
|
await pc.current.addIceCandidate(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws.current.onclose = (e) => {
|
||||||
|
// update state to disconnected
|
||||||
|
pc.current.close();
|
||||||
|
clearRing();
|
||||||
|
clearAlive();
|
||||||
|
calling.current = null;
|
||||||
|
if (videoTrack.current) {
|
||||||
|
videoTrack.current.stop();
|
||||||
|
videoTrack.current = null;
|
||||||
|
}
|
||||||
|
if (audioTrack.current) {
|
||||||
|
audioTrack.current.stop();
|
||||||
|
audioTrack.current = null;
|
||||||
|
}
|
||||||
|
updateState({ callStatus: null });
|
||||||
|
}
|
||||||
|
ws.current.onopen = async () => {
|
||||||
|
ws.current.send(JSON.stringify({ AppToken: token }));
|
||||||
|
if (politePolicy) {
|
||||||
|
connected.current = true;
|
||||||
|
polite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws.current.error = (e) => {
|
||||||
|
console.log(e)
|
||||||
|
ws.current.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
setSession: (token) => {
|
||||||
|
|
||||||
|
if (access.current) {
|
||||||
|
throw new Error("invalid ring state");
|
||||||
|
}
|
||||||
|
access.current = token;
|
||||||
|
ringing.current = new Map();
|
||||||
|
calling.current = null;
|
||||||
|
updateState({ callStatus: null, ringing: ringing.current });
|
||||||
|
},
|
||||||
|
clearSession: () => {
|
||||||
|
access.current = null;
|
||||||
|
},
|
||||||
|
ring: (cardId, callId, calleeToken) => {
|
||||||
|
const key = `${cardId}:${callId}`
|
||||||
|
const call = ringing.current.get(key) || { cardId, calleeToken, callId }
|
||||||
|
call.expires = Date.now() + EXPIRE;
|
||||||
|
ringing.current.set(key, call);
|
||||||
|
updateState({ ringing: ringing.current });
|
||||||
|
setTimeout(() => {
|
||||||
|
updateState({ ringing: ringing.current });
|
||||||
|
}, EXPIRE);
|
||||||
|
},
|
||||||
|
ignore: async (cardId, callId) => {
|
||||||
|
const key = `${cardId}:${callId}`
|
||||||
|
const call = ringing.current.get(key);
|
||||||
|
if (call) {
|
||||||
|
call.status = 'ignored'
|
||||||
|
ringing.current.set(key, call);
|
||||||
|
updateState({ ringing: ringing.current });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
decline: async (cardId, contactNode, contactToken, callId) => {
|
||||||
|
const key = `${cardId}:${callId}`
|
||||||
|
const call = ringing.current.get(key);
|
||||||
|
if (call) {
|
||||||
|
call.status = 'declined'
|
||||||
|
ringing.current.set(key, call);
|
||||||
|
updateState({ ringing: ringing.current });
|
||||||
|
try {
|
||||||
|
await removeContactCall(contactNode, contactToken, callId);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
accept: async (cardId, callId, contactNode, contactToken, calleeToken) => {
|
||||||
|
if (calling.current) {
|
||||||
|
throw new Error("active session");
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = `${cardId}:${callId}`
|
||||||
|
const call = ringing.current.get(key);
|
||||||
|
if (call) {
|
||||||
|
call.status = 'accepted'
|
||||||
|
ringing.current.set(key, call);
|
||||||
|
updateState({ ringing: ringing.current, callStatus: "connecting", cardId });
|
||||||
|
|
||||||
|
calling.current = { callId, contactNode, contactToken, host: false };
|
||||||
|
await connect(impolite, contactNode, calleeToken, () => {}, () => {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
end: async () => {
|
||||||
|
if (!calling.current) {
|
||||||
|
throw new Error('inactive session');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const { host, callId, contactNode, contactToken } = calling.current;
|
||||||
|
if (host) {
|
||||||
|
const { server, token } = access.current;
|
||||||
|
await removeCall(server, token, callId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await removeContactCall(contactNode, contactToken, callId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
ws.current.close();
|
||||||
|
},
|
||||||
|
call: async (cardId, contactNode, contactToken) => {
|
||||||
|
if (calling.current) {
|
||||||
|
throw new Error("active session");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create call
|
||||||
|
const { server, token } = access.current;
|
||||||
|
const call = await addCall(server, token, cardId);
|
||||||
|
const { id, keepAlive, callerToken, calleeToken } = call;
|
||||||
|
try {
|
||||||
|
await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken });
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
const aliveInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
await keepCall(server, token, id);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}, keepAlive * 1000);
|
||||||
|
let index = 0;
|
||||||
|
const ringInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken });
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}, RING);
|
||||||
|
|
||||||
|
updateState({ callStatus: "ringing", cardId });
|
||||||
|
calling.current = { callId: id, host: true };
|
||||||
|
await connect(polite, server, callerToken, () => clearInterval(ringInterval), () => clearInterval(aliveInterval));
|
||||||
|
},
|
||||||
|
enableVideo: async () => {
|
||||||
|
if (!accessVideo.current) {
|
||||||
|
const stream = await mediaDevices.getUserMedia({
|
||||||
|
audio: true,
|
||||||
|
video: {
|
||||||
|
frameRate: 30,
|
||||||
|
facingMode: 'user'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
accessVideo.current = true;
|
||||||
|
accessAudio.current = true;
|
||||||
|
updateState({ localStream: stream });
|
||||||
|
for (const track of stream.getTracks()) {
|
||||||
|
if (track.kind === 'audio') {
|
||||||
|
audioTrack.current = track;
|
||||||
|
}
|
||||||
|
if (track.kind === 'video') {
|
||||||
|
videoTrack.current = track;
|
||||||
|
}
|
||||||
|
pc.current.addTrack(track);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
videoTrack.current.enabled = true;
|
||||||
|
}
|
||||||
|
updateState({ localVideo: true, localAudio: true });
|
||||||
|
},
|
||||||
|
disableVideo: async () => {
|
||||||
|
if (videoTrack.current) {
|
||||||
|
videoTrack.current.enabled = false;
|
||||||
|
}
|
||||||
|
updateState({ localVideo: false });
|
||||||
|
},
|
||||||
|
enableAudio: async () => {
|
||||||
|
if (accessAudio.current) {
|
||||||
|
audioTrack.current.enabled = true;
|
||||||
|
updateState({ localAudio: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disableAudio: async () => {
|
||||||
|
if (accessAudio.current) {
|
||||||
|
audioTrack.current.enabled = false;
|
||||||
|
updateState({ localAudio: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return { state, actions }
|
||||||
|
}
|
||||||
|
|
@ -110,8 +110,9 @@ export function useRingContext() {
|
|||||||
const servers = candidates.current;
|
const servers = candidates.current;
|
||||||
candidates.current = [];
|
candidates.current = [];
|
||||||
for (let i = 0; i < servers.length; i++) {
|
for (let i = 0; i < servers.length; i++) {
|
||||||
const server = servers[i];
|
console.log("FLUSHING:", i);
|
||||||
ws.current.send(JSON.stringify(server));
|
const candidate = new RTCIceCandidate(servers[i]);
|
||||||
|
await pc.current.addIceCandidate(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,8 +161,9 @@ export function useRingContext() {
|
|||||||
const servers = candidates.current;
|
const servers = candidates.current;
|
||||||
candidates.current = [];
|
candidates.current = [];
|
||||||
for (let i = 0; i < servers.length; i++) {
|
for (let i = 0; i < servers.length; i++) {
|
||||||
const server = servers[i];
|
console.log("FLUSHING:", i);
|
||||||
ws.current.send(JSON.stringify(server));
|
const candidate = new RTCIceCandidate(servers[i]);
|
||||||
|
await pc.current.addIceCandidate(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,25 +175,14 @@ export function useRingContext() {
|
|||||||
processing.current = false;
|
processing.current = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const connect = async (policy, node, token, clearRing, clearAlive) => {
|
const transmit = async (policy) => {
|
||||||
|
|
||||||
// connect signal socket
|
|
||||||
connected.current = false;
|
|
||||||
candidates.current = [];
|
|
||||||
updateState({ remoteVideo: false, remoteAudio: false, remoteStream: null, localVideo: false, localAudio: false, localStream: null });
|
|
||||||
|
|
||||||
pc.current = new RTCPeerConnection({ iceServers });
|
pc.current = new RTCPeerConnection({ iceServers });
|
||||||
pc.current.addEventListener( 'connectionstatechange', event => {
|
pc.current.addEventListener( 'connectionstatechange', event => {
|
||||||
console.log("CONNECTION STATE", event);
|
console.log("CONNECTION STATE", event);
|
||||||
} );
|
} );
|
||||||
pc.current.addEventListener( 'icecandidate', event => {
|
pc.current.addEventListener( 'icecandidate', event => {
|
||||||
if (pc.current.remoteDescription == null) {
|
ws.current.send(JSON.stringify({ candidate: event.candidate }));
|
||||||
console.log("QUEING ICE");
|
|
||||||
candidates.current.push({ candidate: event.candidate });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ws.current.send(JSON.stringify({ candidate: event.candidate }));
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
pc.current.addEventListener( 'icecandidateerror', event => {
|
pc.current.addEventListener( 'icecandidateerror', event => {
|
||||||
console.log("ICE ERROR");
|
console.log("ICE ERROR");
|
||||||
@ -225,28 +216,45 @@ export function useRingContext() {
|
|||||||
stream.current.addTrack(event.track, stream.current);
|
stream.current.addTrack(event.track, stream.current);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
videoTrack.current = false;
|
|
||||||
audioTrack.current = false;
|
|
||||||
accessVideo.current = false;
|
|
||||||
accessAudio.current = false;
|
|
||||||
try {
|
try {
|
||||||
const stream = await mediaDevices.getUserMedia({
|
const stream = await mediaDevices.getUserMedia({
|
||||||
video: false,
|
|
||||||
audio: true,
|
audio: true,
|
||||||
|
video: {
|
||||||
|
frameRate: 30,
|
||||||
|
facingMode: 'user'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
accessAudio.current = true;
|
|
||||||
updateState({ localAudio: true });
|
|
||||||
for (const track of stream.getTracks()) {
|
for (const track of stream.getTracks()) {
|
||||||
if (track.kind === 'audio') {
|
if (track.kind === 'audio') {
|
||||||
|
accessAudio.current = true;
|
||||||
audioTrack.current = track;
|
audioTrack.current = track;
|
||||||
|
pc.current.addTrack(track, stream);
|
||||||
|
updateState({ localAudio: true });
|
||||||
|
}
|
||||||
|
if (track.kind === 'video') {
|
||||||
|
accessVideo.current = true;
|
||||||
|
videoTrack.current = track;
|
||||||
|
pc.current.addTrack(track, stream);
|
||||||
|
updateState({ localVideo: true });
|
||||||
}
|
}
|
||||||
pc.current.addTrack(track);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
Alert.alert('Media Access', err.toString());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const connect = async (policy, node, token, clearRing, clearAlive) => {
|
||||||
|
|
||||||
|
// connect signal socket
|
||||||
|
connected.current = false;
|
||||||
|
candidates.current = [];
|
||||||
|
updateState({ remoteVideo: false, remoteAudio: false, remoteStream: null, localVideo: false, localAudio: false, localStream: null });
|
||||||
|
|
||||||
|
videoTrack.current = false;
|
||||||
|
audioTrack.current = false;
|
||||||
|
accessVideo.current = false;
|
||||||
|
accessAudio.current = false;
|
||||||
|
|
||||||
ws.current = createWebsocket(`wss://${node}/signal`);
|
ws.current = createWebsocket(`wss://${node}/signal`);
|
||||||
ws.current.onmessage = async (ev) => {
|
ws.current.onmessage = async (ev) => {
|
||||||
@ -258,6 +266,7 @@ export function useRingContext() {
|
|||||||
updateState({ callStatus: "connected" });
|
updateState({ callStatus: "connected" });
|
||||||
if (policy === 'polite') {
|
if (policy === 'polite') {
|
||||||
connected.current = true;
|
connected.current = true;
|
||||||
|
transmit('polite');
|
||||||
polite();
|
polite();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -275,10 +284,12 @@ export function useRingContext() {
|
|||||||
}
|
}
|
||||||
else if (signal.candidate) {
|
else if (signal.candidate) {
|
||||||
if (pc.current.remoteDescription == null) {
|
if (pc.current.remoteDescription == null) {
|
||||||
return;
|
candidates.current.push(signal.candidate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const candidate = new RTCIceCandidate(signal.candidate);
|
||||||
|
await pc.current.addIceCandidate(candidate);
|
||||||
}
|
}
|
||||||
const candidate = new RTCIceCandidate(signal.candidate);
|
|
||||||
await pc.current.addIceCandidate(candidate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@ -305,6 +316,7 @@ export function useRingContext() {
|
|||||||
ws.current.send(JSON.stringify({ AppToken: token }));
|
ws.current.send(JSON.stringify({ AppToken: token }));
|
||||||
if (policy === 'impolite') {
|
if (policy === 'impolite') {
|
||||||
connected.current = true;
|
connected.current = true;
|
||||||
|
transmit('impolite');
|
||||||
impolite();
|
impolite();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,46 +448,33 @@ export function useRingContext() {
|
|||||||
await connect('polite', server, callerToken, () => clearInterval(ringInterval), () => clearInterval(aliveInterval));
|
await connect('polite', server, callerToken, () => clearInterval(ringInterval), () => clearInterval(aliveInterval));
|
||||||
},
|
},
|
||||||
enableVideo: async () => {
|
enableVideo: async () => {
|
||||||
if (!accessVideo.current) {
|
if (videoTrack.current) {
|
||||||
const stream = await mediaDevices.getUserMedia({
|
if (!accessVideo.current) {
|
||||||
audio: true,
|
accessVideo.current = true;
|
||||||
video: {
|
pc.current.addTrack(videoTrack.current);
|
||||||
frameRate: 30,
|
|
||||||
facingMode: 'user'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
accessVideo.current = true;
|
|
||||||
accessAudio.current = true;
|
|
||||||
updateState({ localStream: stream });
|
|
||||||
for (const track of stream.getTracks()) {
|
|
||||||
if (track.kind === 'audio') {
|
|
||||||
audioTrack.current = track;
|
|
||||||
}
|
|
||||||
if (track.kind === 'video') {
|
|
||||||
videoTrack.current = track;
|
|
||||||
}
|
|
||||||
pc.current.addTrack(track);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
videoTrack.current.enabled = true;
|
videoTrack.current.enabled = true;
|
||||||
}
|
}
|
||||||
updateState({ localVideo: true, localAudio: true });
|
updateState({ localVideo: true });
|
||||||
},
|
},
|
||||||
disableVideo: async () => {
|
disableVideo: async () => {
|
||||||
if (videoTrack.current) {
|
if (videoTrack.current) {
|
||||||
videoTrack.current.enabled = false;
|
videoTrack.current.enabled = false;
|
||||||
|
updateState({ localVideo: false });
|
||||||
}
|
}
|
||||||
updateState({ localVideo: false });
|
|
||||||
},
|
},
|
||||||
enableAudio: async () => {
|
enableAudio: async () => {
|
||||||
if (accessAudio.current) {
|
if (audioTrack.current) {
|
||||||
|
if (!accessAudio.current) {
|
||||||
|
accessAudio.current = true;
|
||||||
|
pc.current.addTrack(audioTrack.current);
|
||||||
|
}
|
||||||
audioTrack.current.enabled = true;
|
audioTrack.current.enabled = true;
|
||||||
updateState({ localAudio: true });
|
updateState({ localAudio: true });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disableAudio: async () => {
|
disableAudio: async () => {
|
||||||
if (accessAudio.current) {
|
if (audioTrack.current) {
|
||||||
audioTrack.current.enabled = false;
|
audioTrack.current.enabled = false;
|
||||||
updateState({ localAudio: false });
|
updateState({ localAudio: false });
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user