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

Release 2.2.0 #284

Merged
merged 32 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
12cbbec
Outside of browser environment
sirknightj Oct 1, 2023
752eaf4
Remove Buffer
sirknightj Oct 1, 2023
6331efc
Remove unnecessary import
sirknightj Oct 2, 2023
d37bb0b
Increase max package size
sirknightj Oct 2, 2023
373983a
Remove _
sirknightj Oct 2, 2023
a93d771
Add options allowing for fine-grained control of sending and receivin…
sirknightj Sep 29, 2023
a17d06a
Add description
sirknightj Sep 29, 2023
f043e57
Add presets
sirknightj Sep 29, 2023
20072a7
Fix wrong method name
sirknightj Sep 29, 2023
08c093f
Remove debugging artifacts
sirknightj Sep 29, 2023
60d6c6d
Remove extra newlines
sirknightj Sep 29, 2023
d879653
Extract to common method
sirknightj Oct 2, 2023
b530868
sample: Add manual JoinStorageSession button
sirknightj Sep 1, 2023
0569350
sample: Adjust labels
sirknightj Sep 1, 2023
8f0b763
master role
sirknightj Sep 1, 2023
80db54b
sample: move the connected check to after the SDP answer is sent
sirknightj Sep 1, 2023
2b7e848
Add correlationId to sdp answer for joinStorageSession
sirknightj Oct 11, 2023
5c872be
100% code coverage in the unit tests
sirknightj Oct 11, 2023
445596f
Increase package size
sirknightj Oct 11, 2023
8f105b0
Remove testing artifact
sirknightj Oct 11, 2023
2534f56
Update README for correlationId
sirknightj Oct 12, 2023
cf4f6ac
Fix boolean flag
sirknightj Oct 18, 2023
c9ef64e
Adjust css
sirknightj Oct 18, 2023
cc7dea9
Disable datachannel for WebRTC ingestion and remove remote-view in in…
sirknightj Oct 18, 2023
8725bed
Adjust stop button color
sirknightj Oct 18, 2023
c949b57
reset storage client on next run
sirknightj Oct 18, 2023
57bc54e
reset storage client on next run
sirknightj Oct 18, 2023
5201fcf
Adjust comment for correlationId
sirknightj Oct 19, 2023
4f8e5bd
Bump @babel/traverse from 7.21.4 to 7.23.2
dependabot[bot] Oct 19, 2023
80de306
Bump react-devtools-core from 4.27.6 to 4.28.4
dependabot[bot] Oct 21, 2023
93dc4e2
Bump version
sirknightj Nov 7, 2023
391f4bc
Bump package lock
sirknightj Nov 7, 2023
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
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,19 @@ Emitted when a new SDP answer is received over the channel. Typically only a vie

Emitted when a new ICE candidate is received over the channel.

#### Event: `'statusResponse'`
* `statusResponse` {statusResponse} The [status response](https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-websocket-apis-7.html) received from the signaling service.

Emitted when a statusResponse is received over the channel.

* `statusResponse` {object}
* `correlationId` {string} `correlationId` of the message for which the status is meant.
* `success` {boolean} Whether this `statusResponse` is a success or failure. (Currently, these responses are only sent on failures.)
* `errorType` {optional string} A name to uniquely identify the error.
* `statusCode` {optional string} HTTP status code corresponding to the nature of the response.
* `description` {optional string} A string description explaining the status.


#### Event: `'close'`
Emitted when the connection to the signaling service is closed. Even if there is an error, as long as the connection is closed, this event will be emitted.

Expand All @@ -305,17 +318,20 @@ Opens a connection to the signaling service. An error will be thrown if there is
#### Method: `close()`
Closes the active connection to the signaling service. Nothing will happen if there is no open connection.

