@norskvideo/norsk-studio 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -0
- package/bin/info.ts.template +23 -0
- package/bin/studio-bundle +23 -0
- package/bin/studio-editor +3 -0
- package/bin/studio-runner +3 -0
- package/bin/studio-wrap-infos +44 -0
- package/lib/client/comms.d.ts +26 -0
- package/lib/client/comms.js +114 -0
- package/lib/client/comms.js.map +1 -0
- package/lib/client/componentevents.d.ts +12 -0
- package/lib/client/componentevents.js +41 -0
- package/lib/client/componentevents.js.map +1 -0
- package/lib/client/console.d.ts +19 -0
- package/lib/client/console.js +42 -0
- package/lib/client/console.js.map +1 -0
- package/lib/client/controls.d.ts +23 -0
- package/lib/client/controls.js +80 -0
- package/lib/client/controls.js.map +1 -0
- package/lib/client/creator.d.ts +45 -0
- package/lib/client/creator.js +276 -0
- package/lib/client/creator.js.map +1 -0
- package/lib/client/jsx/connection-editor.d.ts +11 -0
- package/lib/client/jsx/connection-editor.js +198 -0
- package/lib/client/jsx/connection-editor.js.map +1 -0
- package/lib/client/jsx/connection.d.ts +7 -0
- package/lib/client/jsx/connection.js +33 -0
- package/lib/client/jsx/connection.js.map +1 -0
- package/lib/client/jsx/console-log.d.ts +11 -0
- package/lib/client/jsx/console-log.js +17 -0
- package/lib/client/jsx/console-log.js.map +1 -0
- package/lib/client/jsx/console.d.ts +20 -0
- package/lib/client/jsx/console.js +30 -0
- package/lib/client/jsx/console.js.map +1 -0
- package/lib/client/jsx/node-editor.d.ts +23 -0
- package/lib/client/jsx/node-editor.js +442 -0
- package/lib/client/jsx/node-editor.js.map +1 -0
- package/lib/client/jsx/node.d.ts +25 -0
- package/lib/client/jsx/node.js +244 -0
- package/lib/client/jsx/node.js.map +1 -0
- package/lib/client/jsx/selected-connection.d.ts +21 -0
- package/lib/client/jsx/selected-connection.js +110 -0
- package/lib/client/jsx/selected-connection.js.map +1 -0
- package/lib/client/jsx/selected-node.d.ts +24 -0
- package/lib/client/jsx/selected-node.js +75 -0
- package/lib/client/jsx/selected-node.js.map +1 -0
- package/lib/client/jsx/selected.d.ts +24 -0
- package/lib/client/jsx/selected.js +15 -0
- package/lib/client/jsx/selected.js.map +1 -0
- package/lib/client/jsx/selectfilename.d.ts +7 -0
- package/lib/client/jsx/selectfilename.js +17 -0
- package/lib/client/jsx/selectfilename.js.map +1 -0
- package/lib/client/jsx/toolbox.d.ts +14 -0
- package/lib/client/jsx/toolbox.js +45 -0
- package/lib/client/jsx/toolbox.js.map +1 -0
- package/lib/client/library.d.ts +12 -0
- package/lib/client/library.js +53 -0
- package/lib/client/library.js.map +1 -0
- package/lib/client/modal.d.ts +21 -0
- package/lib/client/modal.js +34 -0
- package/lib/client/modal.js.map +1 -0
- package/lib/client/rete/connection.d.ts +20 -0
- package/lib/client/rete/connection.js +27 -0
- package/lib/client/rete/connection.js.map +1 -0
- package/lib/client/rete/node.d.ts +28 -0
- package/lib/client/rete/node.js +78 -0
- package/lib/client/rete/node.js.map +1 -0
- package/lib/client/rete/selector.d.ts +10 -0
- package/lib/client/rete/selector.js +22 -0
- package/lib/client/rete/selector.js.map +1 -0
- package/lib/client/rete.d.ts +81 -0
- package/lib/client/rete.js +384 -0
- package/lib/client/rete.js.map +1 -0
- package/lib/client/session-view.d.ts +7 -0
- package/lib/client/session-view.js +132 -0
- package/lib/client/session-view.js.map +1 -0
- package/lib/client/session.d.ts +70 -0
- package/lib/client/session.js +185 -0
- package/lib/client/session.js.map +1 -0
- package/lib/client/tools.d.ts +22 -0
- package/lib/client/tools.js +311 -0
- package/lib/client/tools.js.map +1 -0
- package/lib/extension/base-nodes.d.ts +55 -0
- package/lib/extension/base-nodes.js +120 -0
- package/lib/extension/base-nodes.js.map +1 -0
- package/lib/extension/built-ins.d.ts +4 -0
- package/lib/extension/built-ins.js +52 -0
- package/lib/extension/built-ins.js.map +1 -0
- package/lib/extension/client-system.d.ts +5 -0
- package/lib/extension/client-system.js +3 -0
- package/lib/extension/client-system.js.map +1 -0
- package/lib/extension/client-types.d.ts +245 -0
- package/lib/extension/client-types.js +87 -0
- package/lib/extension/client-types.js.map +1 -0
- package/lib/extension/common.d.ts +34 -0
- package/lib/extension/common.js +45 -0
- package/lib/extension/common.js.map +1 -0
- package/lib/extension/registration.d.ts +7 -0
- package/lib/extension/registration.js +62 -0
- package/lib/extension/registration.js.map +1 -0
- package/lib/extension/runtime-system.d.ts +9 -0
- package/lib/extension/runtime-system.js +3 -0
- package/lib/extension/runtime-system.js.map +1 -0
- package/lib/extension/runtime-types.d.ts +91 -0
- package/lib/extension/runtime-types.js +318 -0
- package/lib/extension/runtime-types.js.map +1 -0
- package/lib/extension/validation.d.ts +16 -0
- package/lib/extension/validation.js +50 -0
- package/lib/extension/validation.js.map +1 -0
- package/lib/library/test.d.ts +2 -0
- package/lib/library/test.js +11 -0
- package/lib/library/test.js.map +1 -0
- package/lib/runtime/document.d.ts +62 -0
- package/lib/runtime/document.js +322 -0
- package/lib/runtime/document.js.map +1 -0
- package/lib/runtime/execution.d.ts +48 -0
- package/lib/runtime/execution.js +327 -0
- package/lib/runtime/execution.js.map +1 -0
- package/lib/runtime/norsk-comms.d.ts +24 -0
- package/lib/runtime/norsk-comms.js +71 -0
- package/lib/runtime/norsk-comms.js.map +1 -0
- package/lib/runtime/system.d.ts +30 -0
- package/lib/runtime/system.js +83 -0
- package/lib/runtime/system.js.map +1 -0
- package/lib/server/config.d.ts +19 -0
- package/lib/server/config.js +26 -0
- package/lib/server/config.js.map +1 -0
- package/lib/server/index.d.ts +1 -0
- package/lib/server/index.js +310 -0
- package/lib/server/index.js.map +1 -0
- package/lib/server/logging.d.ts +6 -0
- package/lib/server/logging.js +96 -0
- package/lib/server/logging.js.map +1 -0
- package/lib/server/medialive.d.ts +1 -0
- package/lib/server/medialive.js +34 -0
- package/lib/server/medialive.js.map +1 -0
- package/lib/server/runner.d.ts +1 -0
- package/lib/server/runner.js +137 -0
- package/lib/server/runner.js.map +1 -0
- package/lib/server/session-registration.d.ts +5 -0
- package/lib/server/session-registration.js +18 -0
- package/lib/server/session-registration.js.map +1 -0
- package/lib/server/session.d.ts +117 -0
- package/lib/server/session.js +364 -0
- package/lib/server/session.js.map +1 -0
- package/lib/shared/client-msg.d.ts +13 -0
- package/lib/shared/client-msg.js +3 -0
- package/lib/shared/client-msg.js.map +1 -0
- package/lib/shared/config.d.ts +7 -0
- package/lib/shared/config.js +60 -0
- package/lib/shared/config.js.map +1 -0
- package/lib/shared/document.d.ts +164 -0
- package/lib/shared/document.js +496 -0
- package/lib/shared/document.js.map +1 -0
- package/lib/shared/names.d.ts +3 -0
- package/lib/shared/names.js +8 -0
- package/lib/shared/names.js.map +1 -0
- package/lib/shared/norsk.d.ts +21 -0
- package/lib/shared/norsk.js +3 -0
- package/lib/shared/norsk.js.map +1 -0
- package/lib/shared/server-msg.d.ts +69 -0
- package/lib/shared/server-msg.js +3 -0
- package/lib/shared/server-msg.js.map +1 -0
- package/lib/shared/util.d.ts +7 -0
- package/lib/shared/util.js +63 -0
- package/lib/shared/util.js.map +1 -0
- package/lib/test/_util/builder.d.ts +46 -0
- package/lib/test/_util/builder.js +200 -0
- package/lib/test/_util/builder.js.map +1 -0
- package/lib/test/_util/callback_app.d.ts +13 -0
- package/lib/test/_util/callback_app.js +25 -0
- package/lib/test/_util/callback_app.js.map +1 -0
- package/lib/test/_util/driver.d.ts +16 -0
- package/lib/test/_util/driver.js +89 -0
- package/lib/test/_util/driver.js.map +1 -0
- package/lib/test/_util/fake-norsk.d.ts +14 -0
- package/lib/test/_util/fake-norsk.js +19 -0
- package/lib/test/_util/fake-norsk.js.map +1 -0
- package/lib/test/_util/ffmpeg.d.ts +80 -0
- package/lib/test/_util/ffmpeg.js +266 -0
- package/lib/test/_util/ffmpeg.js.map +1 -0
- package/lib/test/_util/manual-driver.d.ts +42 -0
- package/lib/test/_util/manual-driver.js +206 -0
- package/lib/test/_util/manual-driver.js.map +1 -0
- package/lib/test/_util/runtime.d.ts +81 -0
- package/lib/test/_util/runtime.js +194 -0
- package/lib/test/_util/runtime.js.map +1 -0
- package/lib/test/_util/server.d.ts +8 -0
- package/lib/test/_util/server.js +33 -0
- package/lib/test/_util/server.js.map +1 -0
- package/lib/test/_util/sinks.d.ts +35 -0
- package/lib/test/_util/sinks.js +200 -0
- package/lib/test/_util/sinks.js.map +1 -0
- package/lib/test/_util/sources.d.ts +18 -0
- package/lib/test/_util/sources.js +113 -0
- package/lib/test/_util/sources.js.map +1 -0
- package/lib/test/_util/test-infos-views.d.ts +9 -0
- package/lib/test/_util/test-infos-views.js +46 -0
- package/lib/test/_util/test-infos-views.js.map +1 -0
- package/lib/test/_util/test-infos.d.ts +44 -0
- package/lib/test/_util/test-infos.js +202 -0
- package/lib/test/_util/test-infos.js.map +1 -0
- package/lib/test/client-designview.d.ts +1 -0
- package/lib/test/client-designview.js +258 -0
- package/lib/test/client-designview.js.map +1 -0
- package/lib/test/client-liveview.d.ts +1 -0
- package/lib/test/client-liveview.js +413 -0
- package/lib/test/client-liveview.js.map +1 -0
- package/lib/test/client-session.d.ts +1 -0
- package/lib/test/client-session.js +205 -0
- package/lib/test/client-session.js.map +1 -0
- package/lib/test/client-ui.d.ts +1 -0
- package/lib/test/client-ui.js +74 -0
- package/lib/test/client-ui.js.map +1 -0
- package/lib/test/document-execution.d.ts +1 -0
- package/lib/test/document-execution.js +162 -0
- package/lib/test/document-execution.js.map +1 -0
- package/lib/test/document-loading.d.ts +1 -0
- package/lib/test/document-loading.js +420 -0
- package/lib/test/document-loading.js.map +1 -0
- package/lib/test/runtime-comms.d.ts +1 -0
- package/lib/test/runtime-comms.js +321 -0
- package/lib/test/runtime-comms.js.map +1 -0
- package/lib/test/subscriptions.d.ts +1 -0
- package/lib/test/subscriptions.js +334 -0
- package/lib/test/subscriptions.js.map +1 -0
- package/package.json +112 -0
- package/static/98_slides.html +61 -0
- package/static/Norsk-Favicon-150x150.png +0 -0
- package/static/Norsk-Favicon.png +0 -0
- package/static/Norsk-Logo-Dark-Background.png +0 -0
- package/static/Norsk.png +0 -0
- package/static/ShortStack.woff2 +0 -0
- package/static/bonnie-green.png +0 -0
- package/static/button.svg +67 -0
- package/static/doodle.css +174 -0
- package/static/flowbite.min.css +1 -0
- package/static/flowbite.min.js +2 -0
- package/static/font.css +20 -0
- package/static/jese-leos.png +0 -0
- package/static/joseph-mcfall.png +0 -0
- package/static/michael-gough.png +0 -0
- package/static/news-embedded.html +106 -0
- package/static/overlay-score.html +210 -0
- package/static/overlay-ui.html +918 -0
- package/static/react-dom.development.js +29869 -0
- package/static/react.development.js +3342 -0
- package/static/robert-brown.png +0 -0
- package/static/roberta-casas.png +0 -0
- package/static/style-dark.css +2467 -0
- package/static/style.css +7252 -0
- package/static/tailwind.css +31 -0
- package/static/team1.png +0 -0
- package/static/team2.png +0 -0
- package/static/videoFrame.html +73 -0
- package/static/webrtc.js +430 -0
- package/tailwind-theme.js +66 -0
- package/tailwind.config.js +11 -0
- package/ui/bypass-esbuild.js +24 -0
- package/ui/index.html +189 -0
- package/ui/index.js +229180 -0
- package/ui/studio.css +31 -0
- package/ui/test.html +95 -0
- package/ui/view.html +23 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
.node-editor-label {
|
|
6
|
+
@apply block mb-0.5 text-sm font-medium text-gray-900 dark:text-white
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.node-editor-text-input {
|
|
10
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded focus:ring-blue-500 focus:border-blue-500 block w-full p-1 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 focus:outline-none
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.node-editor-numeric-input {
|
|
14
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded focus:ring-blue-500 focus:border-blue-500 block w-full p-0.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.node-editor-select-input {
|
|
18
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded focus:ring-blue-500 focus:border-blue-500 block w-full p-1 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.node-editor-helper-text {
|
|
22
|
+
@apply mt-0.5 mb-0.5 text-xs text-gray-500 dark:text-gray-400
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.output-socket {
|
|
26
|
+
display: inline-block;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.input-socket {
|
|
30
|
+
display: inline-block;
|
|
31
|
+
}
|
package/static/team1.png
ADDED
|
Binary file
|
package/static/team2.png
ADDED
|
Binary file
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Presenter Video and Slide Presentation</title>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
display: flex;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
align-items: center;
|
|
15
|
+
min-height: 100vh;
|
|
16
|
+
background-color: transparent;
|
|
17
|
+
font-family: Arial, sans-serif;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
.white-border {
|
|
22
|
+
position: absolute;
|
|
23
|
+
margin: 2em;
|
|
24
|
+
/* Set transparent div to 25% of the width of the parent container */
|
|
25
|
+
height: 384px;
|
|
26
|
+
width: 216px;
|
|
27
|
+
top: 1em;
|
|
28
|
+
left: 1em;
|
|
29
|
+
bottom: 1em;
|
|
30
|
+
right: 1em;
|
|
31
|
+
/* Occupy the entire height of the video container */
|
|
32
|
+
border-radius: 20px;
|
|
33
|
+
background-color: transparent;
|
|
34
|
+
outline: 2em solid red
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.video-container {
|
|
38
|
+
/* position: absolute; */
|
|
39
|
+
width: 216px;
|
|
40
|
+
height: 384px;
|
|
41
|
+
top: 1em;
|
|
42
|
+
left: 1em;
|
|
43
|
+
bottom: 1em;
|
|
44
|
+
right: 1em;
|
|
45
|
+
|
|
46
|
+
border-radius: 20px;
|
|
47
|
+
background-color: rgba(0, 0, 0, 0);
|
|
48
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.frame {
|
|
52
|
+
width: 216px;
|
|
53
|
+
height: 384px;
|
|
54
|
+
/* width: 242px;
|
|
55
|
+
height: 420px; */
|
|
56
|
+
border: 3px solid #ccc;
|
|
57
|
+
background: #eee;
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 15px 10px;
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
62
|
+
</head>
|
|
63
|
+
|
|
64
|
+
<body>
|
|
65
|
+
<div>
|
|
66
|
+
<div class="frame">
|
|
67
|
+
<div class="video-container">
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</body>
|
|
72
|
+
|
|
73
|
+
</html>
|
package/static/webrtc.js
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
5
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// node_modules/@norskvideo/webrtc-client/lib/cjs/webrtc.js
|
|
9
|
+
var require_webrtc = __commonJS({
|
|
10
|
+
"node_modules/@norskvideo/webrtc-client/lib/cjs/webrtc.js"(exports) {
|
|
11
|
+
"use strict";
|
|
12
|
+
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) {
|
|
14
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
15
|
+
resolve(value);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
19
|
+
function fulfilled(value) {
|
|
20
|
+
try {
|
|
21
|
+
step(generator.next(value));
|
|
22
|
+
} catch (e) {
|
|
23
|
+
reject(e);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function rejected(value) {
|
|
27
|
+
try {
|
|
28
|
+
step(generator["throw"](value));
|
|
29
|
+
} catch (e) {
|
|
30
|
+
reject(e);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function step(result) {
|
|
34
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
35
|
+
}
|
|
36
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.DuplexClient = exports.WhipClient = exports.WhepClient = exports.WebRtcClient = void 0;
|
|
41
|
+
var WebRtcClient = class extends EventTarget {
|
|
42
|
+
constructor(config) {
|
|
43
|
+
super();
|
|
44
|
+
this.cachedCandidates = [];
|
|
45
|
+
this.client = new RTCPeerConnection({
|
|
46
|
+
// Can set STUN/TURN servers directly here if required, but the server will return the configured/requested servers
|
|
47
|
+
iceServers: config.iceServers
|
|
48
|
+
});
|
|
49
|
+
if (!config) {
|
|
50
|
+
throw new Error("Config is required");
|
|
51
|
+
}
|
|
52
|
+
if (!config.url) {
|
|
53
|
+
throw new Error("Must specify endpoint url in config");
|
|
54
|
+
}
|
|
55
|
+
this.endpointUrl = new URL(config.url, document.location.href);
|
|
56
|
+
this.client.addEventListener("icecandidate", (event) => this.handleIceCandidateFromClient(event));
|
|
57
|
+
this.client.addEventListener("iceconnectionstatechange", (event) => this.handleIceConnectionChange(event));
|
|
58
|
+
this.client.addEventListener("track", (event) => this.handleGotTrack(event));
|
|
59
|
+
}
|
|
60
|
+
handleIceCandidateFromClient(event) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
if (!event.candidate || !event.candidate.candidate) {
|
|
63
|
+
console.log("client ice candidate gathering is done", event);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (!this.sessionUrl) {
|
|
67
|
+
console.debug("received candidate before response from session create, caching", event.candidate);
|
|
68
|
+
this.cachedCandidates.push(event.candidate);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
yield this.sendCandidate(event.candidate, false);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
sendOffer() {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
const client = this.client;
|
|
77
|
+
const localOffer = yield client.createOffer();
|
|
78
|
+
console.debug("received local offer, sending to server", localOffer);
|
|
79
|
+
let response = yield fetch(this.endpointUrl, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers: {
|
|
82
|
+
"Content-Type": "application/sdp"
|
|
83
|
+
},
|
|
84
|
+
body: localOffer.sdp
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
this.onResponseError(response);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.receiveIceServers(response.headers);
|
|
91
|
+
const sessionUrl = response.headers.get("Location");
|
|
92
|
+
if (sessionUrl == null) {
|
|
93
|
+
throw new Error("Session not provided in Location header");
|
|
94
|
+
}
|
|
95
|
+
this.sessionUrl = new URL(sessionUrl, this.endpointUrl);
|
|
96
|
+
const remoteOffer = yield response.text();
|
|
97
|
+
console.log("Got response", { remoteOffer, sessionUrl });
|
|
98
|
+
yield client.setLocalDescription(localOffer);
|
|
99
|
+
const remoteResponse = yield client.setRemoteDescription({
|
|
100
|
+
type: "answer",
|
|
101
|
+
sdp: remoteOffer
|
|
102
|
+
});
|
|
103
|
+
console.log("Applied remote description", remoteResponse);
|
|
104
|
+
console.log("Peer connection state", client);
|
|
105
|
+
this.sendCachedCandidates();
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
sendCandidate(candidate, isCached) {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
if (isCached) {
|
|
111
|
+
console.log("sending cached client ice candidate", candidate);
|
|
112
|
+
} else {
|
|
113
|
+
console.log("sending client ice candidate", candidate);
|
|
114
|
+
}
|
|
115
|
+
if (!this.sessionUrl) {
|
|
116
|
+
throw new Error("Session url not set when expected");
|
|
117
|
+
}
|
|
118
|
+
yield fetch(this.sessionUrl, {
|
|
119
|
+
method: "PATCH",
|
|
120
|
+
headers: {
|
|
121
|
+
"Content-Type": "application/trickle-ice-sdpfrag"
|
|
122
|
+
},
|
|
123
|
+
body: [
|
|
124
|
+
"m=audio 9 RTP/AVP 0",
|
|
125
|
+
"a=ice-ufrag:" + candidate.usernameFragment,
|
|
126
|
+
"a=mid:" + candidate.sdpMid,
|
|
127
|
+
"a=" + candidate.candidate
|
|
128
|
+
// and the candidate itself
|
|
129
|
+
].join("\r\n")
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
sendCachedCandidates() {
|
|
134
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
+
for (const cachedCandidate of this.cachedCandidates) {
|
|
136
|
+
yield this.sendCandidate(cachedCandidate, true);
|
|
137
|
+
}
|
|
138
|
+
this.cachedCandidates = [];
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
handleIceConnectionChange(event) {
|
|
142
|
+
console.log("client ice connection change", event);
|
|
143
|
+
}
|
|
144
|
+
handleGotTrack(event) {
|
|
145
|
+
console.log("got track", event);
|
|
146
|
+
}
|
|
147
|
+
receiveIceServers(headers) {
|
|
148
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
let linkHeader = headers.get("link");
|
|
150
|
+
if (!linkHeader) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
let servers = [];
|
|
154
|
+
let links = linkHeader.split(",");
|
|
155
|
+
for (let link of links) {
|
|
156
|
+
let split = link.split(";").map((x) => x.trim());
|
|
157
|
+
if (split.some((x) => x === `rel="ice-server"`)) {
|
|
158
|
+
let urlMatch = split[0].match(/<(.+)>/);
|
|
159
|
+
if (urlMatch) {
|
|
160
|
+
let server = { urls: [urlMatch[1]] };
|
|
161
|
+
for (let f of split) {
|
|
162
|
+
let pair = f.match(/([^=]+)="([^"]+)"/);
|
|
163
|
+
if (pair) {
|
|
164
|
+
switch (pair[1]) {
|
|
165
|
+
case "username":
|
|
166
|
+
server.username = pair[2];
|
|
167
|
+
break;
|
|
168
|
+
case "credential":
|
|
169
|
+
server.credential = pair[2];
|
|
170
|
+
break;
|
|
171
|
+
case "credential-type":
|
|
172
|
+
server.credentialType = pair[2];
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
servers.push(server);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (servers.length > 0) {
|
|
182
|
+
let existingIceServers = this.client.getConfiguration().iceServers || [];
|
|
183
|
+
if (existingIceServers.length == 0) {
|
|
184
|
+
console.log("Received ICE server configuration from server, applying", { iceServers: servers });
|
|
185
|
+
this.client.setConfiguration({
|
|
186
|
+
iceServers: servers
|
|
187
|
+
});
|
|
188
|
+
} else {
|
|
189
|
+
console.log("Received ICE server configuration from server but have explicit configuration, ignoring", { existingIceServers, iceServers: servers });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
onResponseError(response) {
|
|
195
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
196
|
+
this.raise("responseerror", new CustomEvent("responseerror", { detail: response }));
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
raise(type, ev) {
|
|
200
|
+
this.dispatchEvent(ev);
|
|
201
|
+
}
|
|
202
|
+
addEventListener(type, listener, options) {
|
|
203
|
+
super.addEventListener(type, listener);
|
|
204
|
+
}
|
|
205
|
+
removeEventListener(type, listener, options) {
|
|
206
|
+
super.removeEventListener(type, listener);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
exports.WebRtcClient = WebRtcClient;
|
|
210
|
+
var WhepClient = class extends WebRtcClient {
|
|
211
|
+
constructor(config) {
|
|
212
|
+
super(config);
|
|
213
|
+
this.outputVideoTracks = [];
|
|
214
|
+
this.videoElements = [];
|
|
215
|
+
this.simulcastVideoCount = config.simulcastVideoCount || 1;
|
|
216
|
+
this.container = config.container;
|
|
217
|
+
}
|
|
218
|
+
start() {
|
|
219
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
220
|
+
const client = this.client;
|
|
221
|
+
for (let _ of Array(this.simulcastVideoCount)) {
|
|
222
|
+
client.addTransceiver("video", { "direction": "recvonly" });
|
|
223
|
+
}
|
|
224
|
+
client.addTransceiver("audio", { "direction": "recvonly" });
|
|
225
|
+
this.sendOffer();
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
handleGotTrack(ev) {
|
|
229
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
+
console.log("Got a track", ev);
|
|
231
|
+
if (ev.track.kind == "video" && ev.streams.length > 0) {
|
|
232
|
+
this.outputVideoTracks.push(ev.track);
|
|
233
|
+
}
|
|
234
|
+
if (ev.track.kind == "audio") {
|
|
235
|
+
this.outputAudioTrack = ev.track;
|
|
236
|
+
}
|
|
237
|
+
if (this.outputAudioTrack && this.outputVideoTracks.length > this.videoElements.length) {
|
|
238
|
+
for (let i = 0; i < this.outputVideoTracks.length; i++) {
|
|
239
|
+
if (this.videoElements[i])
|
|
240
|
+
continue;
|
|
241
|
+
let stream = void 0;
|
|
242
|
+
if (i == 0) {
|
|
243
|
+
stream = new MediaStream([this.outputAudioTrack, this.outputVideoTracks[i]]);
|
|
244
|
+
} else {
|
|
245
|
+
stream = new MediaStream([this.outputVideoTracks[i]]);
|
|
246
|
+
}
|
|
247
|
+
if (this.container) {
|
|
248
|
+
this.videoElements.push(createPlayerElement(stream, this.container));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
exports.WhepClient = WhepClient;
|
|
256
|
+
var WhipClient = class extends WebRtcClient {
|
|
257
|
+
constructor(config) {
|
|
258
|
+
super(config);
|
|
259
|
+
}
|
|
260
|
+
requestAccess() {
|
|
261
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
262
|
+
this.media = (yield requestAccess()) || void 0;
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
start() {
|
|
266
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
267
|
+
if (this.media === void 0) {
|
|
268
|
+
yield this.requestAccess();
|
|
269
|
+
if (!this.media) {
|
|
270
|
+
console.error("Could not access media devices");
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const client = this.client;
|
|
275
|
+
for (const track of this.media.getTracks()) {
|
|
276
|
+
console.log("Adding track", track.id);
|
|
277
|
+
client.addTrack(track);
|
|
278
|
+
}
|
|
279
|
+
yield this.sendOffer();
|
|
280
|
+
return true;
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
exports.WhipClient = WhipClient;
|
|
285
|
+
var DuplexClient = class extends WebRtcClient {
|
|
286
|
+
constructor(config) {
|
|
287
|
+
super(config);
|
|
288
|
+
this.outputVideoTracks = [];
|
|
289
|
+
this.videoElements = [];
|
|
290
|
+
this.simulcastVideoCount = config.simulcastVideoCount || 1;
|
|
291
|
+
this.container = config.container || document.getElementById("container");
|
|
292
|
+
}
|
|
293
|
+
requestAccess() {
|
|
294
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
295
|
+
this.media = (yield requestAccess()) || void 0;
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
start() {
|
|
299
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
300
|
+
if (this.media === void 0) {
|
|
301
|
+
yield this.requestAccess();
|
|
302
|
+
}
|
|
303
|
+
const client = this.client;
|
|
304
|
+
for (let _ of Array(this.simulcastVideoCount)) {
|
|
305
|
+
client.addTransceiver("video", { "direction": "recvonly" });
|
|
306
|
+
}
|
|
307
|
+
client.addTransceiver("audio", { "direction": "recvonly" });
|
|
308
|
+
if (this.media) {
|
|
309
|
+
for (const track of this.media.getTracks()) {
|
|
310
|
+
console.log("Adding track", track.id);
|
|
311
|
+
client.addTrack(track);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
this.sendOffer();
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
// This is just like WHEP I just don't want to do a mixin or whatever
|
|
318
|
+
handleGotTrack(ev) {
|
|
319
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
320
|
+
console.log("Got a track", ev);
|
|
321
|
+
if (ev.track.kind == "video" && ev.streams.length > 0) {
|
|
322
|
+
this.outputVideoTracks.push(ev.track);
|
|
323
|
+
}
|
|
324
|
+
if (ev.track.kind == "audio") {
|
|
325
|
+
this.outputAudioTrack = ev.track;
|
|
326
|
+
}
|
|
327
|
+
if (this.outputAudioTrack && this.outputVideoTracks.length > this.videoElements.length) {
|
|
328
|
+
for (let i = 0; i < this.outputVideoTracks.length; i++) {
|
|
329
|
+
if (this.videoElements[i])
|
|
330
|
+
continue;
|
|
331
|
+
let stream = void 0;
|
|
332
|
+
if (i == 0) {
|
|
333
|
+
stream = new MediaStream([this.outputAudioTrack, this.outputVideoTracks[i]]);
|
|
334
|
+
} else {
|
|
335
|
+
stream = new MediaStream([this.outputVideoTracks[i]]);
|
|
336
|
+
}
|
|
337
|
+
if (this.container) {
|
|
338
|
+
this.videoElements.push(createPlayerElement(stream, this.container));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
exports.DuplexClient = DuplexClient;
|
|
346
|
+
function requestAccess() {
|
|
347
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
348
|
+
if (!navigator.mediaDevices) {
|
|
349
|
+
console.log("Can't request user media (insecure context?)");
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
console.log("Requesting access to user media");
|
|
353
|
+
try {
|
|
354
|
+
const media = yield navigator.mediaDevices.getUserMedia({ audio: true, video: true });
|
|
355
|
+
console.debug(media);
|
|
356
|
+
return media;
|
|
357
|
+
} catch (err) {
|
|
358
|
+
console.warn("Couldn't get user media", err);
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function createPlayerElement(stream, container) {
|
|
364
|
+
var element = document.createElement("video");
|
|
365
|
+
element.controls = true;
|
|
366
|
+
container.appendChild(element);
|
|
367
|
+
element.muted = true;
|
|
368
|
+
element.autoplay = true;
|
|
369
|
+
element.srcObject = stream;
|
|
370
|
+
return element;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// workspaces/webrtc/lib/src/webrtc.js
|
|
376
|
+
var require_webrtc2 = __commonJS({
|
|
377
|
+
"workspaces/webrtc/lib/src/webrtc.js"(exports) {
|
|
378
|
+
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
379
|
+
function adopt(value) {
|
|
380
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
381
|
+
resolve(value);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
385
|
+
function fulfilled(value) {
|
|
386
|
+
try {
|
|
387
|
+
step(generator.next(value));
|
|
388
|
+
} catch (e) {
|
|
389
|
+
reject(e);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function rejected(value) {
|
|
393
|
+
try {
|
|
394
|
+
step(generator["throw"](value));
|
|
395
|
+
} catch (e) {
|
|
396
|
+
reject(e);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function step(result) {
|
|
400
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
401
|
+
}
|
|
402
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
406
|
+
var webrtc_client_1 = require_webrtc();
|
|
407
|
+
window.WhepClient = webrtc_client_1.WhepClient;
|
|
408
|
+
window.WhipClient = webrtc_client_1.WhipClient;
|
|
409
|
+
window.DuplexClient = webrtc_client_1.DuplexClient;
|
|
410
|
+
window.handleResponseError = function(x) {
|
|
411
|
+
x.addEventListener("responseerror", (err) => __awaiter(this, void 0, void 0, function* () {
|
|
412
|
+
const error = document.getElementById("error");
|
|
413
|
+
const response = err.detail;
|
|
414
|
+
if (error) {
|
|
415
|
+
error.appendChild(document.createTextNode(`${response.status} ${response.statusText}`));
|
|
416
|
+
error.appendChild(document.createElement("br"));
|
|
417
|
+
const buttons = document.getElementById("buttons");
|
|
418
|
+
if (buttons) {
|
|
419
|
+
buttons.style.display = "";
|
|
420
|
+
}
|
|
421
|
+
const response_body = document.createElement("div");
|
|
422
|
+
error.appendChild(response_body);
|
|
423
|
+
response_body.textContent = yield response.text();
|
|
424
|
+
}
|
|
425
|
+
}));
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
require_webrtc2();
|
|
430
|
+
})();
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
const defaultTheme = require('tailwindcss/defaultTheme');
|
|
3
|
+
module.exports = {
|
|
4
|
+
content: [],
|
|
5
|
+
darkMode: "class",
|
|
6
|
+
theme: {
|
|
7
|
+
extend: {
|
|
8
|
+
colors: {
|
|
9
|
+
primary: { "50": "#eff6ff", "100": "#dbeafe", "200": "#bfdbfe", "300": "#93c5fd", "400": "#60a5fa", "500": "#3b82f6", "600": "#2563eb", "700": "#1d4ed8", "800": "#1e40af", "900": "#1e3a8a", "950": "#172554" }
|
|
10
|
+
},
|
|
11
|
+
keyframes: {
|
|
12
|
+
activeSubscription: {
|
|
13
|
+
to: {
|
|
14
|
+
'stroke-dashoffset': 0
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
animation: {
|
|
19
|
+
activeSubscription: 'activeSubscription 1s linear infinite',
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
fontFamily: {
|
|
23
|
+
'body': [
|
|
24
|
+
'Inter',
|
|
25
|
+
'ui-sans-serif',
|
|
26
|
+
'system-ui',
|
|
27
|
+
'-apple-system',
|
|
28
|
+
'system-ui',
|
|
29
|
+
'Segoe UI',
|
|
30
|
+
'Roboto',
|
|
31
|
+
'Helvetica Neue',
|
|
32
|
+
'Arial',
|
|
33
|
+
'Noto Sans',
|
|
34
|
+
'sans-serif',
|
|
35
|
+
'Apple Color Emoji',
|
|
36
|
+
'Segoe UI Emoji',
|
|
37
|
+
'Segoe UI Symbol',
|
|
38
|
+
'Noto Color Emoji'
|
|
39
|
+
],
|
|
40
|
+
'sans': [
|
|
41
|
+
'Inter',
|
|
42
|
+
'ui-sans-serif',
|
|
43
|
+
'system-ui',
|
|
44
|
+
'-apple-system',
|
|
45
|
+
'system-ui',
|
|
46
|
+
'Segoe UI',
|
|
47
|
+
'Roboto',
|
|
48
|
+
'Helvetica Neue',
|
|
49
|
+
'Arial',
|
|
50
|
+
'Noto Sans',
|
|
51
|
+
'sans-serif',
|
|
52
|
+
'Apple Color Emoji',
|
|
53
|
+
'Segoe UI Emoji',
|
|
54
|
+
'Segoe UI Symbol',
|
|
55
|
+
'Noto Color Emoji'
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
screens: {
|
|
59
|
+
'xs': '300px',
|
|
60
|
+
...defaultTheme.screens,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
plugins: [
|
|
64
|
+
require('flowbite/plugin')
|
|
65
|
+
],
|
|
66
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
const defaultTheme = require('./tailwind-theme.js')
|
|
3
|
+
module.exports = {
|
|
4
|
+
...defaultTheme,
|
|
5
|
+
content: [
|
|
6
|
+
"src/**/*.{html,js,ejs,ts,tsx}",
|
|
7
|
+
"ui/**/*.{html,js,ejs}",
|
|
8
|
+
"static/**/*.{html,js,ejs}",
|
|
9
|
+
"node_modules/flowbite-react/lib/esm/**/*.js"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var exports = {};
|
|
2
|
+
|
|
3
|
+
// I want to do dynamic imports
|
|
4
|
+
// and the only way to do that is to make a global fn accessible from my esbuilt app
|
|
5
|
+
// cos esbuild does not allow this yet
|
|
6
|
+
// https://github.com/evanw/esbuild/issues/700
|
|
7
|
+
window.__loadExternalComponent = function(path) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const p = import(path);
|
|
10
|
+
p.then((f) => {
|
|
11
|
+
|
|
12
|
+
// I'd prefer to just accept plain ol' ES modules here
|
|
13
|
+
// but it's astoundingly easy to end up with other things in various
|
|
14
|
+
// build pipelines, so check for double default exports..
|
|
15
|
+
let module = f.default.default ?? f.default;
|
|
16
|
+
resolve(module);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
window.__loadCss = async function(path) {
|
|
22
|
+
const css = await import(path, {with: { type: 'css' }});
|
|
23
|
+
document.adoptedStyleSheets.push(css.default);
|
|
24
|
+
}
|