Skip to content

Commit

Permalink
Make use of RTCRtpScriptTransform if available. (#1468)
Browse files Browse the repository at this point in the history
* Make use of RTCRtpScriptTransform if available.
Use VP8 by default as it works best with encryption transforms.

* fix some style issues

* Add RTCRtpScriptTransform as global

* Addressing comments

* lint

Co-authored-by: Harald Alvestrand <harald@alvestrand.no>
Co-authored-by: Christoffer Jansson <jansson@google.com>
  • Loading branch information
3 people committed Oct 19, 2021
1 parent d087987 commit 80207cd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 16 deletions.
36 changes: 26 additions & 10 deletions src/content/insertable-streams/endtoend-encryption/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

'use strict';

/* global RTCRtpScriptTransform */
/* global VideoPipe */

const video1 = document.querySelector('video#video1');
Expand Down Expand Up @@ -38,20 +39,25 @@ let localStream;
// eslint-disable-next-line no-unused-vars
let remoteStream;

const supportsInsertableStreams =
let hasEnoughAPIs = !!window.RTCRtpScriptTransform;

if (!hasEnoughAPIs) {
const supportsInsertableStreams =
!!RTCRtpSender.prototype.createEncodedStreams;

let supportsTransferableStreams = false;
try {
const stream = new ReadableStream();
window.postMessage(stream, '*', [stream]);
supportsTransferableStreams = true;
} catch (e) {
console.error('Transferable streams are not supported.');
let supportsTransferableStreams = false;
try {
const stream = new ReadableStream();
window.postMessage(stream, '*', [stream]);
supportsTransferableStreams = true;
} catch (e) {
console.error('Transferable streams are not supported.');
}
hasEnoughAPIs = supportsInsertableStreams && supportsTransferableStreams;
}

if (!(supportsInsertableStreams && supportsTransferableStreams)) {
banner.innerText = 'Your browser does not support Insertable Streams. ' +
if (!hasEnoughAPIs) {
banner.innerText = 'Your browser does not support WebRTC Encoded Transforms. ' +
'This sample will not work.';
if (adapter.browserDetails.browser === 'chrome') {
banner.innerText += ' Try with Enable experimental Web Platform features enabled from chrome://flags.';
Expand Down Expand Up @@ -93,6 +99,11 @@ function start() {
// for basic concepts.
const worker = new Worker('./js/worker.js', {name: 'E2EE worker'});
function setupSenderTransform(sender) {
if (window.RTCRtpScriptTransform) {
sender.transform = new RTCRtpScriptTransform(worker, {operation: 'encode'});
return;
}

const senderStreams = sender.createEncodedStreams();
// Instead of creating the transform stream here, we do a postMessage to the worker. The first
// argument is an object defined by us, the second is a list of variables that will be transferred to
Expand All @@ -116,6 +127,11 @@ function setupSenderTransform(sender) {
}

function setupReceiverTransform(receiver) {
if (window.RTCRtpScriptTransform) {
receiver.transform = new RTCRtpScriptTransform(worker, {operation: 'decode'});
return;
}

const receiverStreams = receiver.createEncodedStreams();
const {readable, writable} = receiverStreams;
worker.postMessage({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
'use strict';

// Preferring a certain codec is an expert option without GUI.
// Use VP8 by default to limit depacketization issues.
// eslint-disable-next-line prefer-const
let preferredVideoCodecMimeType = undefined;
let preferredVideoCodecMimeType = 'video/VP8';

function VideoPipe(stream, forceSend, forceReceive, handler) {
this.pc1 = new RTCPeerConnection({
Expand Down
23 changes: 18 additions & 5 deletions src/content/insertable-streams/endtoend-encryption/js/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,29 +115,42 @@ function decodeFunction(encodedFrame, controller) {
controller.enqueue(encodedFrame);
}

onmessage = async (event) => {
const {operation} = event.data;
function handleTransform(operation, readable, writable) {
if (operation === 'encode') {
const {readable, writable} = event.data;
const transformStream = new TransformStream({
transform: encodeFunction,
});
readable
.pipeThrough(transformStream)
.pipeTo(writable);
} else if (operation === 'decode') {
const {readable, writable} = event.data;
const transformStream = new TransformStream({
transform: decodeFunction,
});
readable
.pipeThrough(transformStream)
.pipeTo(writable);
} else if (operation === 'setCryptoKey') {
}
}

// Handler for messages, including transferable streams.
onmessage = (event) => {
if (event.data.operation === 'encode' || event.data.operation === 'decode') {
return handleTransform(event.data.operation, event.data.readable, event.data.writable);
}
if (event.data.operation === 'setCryptoKey') {
if (event.data.currentCryptoKey !== currentCryptoKey) {
currentKeyIdentifier++;
}
currentCryptoKey = event.data.currentCryptoKey;
useCryptoOffset = event.data.useCryptoOffset;
}
};

// Handler for RTCRtpScriptTransforms.
if (self.RTCTransformEvent) {
self.onrtctransform = (event) => {
const transformer = event.transformer;
handleTransform(transformer.options.operation, transformer.readable, transformer.writable);
};
}

0 comments on commit 80207cd

Please sign in to comment.