@devolutions/web-recorder 0.1.0 → 0.2.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/close-codes.d.ts +7 -0
- package/index.d.ts +1 -0
- package/index.js +19 -18
- package/package.json +31 -31
package/close-codes.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket close code a recorder sends when the user stops the recording.
|
|
3
|
+
*
|
|
4
|
+
* Devolutions Gateway then ends the recording at once, so live viewers see the end right away.
|
|
5
|
+
* Any other close keeps the recording open until its reconnection window passes.
|
|
6
|
+
*/
|
|
7
|
+
export declare const RECORDING_ENDED_CLOSE_CODE = 4011;
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { AsciiCastV2Event, AsciiCastV2EventCode, AsciiCastV2Header, AsciiCastV2Message, AsciiCastV2RecorderOptions, } from './asciicast-v2-recorder';
|
|
2
2
|
export { AsciiCastV2Recorder } from './asciicast-v2-recorder';
|
|
3
|
+
export { RECORDING_ENDED_CLOSE_CODE } from './close-codes';
|
|
3
4
|
export type { IRecordableSession } from './recordable-session';
|
|
4
5
|
export type { WebMRecorderOptions, WebMRecorderTelemetryEvent } from './webm-recorder';
|
|
5
6
|
export { WebMRecorder } from './webm-recorder';
|
package/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
var g = Object.defineProperty;
|
|
2
2
|
var m = (o, e, t) => e in o ? g(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
|
|
3
3
|
var i = (o, e, t) => m(o, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
|
|
4
|
+
const T = 4011;
|
|
5
|
+
class E {
|
|
5
6
|
constructor(e) {
|
|
6
7
|
i(this, "startTime", 0);
|
|
7
8
|
i(this, "websocket", null);
|
|
@@ -62,13 +63,13 @@ class C {
|
|
|
62
63
|
return u;
|
|
63
64
|
}
|
|
64
65
|
stop() {
|
|
65
|
-
this.internalStop();
|
|
66
|
+
this.internalStop(4011);
|
|
66
67
|
}
|
|
67
|
-
internalStop() {
|
|
68
|
-
var
|
|
69
|
-
this.outputGeneration++, this.unsubscribeOutput && (this.unsubscribeOutput(), this.unsubscribeOutput = null), (
|
|
70
|
-
const
|
|
71
|
-
this.websocket = null,
|
|
68
|
+
internalStop(e) {
|
|
69
|
+
var r;
|
|
70
|
+
this.outputGeneration++, this.unsubscribeOutput && (this.unsubscribeOutput(), this.unsubscribeOutput = null), (r = this.settleStart) == null || r.call(this), this.settleStart = null;
|
|
71
|
+
const t = this.websocket;
|
|
72
|
+
this.websocket = null, t == null || t.close(e);
|
|
72
73
|
}
|
|
73
74
|
onEvent(e, t) {
|
|
74
75
|
const r = (Date.now() - this.startTime) / 1e3;
|
|
@@ -102,11 +103,11 @@ class b {
|
|
|
102
103
|
send(e) {
|
|
103
104
|
this.ws.readyState === WebSocket.CLOSING || this.ws.readyState === WebSocket.CLOSED || (this.ready ? this.ws.send(e) : this.queue.push(e));
|
|
104
105
|
}
|
|
105
|
-
close() {
|
|
106
|
-
this.ready = !1, this.queue = [], this.ws.readyState !== WebSocket.CLOSING && this.ws.readyState !== WebSocket.CLOSED && this.ws.close();
|
|
106
|
+
close(e) {
|
|
107
|
+
this.ready = !1, this.queue = [], this.ws.readyState !== WebSocket.CLOSING && this.ws.readyState !== WebSocket.CLOSED && this.ws.close(e);
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
|
-
const
|
|
110
|
+
const v = 8, w = 10;
|
|
110
111
|
class W {
|
|
111
112
|
constructor(e = {}) {
|
|
112
113
|
i(this, "mediaRecorder", null);
|
|
@@ -144,7 +145,7 @@ class W {
|
|
|
144
145
|
this.mediaRecorder.stop();
|
|
145
146
|
return;
|
|
146
147
|
}
|
|
147
|
-
(e = this.resolveStart) == null || e.call(this), this.resolveStart = null, this.rejectStart = null, this.closeWebSocket(), this.cleanupResources(), this.fireTelemetry("recording-stopped");
|
|
148
|
+
(e = this.resolveStart) == null || e.call(this), this.resolveStart = null, this.rejectStart = null, this.closeWebSocket(4011), this.cleanupResources(), this.fireTelemetry("recording-stopped");
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
// Initialize canvas capture stream
|
|
@@ -152,7 +153,7 @@ class W {
|
|
|
152
153
|
if (!e)
|
|
153
154
|
return console.error("[WebMRecorder] Canvas element is null"), !1;
|
|
154
155
|
try {
|
|
155
|
-
this.stream = e.captureStream(
|
|
156
|
+
this.stream = e.captureStream(v);
|
|
156
157
|
} catch (t) {
|
|
157
158
|
return console.error("Failed to initialize canvas capture:", t), !1;
|
|
158
159
|
}
|
|
@@ -182,7 +183,7 @@ class W {
|
|
|
182
183
|
}
|
|
183
184
|
try {
|
|
184
185
|
const r = new MediaRecorder(this.stream, { mimeType: "video/webm" });
|
|
185
|
-
this.mediaRecorder = r, r.onstart = this.handleMediaRecorderStart.bind(this), r.ondataavailable = this.handleMediaRecorderDataAvailable.bind(this), r.onstop = this.handleMediaRecorderStop.bind(this), r.onerror = this.handleMediaRecorderError.bind(this), r.start(
|
|
186
|
+
this.mediaRecorder = r, r.onstart = this.handleMediaRecorderStart.bind(this), r.ondataavailable = this.handleMediaRecorderDataAvailable.bind(this), r.onstop = this.handleMediaRecorderStop.bind(this), r.onerror = this.handleMediaRecorderError.bind(this), r.start(w);
|
|
186
187
|
} catch (r) {
|
|
187
188
|
console.error("[WebMRecorder] Failed to start MediaRecorder:", r), this.isStarting = !1, (t = this.rejectStart) == null || t.call(this, "UnableToStartRecording"), this.resolveStart = null, this.rejectStart = null, this.closeWebSocket(), this.cleanupResources();
|
|
188
189
|
}
|
|
@@ -234,9 +235,8 @@ class W {
|
|
|
234
235
|
}
|
|
235
236
|
handleMediaRecorderStop() {
|
|
236
237
|
var t, r;
|
|
237
|
-
this.closeWebSocket();
|
|
238
238
|
const e = this.pendingError;
|
|
239
|
-
e ? (t = this.rejectStart) == null || t.call(this, e) : (r = this.resolveStart) == null || r.call(this), this.resolveStart = null, this.rejectStart = null, this.cleanupResources(), e || this.fireTelemetry("recording-stopped");
|
|
239
|
+
this.closeWebSocket(e ? void 0 : 4011), e ? (t = this.rejectStart) == null || t.call(this, e) : (r = this.resolveStart) == null || r.call(this), this.resolveStart = null, this.rejectStart = null, this.cleanupResources(), e || this.fireTelemetry("recording-stopped");
|
|
240
240
|
}
|
|
241
241
|
handleMediaRecorderError(e) {
|
|
242
242
|
console.error("[WebMRecorder] MediaRecorder encountered an error:", e), !this.isCleaningUp && (this.isCleaningUp = !0, this.stopKeepalive(), this.pendingError = "UnableToStartRecording", this.mediaRecorder && this.mediaRecorder.state !== "inactive" && this.mediaRecorder.stop());
|
|
@@ -255,11 +255,12 @@ class W {
|
|
|
255
255
|
stopKeepalive() {
|
|
256
256
|
this.keepaliveRaf !== null && (cancelAnimationFrame(this.keepaliveRaf), this.keepaliveRaf = null);
|
|
257
257
|
}
|
|
258
|
-
closeWebSocket() {
|
|
259
|
-
this.ws && (this.ws.onclose = null, this.ws.onerror = null, (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) && this.ws.close());
|
|
258
|
+
closeWebSocket(e) {
|
|
259
|
+
this.ws && (this.ws.onclose = null, this.ws.onerror = null, (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) && this.ws.close(e));
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
export {
|
|
263
|
-
|
|
263
|
+
E as AsciiCastV2Recorder,
|
|
264
|
+
T as RECORDING_ENDED_CLOSE_CODE,
|
|
264
265
|
W as WebMRecorder
|
|
265
266
|
};
|
package/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@devolutions/web-recorder",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Framework-agnostic browser session-recording capture (WebM video + asciicast terminal) for Devolutions Gateway jrec push",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./index.js",
|
|
7
|
-
"module": "./index.js",
|
|
8
|
-
"types": "./index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"import": "./index.js",
|
|
12
|
-
"types": "./index.d.ts"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"repository": {
|
|
16
|
-
"type": "git",
|
|
17
|
-
"url": "https://github.com/Devolutions/devolutions-gateway.git"
|
|
18
|
-
},
|
|
19
|
-
"keywords": [
|
|
20
|
-
"recording",
|
|
21
|
-
"session-recording",
|
|
22
|
-
"webm",
|
|
23
|
-
"asciicast",
|
|
24
|
-
"capture",
|
|
25
|
-
"media-recorder"
|
|
26
|
-
],
|
|
27
|
-
"license": "MIT OR Apache-2.0",
|
|
28
|
-
"publishConfig": {
|
|
29
|
-
"access": "public"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@devolutions/web-recorder",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Framework-agnostic browser session-recording capture (WebM video + asciicast terminal) for Devolutions Gateway jrec push",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"module": "./index.js",
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./index.js",
|
|
12
|
+
"types": "./index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/Devolutions/devolutions-gateway.git"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"recording",
|
|
21
|
+
"session-recording",
|
|
22
|
+
"webm",
|
|
23
|
+
"asciicast",
|
|
24
|
+
"capture",
|
|
25
|
+
"media-recorder"
|
|
26
|
+
],
|
|
27
|
+
"license": "MIT OR Apache-2.0",
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
}
|
|
31
|
+
}
|