@daydreamlive/browser 0.2.0 → 0.3.1
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/dist/index.cjs +40 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -8
- package/dist/index.d.ts +4 -8
- package/dist/index.js +40 -139
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -196,7 +196,6 @@ var WHIPClient = class {
|
|
|
196
196
|
await this.audioSender.replaceTrack(audioTrack);
|
|
197
197
|
}
|
|
198
198
|
this.setCodecPreferences();
|
|
199
|
-
await this.applyBitrateConstraints();
|
|
200
199
|
const offer = await this.pc.createOffer({
|
|
201
200
|
offerToReceiveAudio: false,
|
|
202
201
|
offerToReceiveVideo: false
|
|
@@ -368,6 +367,9 @@ var WHIPClient = class {
|
|
|
368
367
|
this.abortController = null;
|
|
369
368
|
}
|
|
370
369
|
if (this.pc) {
|
|
370
|
+
this.pc.oniceconnectionstatechange = null;
|
|
371
|
+
this.pc.onconnectionstatechange = null;
|
|
372
|
+
this.pc.ontrack = null;
|
|
371
373
|
try {
|
|
372
374
|
this.pc.getTransceivers().forEach((t) => {
|
|
373
375
|
try {
|
|
@@ -410,7 +412,9 @@ var WHIPClient = class {
|
|
|
410
412
|
}
|
|
411
413
|
}
|
|
412
414
|
isConnected() {
|
|
413
|
-
|
|
415
|
+
if (!this.pc) return false;
|
|
416
|
+
const iceState = this.pc.iceConnectionState;
|
|
417
|
+
return iceState === "connected" || iceState === "completed";
|
|
414
418
|
}
|
|
415
419
|
getUrlWithCachedRedirect() {
|
|
416
420
|
const originalUrl = new URL(this.url);
|
|
@@ -590,10 +594,10 @@ var Broadcast = class extends TypedEventEmitter {
|
|
|
590
594
|
setupConnectionMonitoring() {
|
|
591
595
|
const pc = this.whipClient.getPeerConnection();
|
|
592
596
|
if (!pc) return;
|
|
593
|
-
pc.
|
|
597
|
+
pc.oniceconnectionstatechange = () => {
|
|
594
598
|
if (this.state === "ended") return;
|
|
595
|
-
const
|
|
596
|
-
if (
|
|
599
|
+
const iceState = pc.iceConnectionState;
|
|
600
|
+
if (iceState === "connected" || iceState === "completed") {
|
|
597
601
|
this.clearGraceTimeout();
|
|
598
602
|
if (this.state === "reconnecting") {
|
|
599
603
|
this.stateMachine.transition("live");
|
|
@@ -601,19 +605,19 @@ var Broadcast = class extends TypedEventEmitter {
|
|
|
601
605
|
}
|
|
602
606
|
return;
|
|
603
607
|
}
|
|
604
|
-
if (
|
|
608
|
+
if (iceState === "disconnected") {
|
|
605
609
|
this.clearGraceTimeout();
|
|
606
610
|
this.whipClient.restartIce();
|
|
607
611
|
this.disconnectedGraceTimeout = setTimeout(() => {
|
|
608
612
|
if (this.state === "ended") return;
|
|
609
|
-
const currentState = pc.
|
|
613
|
+
const currentState = pc.iceConnectionState;
|
|
610
614
|
if (currentState === "disconnected") {
|
|
611
615
|
this.scheduleReconnect();
|
|
612
616
|
}
|
|
613
617
|
}, 2e3);
|
|
614
618
|
return;
|
|
615
619
|
}
|
|
616
|
-
if (
|
|
620
|
+
if (iceState === "failed" || iceState === "closed") {
|
|
617
621
|
this.clearGraceTimeout();
|
|
618
622
|
this.scheduleReconnect();
|
|
619
623
|
}
|
|
@@ -716,6 +720,7 @@ var WHEPClient = class {
|
|
|
716
720
|
this.url = config.url;
|
|
717
721
|
this.iceServers = config.iceServers ?? DEFAULT_ICE_SERVERS;
|
|
718
722
|
this.connectionTimeout = config.connectionTimeout ?? DEFAULT_CONNECTION_TIMEOUT2;
|
|
723
|
+
this.skipIceGathering = config.skipIceGathering ?? true;
|
|
719
724
|
this.onStats = config.onStats;
|
|
720
725
|
this.statsIntervalMs = config.statsIntervalMs ?? 5e3;
|
|
721
726
|
this.pcFactory = config.peerConnectionFactory ?? defaultPeerConnectionFactory;
|
|
@@ -741,7 +746,9 @@ var WHEPClient = class {
|
|
|
741
746
|
};
|
|
742
747
|
const offer = await this.pc.createOffer();
|
|
743
748
|
await this.pc.setLocalDescription(offer);
|
|
744
|
-
|
|
749
|
+
if (!this.skipIceGathering) {
|
|
750
|
+
await this.waitForIceGathering();
|
|
751
|
+
}
|
|
745
752
|
this.abortController = new AbortController();
|
|
746
753
|
const timeoutId = this.timers.setTimeout(
|
|
747
754
|
() => this.abortController?.abort(),
|
|
@@ -840,6 +847,9 @@ var WHEPClient = class {
|
|
|
840
847
|
this.abortController = null;
|
|
841
848
|
}
|
|
842
849
|
if (this.pc) {
|
|
850
|
+
this.pc.oniceconnectionstatechange = null;
|
|
851
|
+
this.pc.onconnectionstatechange = null;
|
|
852
|
+
this.pc.ontrack = null;
|
|
843
853
|
try {
|
|
844
854
|
this.pc.getTransceivers().forEach((t) => {
|
|
845
855
|
try {
|
|
@@ -924,7 +934,10 @@ var Player = class extends TypedEventEmitter {
|
|
|
924
934
|
get reconnectInfo() {
|
|
925
935
|
if (this.state !== "buffering") return null;
|
|
926
936
|
const baseDelay = this.reconnectConfig.baseDelayMs ?? 200;
|
|
927
|
-
const delay = this.calculateReconnectDelay(
|
|
937
|
+
const delay = this.calculateReconnectDelay(
|
|
938
|
+
this.reconnectAttempts - 1,
|
|
939
|
+
baseDelay
|
|
940
|
+
);
|
|
928
941
|
return {
|
|
929
942
|
attempt: this.reconnectAttempts,
|
|
930
943
|
maxAttempts: this.reconnectConfig.maxAttempts ?? 30,
|
|
@@ -1014,14 +1027,14 @@ var Player = class extends TypedEventEmitter {
|
|
|
1014
1027
|
this.stateMachine.transition("ended");
|
|
1015
1028
|
return;
|
|
1016
1029
|
}
|
|
1017
|
-
const maxAttempts = this.reconnectConfig.maxAttempts ??
|
|
1030
|
+
const maxAttempts = this.reconnectConfig.maxAttempts ?? 30;
|
|
1018
1031
|
if (this.reconnectAttempts >= maxAttempts) {
|
|
1019
1032
|
this.stateMachine.transition("ended");
|
|
1020
1033
|
return;
|
|
1021
1034
|
}
|
|
1022
1035
|
this.clearReconnectTimeout();
|
|
1023
1036
|
this.stateMachine.transition("buffering");
|
|
1024
|
-
const baseDelay = this.reconnectConfig.baseDelayMs ??
|
|
1037
|
+
const baseDelay = this.reconnectConfig.baseDelayMs ?? 200;
|
|
1025
1038
|
const delay = this.calculateReconnectDelay(
|
|
1026
1039
|
this.reconnectAttempts,
|
|
1027
1040
|
baseDelay
|
|
@@ -1066,6 +1079,7 @@ function createPlayer(whepUrl, options) {
|
|
|
1066
1079
|
whepConfig: {
|
|
1067
1080
|
iceServers: options?.iceServers,
|
|
1068
1081
|
connectionTimeout: options?.connectionTimeout,
|
|
1082
|
+
skipIceGathering: options?.skipIceGathering,
|
|
1069
1083
|
onStats: options?.onStats,
|
|
1070
1084
|
statsIntervalMs: options?.statsIntervalMs
|
|
1071
1085
|
}
|
|
@@ -1120,18 +1134,12 @@ function createRenderer(options) {
|
|
|
1120
1134
|
height: options.height,
|
|
1121
1135
|
dpr: Math.min(2, options.dpr)
|
|
1122
1136
|
};
|
|
1123
|
-
let crossfadeMs = options.crossfadeMs;
|
|
1124
1137
|
let keepalive = options.keepalive;
|
|
1125
1138
|
let captureCanvas = null;
|
|
1126
1139
|
let captureCtx = null;
|
|
1127
1140
|
let offscreen = null;
|
|
1128
1141
|
let offscreenCtx = null;
|
|
1129
|
-
let crossfadeCanvas = null;
|
|
1130
|
-
let crossfadeCtx = null;
|
|
1131
1142
|
let currentSource = null;
|
|
1132
|
-
let pendingSource = null;
|
|
1133
|
-
let crossfadeStart = null;
|
|
1134
|
-
let cleanupFn = void 0;
|
|
1135
1143
|
let frameIndex = 0;
|
|
1136
1144
|
let rectCache = /* @__PURE__ */ new WeakMap();
|
|
1137
1145
|
function initCanvas() {
|
|
@@ -1168,25 +1176,6 @@ function createRenderer(options) {
|
|
|
1168
1176
|
offscreen = off;
|
|
1169
1177
|
offscreenCtx = offCtx;
|
|
1170
1178
|
}
|
|
1171
|
-
try {
|
|
1172
|
-
const cfCanvas = new OffscreenCanvas(pxW, pxH);
|
|
1173
|
-
crossfadeCanvas = cfCanvas;
|
|
1174
|
-
const cfCtx = cfCanvas.getContext("2d", { alpha: true });
|
|
1175
|
-
if (cfCtx) {
|
|
1176
|
-
cfCtx.imageSmoothingEnabled = true;
|
|
1177
|
-
crossfadeCtx = cfCtx;
|
|
1178
|
-
}
|
|
1179
|
-
} catch {
|
|
1180
|
-
const cfCanvas = document.createElement("canvas");
|
|
1181
|
-
cfCanvas.width = pxW;
|
|
1182
|
-
cfCanvas.height = pxH;
|
|
1183
|
-
const cfCtx = cfCanvas.getContext("2d", { alpha: true });
|
|
1184
|
-
if (cfCtx) {
|
|
1185
|
-
cfCtx.imageSmoothingEnabled = true;
|
|
1186
|
-
crossfadeCanvas = cfCanvas;
|
|
1187
|
-
crossfadeCtx = cfCtx;
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
1179
|
offscreenCtx.fillStyle = "#111";
|
|
1191
1180
|
offscreenCtx.fillRect(0, 0, pxW, pxH);
|
|
1192
1181
|
captureCtx.drawImage(
|
|
@@ -1206,11 +1195,8 @@ function createRenderer(options) {
|
|
|
1206
1195
|
const v = source.element;
|
|
1207
1196
|
return typeof v.readyState === "number" && v.readyState >= 2 && (v.videoWidth || 0) > 0 && (v.videoHeight || 0) > 0;
|
|
1208
1197
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
return (c.width || 0) > 0 && (c.height || 0) > 0;
|
|
1212
|
-
}
|
|
1213
|
-
return true;
|
|
1198
|
+
const c = source.element;
|
|
1199
|
+
return (c.width || 0) > 0 && (c.height || 0) > 0;
|
|
1214
1200
|
}
|
|
1215
1201
|
function getDrawRect(el, fit) {
|
|
1216
1202
|
const canvas = offscreenCtx?.canvas;
|
|
@@ -1242,46 +1228,19 @@ function createRenderer(options) {
|
|
|
1242
1228
|
});
|
|
1243
1229
|
return { dx, dy, dw, dh };
|
|
1244
1230
|
}
|
|
1245
|
-
function blitSource(source
|
|
1231
|
+
function blitSource(source) {
|
|
1246
1232
|
if (!offscreenCtx) return;
|
|
1247
1233
|
const ctx = offscreenCtx;
|
|
1248
|
-
if (source.kind === "custom") {
|
|
1249
|
-
if (alpha < 1 && crossfadeCtx && crossfadeCanvas) {
|
|
1250
|
-
crossfadeCtx.clearRect(
|
|
1251
|
-
0,
|
|
1252
|
-
0,
|
|
1253
|
-
crossfadeCtx.canvas.width,
|
|
1254
|
-
crossfadeCtx.canvas.height
|
|
1255
|
-
);
|
|
1256
|
-
if (source.onFrame) source.onFrame(crossfadeCtx, timestamp);
|
|
1257
|
-
const prev2 = ctx.globalAlpha;
|
|
1258
|
-
try {
|
|
1259
|
-
ctx.globalAlpha = Math.max(0, Math.min(1, alpha));
|
|
1260
|
-
ctx.drawImage(crossfadeCanvas, 0, 0);
|
|
1261
|
-
} finally {
|
|
1262
|
-
ctx.globalAlpha = prev2;
|
|
1263
|
-
}
|
|
1264
|
-
} else {
|
|
1265
|
-
if (source.onFrame) source.onFrame(ctx, timestamp);
|
|
1266
|
-
}
|
|
1267
|
-
return;
|
|
1268
|
-
}
|
|
1269
1234
|
const el = source.element;
|
|
1270
1235
|
const rect = getDrawRect(el, source.fit ?? "contain");
|
|
1271
1236
|
if (!rect) return;
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
rect.dw,
|
|
1280
|
-
rect.dh
|
|
1281
|
-
);
|
|
1282
|
-
} finally {
|
|
1283
|
-
ctx.globalAlpha = prev;
|
|
1284
|
-
}
|
|
1237
|
+
ctx.drawImage(
|
|
1238
|
+
el,
|
|
1239
|
+
rect.dx,
|
|
1240
|
+
rect.dy,
|
|
1241
|
+
rect.dw,
|
|
1242
|
+
rect.dh
|
|
1243
|
+
);
|
|
1285
1244
|
}
|
|
1286
1245
|
initCanvas();
|
|
1287
1246
|
return {
|
|
@@ -1296,57 +1255,18 @@ function createRenderer(options) {
|
|
|
1296
1255
|
},
|
|
1297
1256
|
isSourceReady,
|
|
1298
1257
|
setActiveSource(source) {
|
|
1299
|
-
|
|
1300
|
-
cleanupFn();
|
|
1301
|
-
cleanupFn = void 0;
|
|
1302
|
-
}
|
|
1303
|
-
if (source === null) {
|
|
1304
|
-
currentSource = null;
|
|
1305
|
-
pendingSource = null;
|
|
1306
|
-
crossfadeStart = null;
|
|
1307
|
-
return;
|
|
1308
|
-
}
|
|
1309
|
-
pendingSource = source;
|
|
1310
|
-
crossfadeStart = null;
|
|
1311
|
-
if (source.kind === "custom" && source.onStart) {
|
|
1312
|
-
const cleanup = source.onStart(offscreenCtx);
|
|
1313
|
-
cleanupFn = cleanup || void 0;
|
|
1314
|
-
return cleanupFn;
|
|
1315
|
-
}
|
|
1258
|
+
currentSource = source;
|
|
1316
1259
|
},
|
|
1317
|
-
renderFrame(
|
|
1260
|
+
renderFrame(_timestamp) {
|
|
1318
1261
|
const off = offscreenCtx;
|
|
1319
1262
|
const cap = captureCtx;
|
|
1320
1263
|
const capCanvas = captureCanvas;
|
|
1321
1264
|
if (!off || !cap || !capCanvas) return;
|
|
1322
|
-
if (pendingSource && isSourceReady(pendingSource)) {
|
|
1323
|
-
if (crossfadeStart === null) crossfadeStart = timestamp;
|
|
1324
|
-
}
|
|
1325
1265
|
off.globalCompositeOperation = "source-over";
|
|
1326
|
-
|
|
1327
|
-
if (willDraw) {
|
|
1266
|
+
if (currentSource && isSourceReady(currentSource)) {
|
|
1328
1267
|
off.fillStyle = "#000";
|
|
1329
1268
|
off.fillRect(0, 0, off.canvas.width, off.canvas.height);
|
|
1330
|
-
|
|
1331
|
-
const fading = pendingSource && crossfadeStart !== null && currentSource;
|
|
1332
|
-
if (fading) {
|
|
1333
|
-
const t = Math.min(1, (timestamp - crossfadeStart) / crossfadeMs);
|
|
1334
|
-
blitSource(currentSource, 1 - t, timestamp);
|
|
1335
|
-
blitSource(pendingSource, t, timestamp);
|
|
1336
|
-
if (t >= 1) {
|
|
1337
|
-
currentSource = pendingSource;
|
|
1338
|
-
pendingSource = null;
|
|
1339
|
-
crossfadeStart = null;
|
|
1340
|
-
}
|
|
1341
|
-
} else if (pendingSource && !currentSource) {
|
|
1342
|
-
if (isSourceReady(pendingSource)) {
|
|
1343
|
-
blitSource(pendingSource, 1, timestamp);
|
|
1344
|
-
currentSource = pendingSource;
|
|
1345
|
-
pendingSource = null;
|
|
1346
|
-
crossfadeStart = null;
|
|
1347
|
-
}
|
|
1348
|
-
} else if (currentSource) {
|
|
1349
|
-
blitSource(currentSource, 1, timestamp);
|
|
1269
|
+
blitSource(currentSource);
|
|
1350
1270
|
}
|
|
1351
1271
|
if (keepalive) {
|
|
1352
1272
|
const w = off.canvas.width;
|
|
@@ -1396,34 +1316,17 @@ function createRenderer(options) {
|
|
|
1396
1316
|
offscreen.width = pxW;
|
|
1397
1317
|
offscreen.height = pxH;
|
|
1398
1318
|
}
|
|
1399
|
-
if (crossfadeCanvas instanceof HTMLCanvasElement) {
|
|
1400
|
-
crossfadeCanvas.width = pxW;
|
|
1401
|
-
crossfadeCanvas.height = pxH;
|
|
1402
|
-
} else if (crossfadeCanvas instanceof OffscreenCanvas) {
|
|
1403
|
-
crossfadeCanvas.width = pxW;
|
|
1404
|
-
crossfadeCanvas.height = pxH;
|
|
1405
|
-
}
|
|
1406
1319
|
rectCache = /* @__PURE__ */ new WeakMap();
|
|
1407
1320
|
},
|
|
1408
|
-
setCrossfadeMs(ms) {
|
|
1409
|
-
crossfadeMs = Math.max(0, ms);
|
|
1410
|
-
},
|
|
1411
1321
|
setKeepalive(enabled) {
|
|
1412
1322
|
keepalive = enabled;
|
|
1413
1323
|
},
|
|
1414
1324
|
destroy() {
|
|
1415
|
-
if (cleanupFn) {
|
|
1416
|
-
cleanupFn();
|
|
1417
|
-
cleanupFn = void 0;
|
|
1418
|
-
}
|
|
1419
1325
|
currentSource = null;
|
|
1420
|
-
pendingSource = null;
|
|
1421
1326
|
captureCanvas = null;
|
|
1422
1327
|
captureCtx = null;
|
|
1423
1328
|
offscreen = null;
|
|
1424
1329
|
offscreenCtx = null;
|
|
1425
|
-
crossfadeCanvas = null;
|
|
1426
|
-
crossfadeCtx = null;
|
|
1427
1330
|
}
|
|
1428
1331
|
};
|
|
1429
1332
|
}
|
|
@@ -1958,7 +1861,6 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1958
1861
|
2,
|
|
1959
1862
|
options.dpr ?? (typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1)
|
|
1960
1863
|
);
|
|
1961
|
-
const crossfadeMs = options.crossfadeMs ?? 500;
|
|
1962
1864
|
const keepalive = options.keepalive ?? true;
|
|
1963
1865
|
this.registry = createRegistry({
|
|
1964
1866
|
onRegister: (id, source) => this.emit("registered", id, source),
|
|
@@ -1968,7 +1870,6 @@ var Compositor = class extends CompositorEventEmitter {
|
|
|
1968
1870
|
width,
|
|
1969
1871
|
height,
|
|
1970
1872
|
dpr,
|
|
1971
|
-
crossfadeMs,
|
|
1972
1873
|
keepalive
|
|
1973
1874
|
});
|
|
1974
1875
|
this.scheduler = createScheduler({
|