#### Method: `sendSdpOffer(sdpOffer, [recipientClientId])`
#### Method: `sendSdpOffer(sdpOffer, [recipientClientId, correlationId])`
* `sdpOffer` {[RTCSessionDescription](https://developer.mozilla.org/en-US/docs/Web/API/RTCSessionDescription)} SDP offer to send to the recipient client.
* `recipientClientId` {string} The id of the client to send the SDP offer to. If no id is provided, it will be sent to the master.
* `correlationId` {string} A unique identifier for this message. If there was an error with this message, Signaling will send a failure StatusResponse with the same correlationId.

#### Method: `sendSdpAnswer(sdpAnswer, [recipientClientId])`
#### Method: `sendSdpAnswer(sdpAnswer, [recipientClientId, correlationId])`
* `sdpAnswer` {[RTCSessionDescription](https://developer.mozilla.org/en-US/docs/Web/API/RTCSessionDescription)} SDP answer to send to the recipient client.
* `recipientClientId` {string} The id of the client to send the SDP answer to. If no id is provided, it will be sent to the master.
* `correlationId` {string} A unique identifier for this message. If there was an error with this message, Signaling will send a failure StatusResponse with the same correlationId.

#### Method: `sendIceCandidate(iceCandidate, [recipientClientId])`
#### Method: `sendIceCandidate(iceCandidate, [recipientClientId, correlationId])`
* `iceCandidate` {[RTCIceCandidate](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate)} ICE candidate to send to the recipient client.
* `recipientClientId` {string} The id of the client to send the ICE candidate to. If no id is provided, it will be sent to the master.
* `correlationId` {string} A unique identifier for this message. If there was an error with this message, Signaling will send a failure StatusResponse with the same correlationId.

### Interface: `RequestSigner`
Interface for signing HTTP and WebSocket requests.
Expand Down
4 changes: 2 additions & 2 deletions examples/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pre .warn {
color: goldenrod;
}

#debug pre {
#logs {
height: 500px;
overflow: auto;
}
}
179 changes: 179 additions & 0 deletions examples/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function getFormValues() {
sendAudio: $('#sendAudio').is(':checked'),
streamName: $('#streamName').val(),
ingestMedia: $('#ingest-media').is(':checked'),
showJSSButton: $('#show-join-storage-session-button').is(':checked'),
openDataChannel: $('#openDataChannel').is(':checked'),
widescreen: $('#widescreen').is(':checked'),
fullscreen: $('#fullscreen').is(':checked'),
Expand All @@ -88,6 +89,18 @@ function getFormValues() {
secretAccessKey: $('#secretAccessKey').val(),
sessionToken: $('#sessionToken').val() || null,
enableDQPmetrics: $('#enableDQPmetrics').is(':checked'),
sendHostCandidates: $('#send-host').is(':checked'),
acceptHostCandidates: $('#accept-host').is(':checked'),
sendRelayCandidates: $('#send-relay').is(':checked'),
acceptRelayCandidates: $('#accept-relay').is(':checked'),
sendSrflxCandidates: $('#send-srflx').is(':checked'),
acceptSrflxCandidates: $('#accept-srflx').is(':checked'),
sendPrflxCandidates: $('#send-prflx').is(':checked'),
acceptPrflxCandidates: $('#accept-prflx').is(':checked'),
sendTcpCandidates: $('#send-tcp').is(':checked'),
acceptTcpCandidates: $('#accept-tcp').is(':checked'),
sendUdpCandidates: $('#send-udp').is(':checked'),
acceptUdpCandidates: $('#accept-udp').is(':checked'),
};
}

Expand All @@ -112,6 +125,8 @@ function onStop() {
if (ROLE === 'master') {
stopMaster();
$('#master').addClass('d-none');
$('#master .remote-view').removeClass('d-none');
$('#master .remote').removeClass('d-none');
} else {
stopViewer();
$('#viewer').addClass('d-none');
Expand All @@ -123,6 +138,7 @@ function onStop() {
}

$('#form').removeClass('d-none');
$('#join-storage-session-button').addClass('d-none');
ROLE = null;
}

Expand Down Expand Up @@ -402,6 +418,7 @@ const fields = [
{ field: 'sendAudio', type: 'checkbox' },
{ field: 'streamName', type: 'text' },
{ field: 'ingest-media', type: 'checkbox' },
{ field: 'show-join-storage-session-button', type: 'checkbox' },
{ field: 'widescreen', type: 'radio', name: 'resolution' },
{ field: 'fullscreen', type: 'radio', name: 'resolution' },
{ field: 'openDataChannel', type: 'checkbox' },
Expand All @@ -410,7 +427,21 @@ const fields = [
{ field: 'forceSTUN', type: 'radio', name: 'natTraversal' },
{ field: 'forceTURN', type: 'radio', name: 'natTraversal' },
{ field: 'natTraversalDisabled', type: 'radio', name: 'natTraversal' },
{ field: 'enableDQPmetrics', type: 'checkbox' },
{ field: 'send-host', type: 'checkbox' },
{ field: 'accept-host', type: 'checkbox' },
{ field: 'send-relay', type: 'checkbox' },
{ field: 'accept-relay', type: 'checkbox' },
{ field: 'send-srflx', type: 'checkbox' },
{ field: 'accept-srflx', type: 'checkbox' },
{ field: 'send-prflx', type: 'checkbox' },
{ field: 'accept-prflx', type: 'checkbox' },
{ field: 'send-tcp', type: 'checkbox' },
{ field: 'accept-tcp', type: 'checkbox' },
{ field: 'send-udp', type: 'checkbox' },
{ field: 'accept-udp', type: 'checkbox' },
];

fields.forEach(({ field, type, name }) => {
const id = '#' + field;

Expand Down Expand Up @@ -459,6 +490,149 @@ fields.forEach(({ field, type, name }) => {
});
});

/**
* Determines whether the ICE Candidate should be added.
* @param formValues Settings used.
* @param candidate {RTCIceCandidate} iceCandidate to check
* @returns true if the candidate should be added to the peerConnection.
*/
function shouldAcceptCandidate(formValues, candidate) {
const { transport, type } = extractTransportAndType(candidate);

if (!formValues.acceptUdpCandidates && transport === 'udp') {
return false;
}

if (!formValues.acceptTcpCandidates && transport === 'tcp') {
return false;
}

switch (type) {
case 'host':
return formValues.acceptHostCandidates;
case 'srflx':
return formValues.acceptSrflxCandidates;
case 'relay':
return formValues.acceptRelayCandidates;
case 'prflx':
return formValues.acceptPrflxCandidates;
default:
console.warn('ShouldAcceptICECandidate: Unknown candidate type:', candidate.type);
return false;
}
}

$('#natTraversalEnabled').on('click', () => {
$('#accept-host').prop('checked', true);
$('#send-host').prop('checked', true);
$('#accept-relay').prop('checked', true);
$('#send-relay').prop('checked', true);
$('#accept-srflx').prop('checked', true);
$('#send-srflx').prop('checked', true);
$('#accept-prflx').prop('checked', true);
$('#send-prflx').prop('checked', true);

saveAdvanced();
});

$('#forceSTUN').on('click', () => {
$('#accept-host').prop('checked', false);
$('#send-host').prop('checked', false);
$('#accept-relay').prop('checked', false);
$('#send-relay').prop('checked', false);
$('#accept-srflx').prop('checked', true);
$('#send-srflx').prop('checked', true);
$('#accept-prflx').prop('checked', false);
$('#send-prflx').prop('checked', false);

saveAdvanced();
});

$('#forceTURN').on('click', () => {
$('#accept-host').prop('checked', false);
$('#send-host').prop('checked', false);
$('#accept-relay').prop('checked', true);
$('#send-relay').prop('checked', true);
$('#accept-srflx').prop('checked', false);
$('#send-srflx').prop('checked', false);
$('#accept-prflx').prop('checked', false);
$('#send-prflx').prop('checked', false);

saveAdvanced();
});

$('#natTraversalDisabled').on('click', () => {
$('#accept-host').prop('checked', true);
$('#send-host').prop('checked', true);
$('#accept-relay').prop('checked', true);
$('#send-relay').prop('checked', true);
$('#accept-srflx').prop('checked', true);
$('#send-srflx').prop('checked', true);
$('#accept-prflx').prop('checked', true);
$('#send-prflx').prop('checked', true);

saveAdvanced();
});

function saveAdvanced() {
$('#accept-host').trigger('change');
$('#send-host').trigger('change');
$('#accept-relay').trigger('change');
$('#send-relay').trigger('change');
$('#accept-srflx').trigger('change');
$('#send-srflx').trigger('change');
$('#accept-prflx').trigger('change');
$('#send-prflx').trigger('change');
}

/**
* Determines whether the ICE Candidate should be sent to the peer.
* @param formValues Settings used.
* @param candidate {RTCIceCandidate} iceCandidate to check
* @returns true if the candidate should be sent to the peer.
*/
function shouldSendIceCandidate(formValues, candidate) {
const { transport, type } = extractTransportAndType(candidate);

if (!formValues.sendUdpCandidates && transport === 'udp') {
return false;
}

if (!formValues.sendTcpCandidates && transport === 'tcp') {
return false;
}

switch (type) {
case 'host':
return formValues.sendHostCandidates;
case 'srflx':
return formValues.sendSrflxCandidates;
case 'relay':
return formValues.sendRelayCandidates;
case 'prflx':
return formValues.sendPrflxCandidates;
default:
console.warn('ShouldSendICECandidate: Unknown candidate type:', candidate.type);
return false;
}
}

function randomString() {
return Date.now().toString();
}

function extractTransportAndType(candidate) {
const words = candidate.candidate.split(' ');

if (words.length < 7) {
console.error('Invalid ice candidate!', candidate);
return false;
}

// https://datatracker.ietf.org/doc/html/rfc5245#section-15.1
return { transport: words[2], type: words[7] };
}

$('#copy-logs').on('click', async function() {
const logsResult = [];
$('#logs')
Expand Down Expand Up @@ -506,6 +680,11 @@ $('#create-stream-modal-create-stream-button').on('click', async function() {
});
});

$('#join-storage-session-button').on('click', async function() {
const formValues = getFormValues();
joinStorageSessionManually(formValues);
});

// Enable tooltips
$(document).ready(function() {
$('[data-toggle="tooltip"]').tooltip();
Expand Down
Loading
Loading