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

call get ice servers when offer is received to avoid stale ice server… #86

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 51 additions & 29 deletions examples/master.js
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@ const master = {
localStream: null,
remoteStreams: [],
peerConnectionStatsInterval: null,
kinesisVideoSignalingChannelsClient: null,
pendingIceCandidateByClientId: {},
};

async function startMaster(localView, remoteView, formValues, onStatsReport, onRemoteDataMessage) {
@@ -63,48 +65,24 @@ async function startMaster(localView, remoteView, formValues, onStatsReport, onR
systemClockOffset: kinesisVideoClient.config.systemClockOffset,
});

// Get ICE server configuration
const kinesisVideoSignalingChannelsClient = new AWS.KinesisVideoSignalingChannels({
// Create client for calling getIceServerConfig
master.kinesisVideoSignalingChannelsClient = new AWS.KinesisVideoSignalingChannels({
region: formValues.region,
accessKeyId: formValues.accessKeyId,
secretAccessKey: formValues.secretAccessKey,
sessionToken: formValues.sessionToken,
endpoint: endpointsByProtocol.HTTPS,
correctClockSkew: true,
});
const getIceServerConfigResponse = await kinesisVideoSignalingChannelsClient
.getIceServerConfig({
ChannelARN: channelARN,
})
.promise();
const iceServers = [];
if (!formValues.natTraversalDisabled && !formValues.forceTURN) {
iceServers.push({ urls: `stun:stun.kinesisvideo.${formValues.region}.amazonaws.com:443` });
}
if (!formValues.natTraversalDisabled) {
getIceServerConfigResponse.IceServerList.forEach(iceServer =>
iceServers.push({
urls: iceServer.Uris,
username: iceServer.Username,
credential: iceServer.Password,
}),
);
}
console.log('[MASTER] ICE servers: ', iceServers);

const configuration = {
iceServers,
iceTransportPolicy: formValues.forceTURN ? 'relay' : 'all',
};

const resolution = formValues.widescreen ? { width: { ideal: 1280 }, height: { ideal: 720 } } : { width: { ideal: 640 }, height: { ideal: 480 } };
const constraints = {
video: formValues.sendVideo ? resolution : false,
audio: formValues.sendAudio,
};

// Get a stream from the webcam and display it in the local view.
// If no video/audio needed, no need to request for the sources.
// Get a stream from the webcam and display it in the local view.
// If no video/audio needed, no need to request for the sources.
// Otherwise, the browser will throw an error saying that either video or audio has to be enabled.
if (formValues.sendVideo || formValues.sendAudio) {
try {
@@ -122,6 +100,35 @@ async function startMaster(localView, remoteView, formValues, onStatsReport, onR
master.signalingClient.on('sdpOffer', async (offer, remoteClientId) => {
console.log('[MASTER] Received SDP offer from client: ' + remoteClientId);

// Get ICE server configuration.
const getIceServerConfigResponse = await master.kinesisVideoSignalingChannelsClient
.getIceServerConfig({
ChannelARN: channelARN,
})
.promise();

const iceServers = [];

if (!formValues.natTraversalDisabled && !formValues.forceTURN) {
iceServers.push({ urls: `stun:stun.kinesisvideo.${formValues.region}.amazonaws.com:443` });
}
if (!formValues.natTraversalDisabled) {
getIceServerConfigResponse.IceServerList.forEach(iceServer =>
iceServers.push({
urls: iceServer.Uris,
username: iceServer.Username,
credential: iceServer.Password,
}),
);
}

console.log('[MASTER] ICE servers: ', iceServers);

const configuration = {
iceServers,
iceTransportPolicy: formValues.forceTURN ? 'relay' : 'all',
};

// Create a new peer connection using the offer from the given client
const peerConnection = new RTCPeerConnection(configuration);
master.peerConnectionByClientId[remoteClientId] = peerConnection;
@@ -174,6 +181,11 @@ async function startMaster(localView, remoteView, formValues, onStatsReport, onR
}
await peerConnection.setRemoteDescription(offer);

// Submit ice candidates after remote description has been set.
if (master.pendingIceCandidateByClientId[remoteClientId]) {
master.pendingIceCandidateByClientId[remoteClientId].forEach(iceCandidate => peerConnection.addIceCandidate(iceCandidate));
}

// Create an SDP answer to send back to the client
console.log('[MASTER] Creating SDP answer for client: ' + remoteClientId);
await peerConnection.setLocalDescription(
@@ -196,7 +208,17 @@ async function startMaster(localView, remoteView, formValues, onStatsReport, onR

// Add the ICE candidate received from the client to the peer connection
const peerConnection = master.peerConnectionByClientId[remoteClientId];
peerConnection.addIceCandidate(candidate);

// Can not deliver ice candidate until remote description has been set.
// Therefore store ice candidate if peerConnection is not ready.
if (peerConnection && peerConnection.remoteDescription) {
peerConnection.addIceCandidate(candidate);
} else {
if (!master.pendingIceCandidateByClientId[remoteClientId]) {
master.pendingIceCandidateByClientId[remoteClientId] = [];
}
master.pendingIceCandidateByClientId[remoteClientId].push(candidate);
}
});

master.signalingClient.on('close', () => {