From bce8af16deb34ed58fd6f46ee5dbc66aba05f1e8 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Sun, 25 Sep 2022 11:16:28 +0100 Subject: [PATCH] website: add call page back (#1121) --- website/.eleventy.js | 2 +- website/copy_call.sh | 9 + website/package.json | 14 +- website/src/call/call.js | 655 ++++++++++++++++++++++++++++++ website/src/call/call.js.map | 1 + website/src/call/index.html | 52 +++ website/src/call/lz-string.min.js | 1 + website/src/call/style.css | 41 ++ website/src/call/ui.js | 125 ++++++ website/src/contact/qrcode.js | 2 +- website/web.sh | 1 - 11 files changed, 894 insertions(+), 9 deletions(-) create mode 100755 website/copy_call.sh create mode 100644 website/src/call/call.js create mode 100644 website/src/call/call.js.map create mode 100644 website/src/call/index.html create mode 100644 website/src/call/lz-string.min.js create mode 100644 website/src/call/style.css create mode 100644 website/src/call/ui.js diff --git a/website/.eleventy.js b/website/.eleventy.js index fad86990fa..5f6d1168b8 100644 --- a/website/.eleventy.js +++ b/website/.eleventy.js @@ -11,7 +11,7 @@ module.exports = function (ty) { ty.addPassthroughCopy("src/css") ty.addPassthroughCopy("src/js") ty.addPassthroughCopy("src/contact") - ty.addPassthroughCopy("src/app-demo") + ty.addPassthroughCopy("src/call") ty.addPassthroughCopy("src/blog/images") ty.addPassthroughCopy("src/images") ty.addPassthroughCopy("src/CNAME") diff --git a/website/copy_call.sh b/website/copy_call.sh new file mode 100755 index 0000000000..0b1b491fee --- /dev/null +++ b/website/copy_call.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +mkdir -p ./src/call +cp ./node_modules/@simplex-chat/webrtc/dist/call.js ./src/call/ +cp ./node_modules/@simplex-chat/webrtc/dist/call.js.map ./src/call/ +cp ./node_modules/@simplex-chat/webrtc/dist/ui.js ./src/call/ +cp ./node_modules/@simplex-chat/webrtc/dist/style.css ./src/call/ +cp ./node_modules/@simplex-chat/webrtc/dist/webcall.html ./src/call/index.html +cp ./node_modules/@simplex-chat/webrtc/dist/lz-string.min.js ./src/call/ diff --git a/website/package.json b/website/package.json index a252d1a104..a7f8d85357 100644 --- a/website/package.json +++ b/website/package.json @@ -4,24 +4,26 @@ "description": "", "main": "index.js", "scripts": { - "build": "eleventy", + "build": "npm run build:js && npm run build:eleventy && npm run build:tailwind", "start": "npx eleventy --serve", "test": "echo \"Error: no test specified\" && exit 1", - "watch-tailwind": "npx tailwindcss -i ./tailwind.css -o ./_site/css/tailwind.css --watch", - "build-tailwind": "npx tailwindcss -i ./tailwind.css -o ./_site/css/tailwind.css" + "build:js": "cp ./node_modules/qrcode/build/qrcode.js ./src/contact/ && ./copy_call.sh", + "build:eleventy": "eleventy", + "build:tailwind": "npx tailwindcss -i ./tailwind.css -o ./_site/css/tailwind.css", + "watch:tailwind": "npx tailwindcss -i ./tailwind.css -o ./_site/css/tailwind.css --watch" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@11ty/eleventy": "^1.0.1", + "@simplex-chat/webrtc": "^0.1.1", "common-tags": "^1.8.2", "fast-uri": "^2.1.0", "markdown-it-anchor": "^8.6.4", + "markdown-it-replace-link": "^1.1.0", + "qrcode": "^1.5.1", "slugify": "^1.6.5", "tailwindcss": "^3.0.24" - }, - "dependencies": { - "markdown-it-replace-link": "^1.1.0" } } diff --git a/website/src/call/call.js b/website/src/call/call.js new file mode 100644 index 0000000000..b247431f4b --- /dev/null +++ b/website/src/call/call.js @@ -0,0 +1,655 @@ +"use strict"; +// Inspired by +// https://github.com/webrtc/samples/blob/gh-pages/src/content/insertable-streams/endtoend-encryption +var CallMediaType; +(function (CallMediaType) { + CallMediaType["Audio"] = "audio"; + CallMediaType["Video"] = "video"; +})(CallMediaType || (CallMediaType = {})); +var VideoCamera; +(function (VideoCamera) { + VideoCamera["User"] = "user"; + VideoCamera["Environment"] = "environment"; +})(VideoCamera || (VideoCamera = {})); +// for debugging +// var sendMessageToNative = ({resp}: WVApiMessage) => console.log(JSON.stringify({command: resp})) +var sendMessageToNative = (msg) => console.log(JSON.stringify(msg)); +// Global object with cryptrographic/encoding functions +const callCrypto = callCryptoFunction(); +var TransformOperation; +(function (TransformOperation) { + TransformOperation["Encrypt"] = "encrypt"; + TransformOperation["Decrypt"] = "decrypt"; +})(TransformOperation || (TransformOperation = {})); +let activeCall; +const processCommand = (function () { + const defaultIceServers = [ + { urls: ["stun:stun.simplex.im:443"] }, + { urls: ["turn:turn.simplex.im:443"], username: "private", credential: "yleob6AVkiNI87hpR94Z" }, + ]; + function getCallConfig(encodedInsertableStreams, iceServers, relay) { + return { + peerConnectionConfig: { + iceServers: iceServers !== null && iceServers !== void 0 ? iceServers : defaultIceServers, + iceCandidatePoolSize: 10, + encodedInsertableStreams, + iceTransportPolicy: relay ? "relay" : "all", + }, + iceCandidates: { + delay: 3000, + extrasInterval: 2000, + extrasTimeout: 8000, + }, + }; + } + function getIceCandidates(conn, config) { + return new Promise((resolve, _) => { + let candidates = []; + let resolved = false; + let extrasInterval; + let extrasTimeout; + const delay = setTimeout(() => { + if (!resolved) { + resolveIceCandidates(); + extrasInterval = setInterval(() => { + sendIceCandidates(); + }, config.iceCandidates.extrasInterval); + extrasTimeout = setTimeout(() => { + clearInterval(extrasInterval); + sendIceCandidates(); + }, config.iceCandidates.extrasTimeout); + } + }, config.iceCandidates.delay); + conn.onicecandidate = ({ candidate: c }) => c && candidates.push(c); + conn.onicegatheringstatechange = () => { + if (conn.iceGatheringState == "complete") { + if (resolved) { + if (extrasInterval) + clearInterval(extrasInterval); + if (extrasTimeout) + clearTimeout(extrasTimeout); + sendIceCandidates(); + } + else { + resolveIceCandidates(); + } + } + }; + function resolveIceCandidates() { + if (delay) + clearTimeout(delay); + resolved = true; + const iceCandidates = serialize(candidates); + candidates = []; + resolve(iceCandidates); + } + function sendIceCandidates() { + if (candidates.length === 0) + return; + const iceCandidates = serialize(candidates); + candidates = []; + sendMessageToNative({ resp: { type: "ice", iceCandidates } }); + } + }); + } + async function initializeCall(config, mediaType, aesKey, useWorker) { + const pc = new RTCPeerConnection(config.peerConnectionConfig); + const remoteStream = new MediaStream(); + const localCamera = VideoCamera.User; + const localStream = await getLocalMediaStream(mediaType, localCamera); + const iceCandidates = getIceCandidates(pc, config); + const call = { connection: pc, iceCandidates, localMedia: mediaType, localCamera, localStream, remoteStream, aesKey, useWorker }; + await setupMediaStreams(call); + pc.addEventListener("connectionstatechange", connectionStateChange); + return call; + async function connectionStateChange() { + sendMessageToNative({ + resp: { + type: "connection", + state: { + connectionState: pc.connectionState, + iceConnectionState: pc.iceConnectionState, + iceGatheringState: pc.iceGatheringState, + signalingState: pc.signalingState, + }, + }, + }); + if (pc.connectionState == "disconnected" || pc.connectionState == "failed") { + pc.removeEventListener("connectionstatechange", connectionStateChange); + if (activeCall) { + setTimeout(() => sendMessageToNative({ resp: { type: "ended" } }), 0); + } + endCall(); + } + else if (pc.connectionState == "connected") { + const stats = (await pc.getStats()); + for (const stat of stats.values()) { + const { type, state } = stat; + if (type === "candidate-pair" && state === "succeeded") { + const iceCandidatePair = stat; + const resp = { + type: "connected", + connectionInfo: { + iceCandidatePair, + localCandidate: stats.get(iceCandidatePair.localCandidateId), + remoteCandidate: stats.get(iceCandidatePair.remoteCandidateId), + }, + }; + setTimeout(() => sendMessageToNative({ resp }), 500); + break; + } + } + } + } + } + function serialize(x) { + return LZString.compressToBase64(JSON.stringify(x)); + } + function parse(s) { + return JSON.parse(LZString.decompressFromBase64(s)); + } + async function processCommand(body) { + const { corrId, command } = body; + const pc = activeCall === null || activeCall === void 0 ? void 0 : activeCall.connection; + let resp; + try { + switch (command.type) { + case "capabilities": + console.log("starting outgoing call - capabilities"); + if (activeCall) + endCall(); + // This request for local media stream is made to prompt for camera/mic permissions on call start + if (command.media) + await getLocalMediaStream(command.media, VideoCamera.User); + const encryption = supportsInsertableStreams(command.useWorker); + resp = { type: "capabilities", capabilities: { encryption } }; + break; + case "start": { + console.log("starting incoming call - create webrtc session"); + if (activeCall) + endCall(); + const { media, useWorker, iceServers, relay } = command; + const encryption = supportsInsertableStreams(useWorker); + const aesKey = encryption ? command.aesKey : undefined; + activeCall = await initializeCall(getCallConfig(encryption && !!aesKey, iceServers, relay), media, aesKey, useWorker); + const pc = activeCall.connection; + const offer = await pc.createOffer(); + await pc.setLocalDescription(offer); + // for debugging, returning the command for callee to use + // resp = { + // type: "offer", + // offer: serialize(offer), + // iceCandidates: await activeCall.iceCandidates, + // capabilities: {encryption}, + // media, + // iceServers, + // relay, + // aesKey, + // useWorker, + // } + resp = { + type: "offer", + offer: serialize(offer), + iceCandidates: await activeCall.iceCandidates, + capabilities: { encryption }, + }; + break; + } + case "offer": + if (activeCall) { + resp = { type: "error", message: "accept: call already started" }; + } + else if (!supportsInsertableStreams(command.useWorker) && command.aesKey) { + resp = { type: "error", message: "accept: encryption is not supported" }; + } + else { + const offer = parse(command.offer); + const remoteIceCandidates = parse(command.iceCandidates); + const { media, aesKey, useWorker, iceServers, relay } = command; + activeCall = await initializeCall(getCallConfig(!!aesKey, iceServers, relay), media, aesKey, useWorker); + const pc = activeCall.connection; + await pc.setRemoteDescription(new RTCSessionDescription(offer)); + const answer = await pc.createAnswer(); + await pc.setLocalDescription(answer); + addIceCandidates(pc, remoteIceCandidates); + // same as command for caller to use + resp = { + type: "answer", + answer: serialize(answer), + iceCandidates: await activeCall.iceCandidates, + }; + } + break; + case "answer": + if (!pc) { + resp = { type: "error", message: "answer: call not started" }; + } + else if (!pc.localDescription) { + resp = { type: "error", message: "answer: local description is not set" }; + } + else if (pc.currentRemoteDescription) { + resp = { type: "error", message: "answer: remote description already set" }; + } + else { + const answer = parse(command.answer); + const remoteIceCandidates = parse(command.iceCandidates); + await pc.setRemoteDescription(new RTCSessionDescription(answer)); + addIceCandidates(pc, remoteIceCandidates); + resp = { type: "ok" }; + } + break; + case "ice": + if (pc) { + const remoteIceCandidates = parse(command.iceCandidates); + addIceCandidates(pc, remoteIceCandidates); + resp = { type: "ok" }; + } + else { + resp = { type: "error", message: "ice: call not started" }; + } + break; + case "media": + if (!activeCall) { + resp = { type: "error", message: "media: call not started" }; + } + else if (activeCall.localMedia == CallMediaType.Audio && command.media == CallMediaType.Video) { + resp = { type: "error", message: "media: no video" }; + } + else { + enableMedia(activeCall.localStream, command.media, command.enable); + resp = { type: "ok" }; + } + break; + case "camera": + if (!activeCall || !pc) { + resp = { type: "error", message: "camera: call not started" }; + } + else { + await replaceMedia(activeCall, command.camera); + resp = { type: "ok" }; + } + break; + case "end": + endCall(); + resp = { type: "ok" }; + break; + default: + resp = { type: "error", message: "unknown command" }; + break; + } + } + catch (e) { + resp = { type: "error", message: `${command.type}: ${e.message}` }; + } + const apiResp = { corrId, resp, command }; + sendMessageToNative(apiResp); + return apiResp; + } + function endCall() { + var _a; + try { + (_a = activeCall === null || activeCall === void 0 ? void 0 : activeCall.connection) === null || _a === void 0 ? void 0 : _a.close(); + } + catch (e) { + console.log(e); + } + activeCall = undefined; + resetVideoElements(); + } + function addIceCandidates(conn, iceCandidates) { + for (const c of iceCandidates) { + conn.addIceCandidate(new RTCIceCandidate(c)); + } + } + async function setupMediaStreams(call) { + const videos = getVideoElements(); + if (!videos) + throw Error("no video elements"); + await setupEncryptionWorker(call); + setupLocalStream(call); + setupRemoteStream(call); + setupCodecPreferences(call); + // setupVideoElement(videos.local) + // setupVideoElement(videos.remote) + videos.local.srcObject = call.localStream; + videos.remote.srcObject = call.remoteStream; + } + async function setupEncryptionWorker(call) { + if (call.aesKey) { + if (!call.key) + call.key = await callCrypto.decodeAesKey(call.aesKey); + if (call.useWorker && !call.worker) { + const workerCode = `const callCrypto = (${callCryptoFunction.toString()})(); (${workerFunction.toString()})()`; + call.worker = new Worker(URL.createObjectURL(new Blob([workerCode], { type: "text/javascript" }))); + call.worker.onerror = ({ error, filename, lineno, message }) => console.log(JSON.stringify({ error, filename, lineno, message })); + call.worker.onmessage = ({ data }) => console.log(JSON.stringify({ message: data })); + } + } + } + function setupLocalStream(call) { + const videos = getVideoElements(); + if (!videos) + throw Error("no video elements"); + const pc = call.connection; + let { localStream } = call; + for (const track of localStream.getTracks()) { + pc.addTrack(track, localStream); + } + if (call.aesKey && call.key) { + console.log("set up encryption for sending"); + for (const sender of pc.getSenders()) { + setupPeerTransform(TransformOperation.Encrypt, sender, call.worker, call.aesKey, call.key); + } + } + } + function setupRemoteStream(call) { + // Pull tracks from remote stream as they arrive add them to remoteStream video + const pc = call.connection; + pc.ontrack = (event) => { + try { + if (call.aesKey && call.key) { + console.log("set up decryption for receiving"); + setupPeerTransform(TransformOperation.Decrypt, event.receiver, call.worker, call.aesKey, call.key); + } + for (const stream of event.streams) { + for (const track of stream.getTracks()) { + call.remoteStream.addTrack(track); + } + } + console.log(`ontrack success`); + } + catch (e) { + console.log(`ontrack error: ${e.message}`); + } + }; + } + function setupCodecPreferences(call) { + // We assume VP8 encoding in the decode/encode stages to get the initial + // bytes to pass as plaintext so we enforce that here. + // VP8 is supported by all supports of webrtc. + // Use of VP8 by default may also reduce depacketisation issues. + // We do not encrypt the first couple of bytes of the payload so that the + // video elements can work by determining video keyframes and the opus mode + // being used. This appears to be necessary for any video feed at all. + // For VP8 this is the content described in + // https://tools.ietf.org/html/rfc6386#section-9.1 + // which is 10 bytes for key frames and 3 bytes for delta frames. + // For opus (where encodedFrame.type is not set) this is the TOC byte from + // https://tools.ietf.org/html/rfc6716#section-3.1 + var _a; + const capabilities = RTCRtpSender.getCapabilities("video"); + if (capabilities) { + const { codecs } = capabilities; + const selectedCodecIndex = codecs.findIndex((c) => c.mimeType === "video/VP8"); + const selectedCodec = codecs[selectedCodecIndex]; + codecs.splice(selectedCodecIndex, 1); + codecs.unshift(selectedCodec); + for (const t of call.connection.getTransceivers()) { + if (((_a = t.sender.track) === null || _a === void 0 ? void 0 : _a.kind) === "video") { + t.setCodecPreferences(codecs); + } + } + } + } + async function replaceMedia(call, camera) { + const videos = getVideoElements(); + if (!videos) + throw Error("no video elements"); + const pc = call.connection; + for (const t of call.localStream.getTracks()) + t.stop(); + call.localCamera = camera; + const localStream = await getLocalMediaStream(call.localMedia, camera); + replaceTracks(pc, localStream.getVideoTracks()); + replaceTracks(pc, localStream.getAudioTracks()); + call.localStream = localStream; + videos.local.srcObject = localStream; + } + function replaceTracks(pc, tracks) { + if (!tracks.length) + return; + const sender = pc.getSenders().find((s) => { var _a; return ((_a = s.track) === null || _a === void 0 ? void 0 : _a.kind) === tracks[0].kind; }); + if (sender) + for (const t of tracks) + sender.replaceTrack(t); + } + function setupPeerTransform(operation, peer, worker, aesKey, key) { + if (worker && "RTCRtpScriptTransform" in window) { + console.log(`${operation} with worker & RTCRtpScriptTransform`); + peer.transform = new RTCRtpScriptTransform(worker, { operation, aesKey }); + } + else if ("createEncodedStreams" in peer) { + const { readable, writable } = peer.createEncodedStreams(); + if (worker) { + console.log(`${operation} with worker`); + worker.postMessage({ operation, readable, writable, aesKey }, [readable, writable]); + } + else { + console.log(`${operation} without worker`); + const transform = callCrypto.transformFrame[operation](key); + readable.pipeThrough(new TransformStream({ transform })).pipeTo(writable); + } + } + else { + console.log(`no ${operation}`); + } + } + function getLocalMediaStream(mediaType, facingMode) { + const constraints = callMediaConstraints(mediaType, facingMode); + return navigator.mediaDevices.getUserMedia(constraints); + } + function callMediaConstraints(mediaType, facingMode) { + switch (mediaType) { + case CallMediaType.Audio: + return { audio: true, video: false }; + case CallMediaType.Video: + return { + audio: true, + video: { + frameRate: 24, + width: { + min: 480, + ideal: 720, + max: 1280, + }, + aspectRatio: 1.33, + facingMode, + }, + }; + } + } + function supportsInsertableStreams(useWorker) { + return (("createEncodedStreams" in RTCRtpSender.prototype && "createEncodedStreams" in RTCRtpReceiver.prototype) || + (!!useWorker && "RTCRtpScriptTransform" in window)); + } + function resetVideoElements() { + const videos = getVideoElements(); + if (!videos) + return; + videos.local.srcObject = null; + videos.remote.srcObject = null; + } + function getVideoElements() { + const local = document.getElementById("local-video-stream"); + const remote = document.getElementById("remote-video-stream"); + if (!(local && remote && local instanceof HTMLMediaElement && remote instanceof HTMLMediaElement)) + return; + return { local, remote }; + } + // function setupVideoElement(video: HTMLElement) { + // // TODO use display: none + // video.style.opacity = "0" + // video.onplaying = () => { + // video.style.opacity = "1" + // } + // } + function enableMedia(s, media, enable) { + const tracks = media == CallMediaType.Video ? s.getVideoTracks() : s.getAudioTracks(); + for (const t of tracks) + t.enabled = enable; + } + return processCommand; +})(); +// Cryptography function - it is loaded both in the main window and in worker context (if the worker is used) +function callCryptoFunction() { + const initialPlainTextRequired = { + key: 10, + delta: 3, + empty: 1, + }; + const IV_LENGTH = 12; + function encryptFrame(key) { + return async (frame, controller) => { + const data = new Uint8Array(frame.data); + const n = initialPlainTextRequired[frame.type] || 1; + const iv = randomIV(); + const initial = data.subarray(0, n); + const plaintext = data.subarray(n, data.byteLength); + try { + const ciphertext = plaintext.length + ? new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv: iv.buffer }, key, plaintext)) + : new Uint8Array(0); + frame.data = concatN(initial, ciphertext, iv).buffer; + controller.enqueue(frame); + } + catch (e) { + console.log(`encryption error ${e}`); + throw e; + } + }; + } + function decryptFrame(key) { + return async (frame, controller) => { + const data = new Uint8Array(frame.data); + const n = initialPlainTextRequired[frame.type] || 1; + const initial = data.subarray(0, n); + const ciphertext = data.subarray(n, data.byteLength - IV_LENGTH); + const iv = data.subarray(data.byteLength - IV_LENGTH, data.byteLength); + try { + const plaintext = ciphertext.length + ? new Uint8Array(await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ciphertext)) + : new Uint8Array(0); + frame.data = concatN(initial, plaintext).buffer; + controller.enqueue(frame); + } + catch (e) { + console.log(`decryption error ${e}`); + throw e; + } + }; + } + function decodeAesKey(aesKey) { + const keyData = callCrypto.decodeBase64url(callCrypto.encodeAscii(aesKey)); + return crypto.subtle.importKey("raw", keyData, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]); + } + function concatN(...bs) { + const a = new Uint8Array(bs.reduce((size, b) => size + b.byteLength, 0)); + bs.reduce((offset, b) => { + a.set(b, offset); + return offset + b.byteLength; + }, 0); + return a; + } + function randomIV() { + return crypto.getRandomValues(new Uint8Array(IV_LENGTH)); + } + const base64urlChars = new Uint8Array("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split("").map((c) => c.charCodeAt(0))); + const base64urlLookup = new Array(256); + base64urlChars.forEach((c, i) => (base64urlLookup[c] = i)); + const char_equal = "=".charCodeAt(0); + function encodeAscii(s) { + const a = new Uint8Array(s.length); + let i = s.length; + while (i--) + a[i] = s.charCodeAt(i); + return a; + } + function decodeAscii(a) { + let s = ""; + for (let i = 0; i < a.length; i++) + s += String.fromCharCode(a[i]); + return s; + } + function encodeBase64url(a) { + const len = a.length; + const b64len = Math.ceil(len / 3) * 4; + const b64 = new Uint8Array(b64len); + let j = 0; + for (let i = 0; i < len; i += 3) { + b64[j++] = base64urlChars[a[i] >> 2]; + b64[j++] = base64urlChars[((a[i] & 3) << 4) | (a[i + 1] >> 4)]; + b64[j++] = base64urlChars[((a[i + 1] & 15) << 2) | (a[i + 2] >> 6)]; + b64[j++] = base64urlChars[a[i + 2] & 63]; + } + if (len % 3) + b64[b64len - 1] = char_equal; + if (len % 3 === 1) + b64[b64len - 2] = char_equal; + return b64; + } + function decodeBase64url(b64) { + let len = b64.length; + if (len % 4) + return; + let bLen = (len * 3) / 4; + if (b64[len - 1] === char_equal) { + len--; + bLen--; + if (b64[len - 1] === char_equal) { + len--; + bLen--; + } + } + const bytes = new Uint8Array(bLen); + let i = 0; + let pos = 0; + while (i < len) { + const enc1 = base64urlLookup[b64[i++]]; + const enc2 = i < len ? base64urlLookup[b64[i++]] : 0; + const enc3 = i < len ? base64urlLookup[b64[i++]] : 0; + const enc4 = i < len ? base64urlLookup[b64[i++]] : 0; + if (enc1 === undefined || enc2 === undefined || enc3 === undefined || enc4 === undefined) + return; + bytes[pos++] = (enc1 << 2) | (enc2 >> 4); + bytes[pos++] = ((enc2 & 15) << 4) | (enc3 >> 2); + bytes[pos++] = ((enc3 & 3) << 6) | (enc4 & 63); + } + return bytes; + } + return { + transformFrame: { encrypt: encryptFrame, decrypt: decryptFrame }, + decodeAesKey, + encodeAscii, + decodeAscii, + encodeBase64url, + decodeBase64url, + }; +} +// If the worker is used for decryption, this function code (as string) is used to load the worker via Blob +// We have to use worker optionally, as it crashes in Android web view, regardless of how it is loaded +function workerFunction() { + // encryption with createEncodedStreams support + self.addEventListener("message", async ({ data }) => { + await setupTransform(data); + }); + // encryption using RTCRtpScriptTransform. + if ("RTCTransformEvent" in self) { + self.addEventListener("rtctransform", async ({ transformer }) => { + try { + const { operation, aesKey } = transformer.options; + const { readable, writable } = transformer; + await setupTransform({ operation, aesKey, readable, writable }); + self.postMessage({ result: "setupTransform success" }); + } + catch (e) { + self.postMessage({ message: `setupTransform error: ${e.message}` }); + } + }); + } + async function setupTransform({ operation, aesKey, readable, writable }) { + const key = await callCrypto.decodeAesKey(aesKey); + const transform = callCrypto.transformFrame[operation](key); + readable.pipeThrough(new TransformStream({ transform })).pipeTo(writable); + } +} +//# sourceMappingURL=call.js.map \ No newline at end of file diff --git a/website/src/call/call.js.map b/website/src/call/call.js.map new file mode 100644 index 0000000000..b6952eb495 --- /dev/null +++ b/website/src/call/call.js.map @@ -0,0 +1 @@ +{"version":3,"file":"call.js","sourceRoot":"","sources":["../src/call.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/website/src/call/index.html b/website/src/call/index.html new file mode 100644 index 0000000000..1e1fad9e12 --- /dev/null +++ b/website/src/call/index.html @@ -0,0 +1,52 @@ + + +
+ + + + + + + +