@whereby.com/core 0.8.0 → 0.9.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/{cjs/index.cjs → index.cjs} +102 -10
- package/dist/index.d.cts +5325 -0
- package/dist/index.d.mts +5325 -0
- package/dist/index.d.ts +29 -12
- package/dist/index.mjs +98 -9
- package/package.json +18 -22
- package/dist/cjs/utils.cjs +0 -113
- package/dist/utils.d.ts +0 -19
- package/dist/utils.mjs +0 -108
package/dist/index.d.ts
CHANGED
|
@@ -199,6 +199,7 @@ interface RemoteParticipant {
|
|
|
199
199
|
presentationStream: (MediaStream & {
|
|
200
200
|
inboundId?: string;
|
|
201
201
|
}) | null;
|
|
202
|
+
externalId: string | null;
|
|
202
203
|
}
|
|
203
204
|
declare class LocalParticipant extends RoomParticipant {
|
|
204
205
|
readonly isLocalParticipant = true;
|
|
@@ -454,7 +455,7 @@ interface AppState {
|
|
|
454
455
|
roomName: string | null;
|
|
455
456
|
roomKey: string | null;
|
|
456
457
|
displayName: string | null;
|
|
457
|
-
|
|
458
|
+
userAgent: string | null;
|
|
458
459
|
externalId: string | null;
|
|
459
460
|
}
|
|
460
461
|
declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
@@ -465,7 +466,7 @@ declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
|
465
466
|
roomName: string | null;
|
|
466
467
|
roomKey: string | null;
|
|
467
468
|
displayName: string | null;
|
|
468
|
-
|
|
469
|
+
userAgent: string | null;
|
|
469
470
|
externalId: string | null;
|
|
470
471
|
}, action: PayloadAction<{
|
|
471
472
|
isNodeSdk?: boolean;
|
|
@@ -473,7 +474,7 @@ declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
|
473
474
|
localMediaOptions?: LocalMediaOptions;
|
|
474
475
|
roomKey: string | null;
|
|
475
476
|
roomUrl: string;
|
|
476
|
-
|
|
477
|
+
userAgent?: string;
|
|
477
478
|
externalId: string | null;
|
|
478
479
|
}>) => {
|
|
479
480
|
roomName: string;
|
|
@@ -483,7 +484,7 @@ declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
|
483
484
|
localMediaOptions?: LocalMediaOptions | undefined;
|
|
484
485
|
roomKey: string | null;
|
|
485
486
|
roomUrl: string;
|
|
486
|
-
|
|
487
|
+
userAgent: string | null;
|
|
487
488
|
externalId: string | null;
|
|
488
489
|
};
|
|
489
490
|
appLeft: (state: {
|
|
@@ -493,7 +494,7 @@ declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
|
493
494
|
roomName: string | null;
|
|
494
495
|
roomKey: string | null;
|
|
495
496
|
displayName: string | null;
|
|
496
|
-
|
|
497
|
+
userAgent: string | null;
|
|
497
498
|
externalId: string | null;
|
|
498
499
|
}) => {
|
|
499
500
|
wantsToJoin: false;
|
|
@@ -502,7 +503,7 @@ declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
|
502
503
|
roomName: string | null;
|
|
503
504
|
roomKey: string | null;
|
|
504
505
|
displayName: string | null;
|
|
505
|
-
|
|
506
|
+
userAgent: string | null;
|
|
506
507
|
externalId: string | null;
|
|
507
508
|
};
|
|
508
509
|
setRoomKey: (state: {
|
|
@@ -512,7 +513,7 @@ declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
|
512
513
|
roomName: string | null;
|
|
513
514
|
roomKey: string | null;
|
|
514
515
|
displayName: string | null;
|
|
515
|
-
|
|
516
|
+
userAgent: string | null;
|
|
516
517
|
externalId: string | null;
|
|
517
518
|
}, action: PayloadAction<string>) => {
|
|
518
519
|
roomKey: string;
|
|
@@ -521,7 +522,7 @@ declare const appSlice: _reduxjs_toolkit.Slice<AppState, {
|
|
|
521
522
|
roomUrl: string | null;
|
|
522
523
|
roomName: string | null;
|
|
523
524
|
displayName: string | null;
|
|
524
|
-
|
|
525
|
+
userAgent: string | null;
|
|
525
526
|
externalId: string | null;
|
|
526
527
|
};
|
|
527
528
|
}, "app", "app", _reduxjs_toolkit.SliceSelectors<AppState>>;
|
|
@@ -531,7 +532,7 @@ declare const doAppJoin: _reduxjs_toolkit.ActionCreatorWithPayload<{
|
|
|
531
532
|
localMediaOptions?: LocalMediaOptions | undefined;
|
|
532
533
|
roomKey: string | null;
|
|
533
534
|
roomUrl: string;
|
|
534
|
-
|
|
535
|
+
userAgent?: string | undefined;
|
|
535
536
|
externalId: string | null;
|
|
536
537
|
}, "app/doAppJoin">;
|
|
537
538
|
declare const appLeft: _reduxjs_toolkit.ActionCreatorWithoutPayload<"app/appLeft">;
|
|
@@ -542,7 +543,7 @@ declare const selectAppRoomName: (state: RootState) => string | null;
|
|
|
542
543
|
declare const selectAppRoomUrl: (state: RootState) => string | null;
|
|
543
544
|
declare const selectAppRoomKey: (state: RootState) => string | null;
|
|
544
545
|
declare const selectAppDisplayName: (state: RootState) => string | null;
|
|
545
|
-
declare const
|
|
546
|
+
declare const selectAppUserAgent: (state: RootState) => string | null;
|
|
546
547
|
declare const selectAppExternalId: (state: RootState) => string | null;
|
|
547
548
|
declare const selectAppIsNodeSdk: (state: RootState) => boolean;
|
|
548
549
|
|
|
@@ -838,9 +839,14 @@ declare const selectShouldFetchDeviceCredentials: ((state: {
|
|
|
838
839
|
memoize: typeof reselect.weakMapMemoize;
|
|
839
840
|
};
|
|
840
841
|
|
|
842
|
+
interface Options {
|
|
843
|
+
delay?: number;
|
|
844
|
+
edges?: boolean;
|
|
845
|
+
}
|
|
841
846
|
interface DebouncedFunction {
|
|
842
847
|
(...args: any[]): void;
|
|
843
848
|
}
|
|
849
|
+
declare function debounce(fn: DebouncedFunction, { delay, edges }?: Options): DebouncedFunction;
|
|
844
850
|
|
|
845
851
|
type LocalMediaOptions = {
|
|
846
852
|
audio: boolean;
|
|
@@ -2400,6 +2406,7 @@ declare const remoteParticipantsSlice: _reduxjs_toolkit.Slice<RemoteParticipantS
|
|
|
2400
2406
|
dispatchEvent: (event: Event) => boolean;
|
|
2401
2407
|
inboundId?: string | undefined;
|
|
2402
2408
|
} | null;
|
|
2409
|
+
externalId: string | null;
|
|
2403
2410
|
}[];
|
|
2404
2411
|
}, action: PayloadAction<StreamStatusUpdate[]>) => {
|
|
2405
2412
|
remoteParticipants: {
|
|
@@ -2459,6 +2466,7 @@ declare const remoteParticipantsSlice: _reduxjs_toolkit.Slice<RemoteParticipantS
|
|
|
2459
2466
|
dispatchEvent: (event: Event) => boolean;
|
|
2460
2467
|
inboundId?: string | undefined;
|
|
2461
2468
|
} | null;
|
|
2469
|
+
externalId: string | null;
|
|
2462
2470
|
}[];
|
|
2463
2471
|
};
|
|
2464
2472
|
participantStreamAdded: (state: {
|
|
@@ -2519,6 +2527,7 @@ declare const remoteParticipantsSlice: _reduxjs_toolkit.Slice<RemoteParticipantS
|
|
|
2519
2527
|
dispatchEvent: (event: Event) => boolean;
|
|
2520
2528
|
inboundId?: string | undefined;
|
|
2521
2529
|
} | null;
|
|
2530
|
+
externalId: string | null;
|
|
2522
2531
|
}[];
|
|
2523
2532
|
}, action: PayloadAction<RtcStreamAddedPayload>) => RemoteParticipantState;
|
|
2524
2533
|
participantStreamIdAdded: (state: {
|
|
@@ -2579,6 +2588,7 @@ declare const remoteParticipantsSlice: _reduxjs_toolkit.Slice<RemoteParticipantS
|
|
|
2579
2588
|
dispatchEvent: (event: Event) => boolean;
|
|
2580
2589
|
inboundId?: string | undefined;
|
|
2581
2590
|
} | null;
|
|
2591
|
+
externalId: string | null;
|
|
2582
2592
|
}[];
|
|
2583
2593
|
}, action: PayloadAction<{
|
|
2584
2594
|
clientId: string;
|
|
@@ -5303,6 +5313,13 @@ declare const createReactor: <Selectors extends Selector<{
|
|
|
5303
5313
|
extra: ReturnType<typeof createServices>;
|
|
5304
5314
|
}, ...selectorValues: SelectorResults<Selectors>) => void | Promise<void>) => _reduxjs_toolkit.UnsubscribeListener;
|
|
5305
5315
|
|
|
5306
|
-
declare
|
|
5316
|
+
declare function fakeAudioStream(): MediaStream;
|
|
5317
|
+
|
|
5318
|
+
declare function fakeWebcamFrame(canvas: HTMLCanvasElement): void;
|
|
5319
|
+
|
|
5320
|
+
declare function parseRoomUrlAndSubdomain(roomAttribute?: string, subdomainAttribute?: string): {
|
|
5321
|
+
subdomain: string;
|
|
5322
|
+
roomUrl: URL;
|
|
5323
|
+
};
|
|
5307
5324
|
|
|
5308
|
-
export { ApiClient, type AppDispatch, type AppStartListening, type AppState, type AppThunk, type ChatMessage, type ChatState, type CloudRecordingState, type ConnectionStatus, Credentials, CredentialsService, type DeviceCredentialsState, type LocalMediaOptions, type LocalMediaState, LocalParticipant, type LocalParticipantState, type LocalScreenshareState, OrganizationApiClient, OrganizationService, OrganizationServiceCache, type OrganizationState, type RemoteParticipant, type RemoteParticipantData, type RemoteParticipantState, type RoomConnectionState, RoomService, type RootReducer, type RootState, type RtcConnectionState, type Screenshare, type SignalConnectionState, type Store, type StreamState, type StreamingState, type ThunkConfig, type WaitingParticipant, type WaitingParticipantsState, addAppListener, appLeft, appSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppJoin, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKnockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSetDevice, doSetDisplayName, doSetLocalParticipant, doSignalDisconnect, doSignalIdentifyDevice, doSignalReconnect, doSignalSocketConnect, doStartCloudRecording, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doUpdateDeviceList, initialCloudRecordingState, initialLocalMediaState, isAcceptingStreams, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, observeStore, organizationSlice, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, resolutionReported, roomConnectionSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, type rtcAnalyticsState, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized,
|
|
5325
|
+
export { ApiClient, type AppDispatch, type AppStartListening, type AppState, type AppThunk, type ChatMessage, type ChatState, type CloudRecordingState, type ConnectionStatus, Credentials, CredentialsService, type DeviceCredentialsState, type LocalMediaOptions, type LocalMediaState, LocalParticipant, type LocalParticipantState, type LocalScreenshareState, OrganizationApiClient, OrganizationService, OrganizationServiceCache, type OrganizationState, type RemoteParticipant, type RemoteParticipantData, type RemoteParticipantState, type RoomConnectionState, RoomService, type RootReducer, type RootState, type RtcConnectionState, type Screenshare, type SignalConnectionState, type Store, type StreamState, type StreamingState, type ThunkConfig, type WaitingParticipant, type WaitingParticipantsState, addAppListener, appLeft, appSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, debounce, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppJoin, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKnockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSetDevice, doSetDisplayName, doSetLocalParticipant, doSignalDisconnect, doSignalIdentifyDevice, doSignalReconnect, doSignalSocketConnect, doStartCloudRecording, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doUpdateDeviceList, fakeAudioStream, fakeWebcamFrame, initialCloudRecordingState, initialLocalMediaState, isAcceptingStreams, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, observeStore, organizationSlice, parseRoomUrlAndSubdomain, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, resolutionReported, roomConnectionSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, type rtcAnalyticsState, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, selectAppDisplayName, selectAppExternalId, selectAppIsNodeSdk, selectAppRaw, selectAppRoomKey, selectAppRoomName, selectAppRoomUrl, selectAppUserAgent, selectAppWantsToJoin, selectBusyDeviceIds, selectCameraDeviceError, selectCameraDevices, selectChatMessages, selectChatRaw, selectCloudRecordingError, selectCloudRecordingRaw, selectCloudRecordingStartedAt, selectCloudRecordingStatus, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectDeviceCredentialsRaw, selectDeviceId, selectHasFetchedDeviceCredentials, selectIsAcceptingStreams, selectIsCameraEnabled, selectIsCloudRecording, selectIsLocalMediaStarting, selectIsMicrophoneEnabled, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsToggleCamera, selectLocalMediaConstraintsOptions, selectLocalMediaDevices, selectLocalMediaIsSwitchingStream, selectLocalMediaOptions, selectLocalMediaOwnsStream, selectLocalMediaRaw, selectLocalMediaShouldStartWithOptions, selectLocalMediaShouldStop, selectLocalMediaStartError, selectLocalMediaStatus, selectLocalMediaStream, selectLocalParticipantClientClaim, selectLocalParticipantIsScreenSharing, selectLocalParticipantRaw, selectLocalParticipantRole, selectLocalScreenshareRaw, selectLocalScreenshareStatus, selectLocalScreenshareStream, selectMicrophoneDeviceError, selectMicrophoneDevices, selectOrganizationId, selectOrganizationRaw, selectRemoteParticipants, selectRemoteParticipantsRaw, selectRoomConnectionError, selectRoomConnectionRaw, selectRoomConnectionSession, selectRoomConnectionSessionId, selectRoomConnectionStatus, selectRtcConnectionRaw, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectRtcManager, selectRtcManagerInitialized, selectRtcStatus, selectScreenshares, selectSelfId, selectShouldConnectRoom, selectShouldConnectRtc, selectShouldConnectSignal, selectShouldDisconnectRtc, selectShouldFetchDeviceCredentials, selectShouldFetchOrganization, selectShouldIdentifyDevice, selectShouldInitializeRtc, selectSignalConnectionDeviceIdentified, selectSignalConnectionRaw, selectSignalConnectionSocket, selectSignalIsIdentifyingDevice, selectSignalStatus, selectSpeakerDevices, selectStreamingRaw, selectStreamsToAccept, selectWaitingParticipants, selectWaitingParticipantsRaw, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setLocalMediaOptions, setLocalMediaStream, setRoomKey, signalConnectionSlice, socketConnected, socketConnecting, socketDisconnected, socketReconnecting, startAppListening, stopScreenshare, streamStatusUpdated, streamingSlice, toggleCameraEnabled, toggleMicrophoneEnabled, updateReportedValues, waitingParticipantsSlice };
|
package/dist/index.mjs
CHANGED
|
@@ -33,6 +33,8 @@ const createReactor = (selectors, callback) => {
|
|
|
33
33
|
});
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
const coreVersion = "0.9.1";
|
|
37
|
+
|
|
36
38
|
const initialState$c = {
|
|
37
39
|
isNodeSdk: false,
|
|
38
40
|
wantsToJoin: false,
|
|
@@ -40,7 +42,7 @@ const initialState$c = {
|
|
|
40
42
|
roomKey: null,
|
|
41
43
|
roomUrl: null,
|
|
42
44
|
displayName: null,
|
|
43
|
-
|
|
45
|
+
userAgent: `core:${coreVersion}`,
|
|
44
46
|
externalId: null,
|
|
45
47
|
};
|
|
46
48
|
const appSlice = createSlice({
|
|
@@ -66,7 +68,7 @@ const selectAppRoomName = (state) => state.app.roomName;
|
|
|
66
68
|
const selectAppRoomUrl = (state) => state.app.roomUrl;
|
|
67
69
|
const selectAppRoomKey = (state) => state.app.roomKey;
|
|
68
70
|
const selectAppDisplayName = (state) => state.app.displayName;
|
|
69
|
-
const
|
|
71
|
+
const selectAppUserAgent = (state) => state.app.userAgent;
|
|
70
72
|
const selectAppExternalId = (state) => state.app.externalId;
|
|
71
73
|
const selectAppIsNodeSdk = (state) => state.app.isNodeSdk;
|
|
72
74
|
|
|
@@ -404,6 +406,75 @@ const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
|
|
|
404
406
|
const selectCloudRecordingError = (state) => state.cloudRecording.error;
|
|
405
407
|
const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
|
|
406
408
|
|
|
409
|
+
function fakeAudioStream() {
|
|
410
|
+
const audioCtx = new AudioContext();
|
|
411
|
+
const oscillator = audioCtx.createOscillator();
|
|
412
|
+
const destination = audioCtx.createMediaStreamDestination();
|
|
413
|
+
oscillator.connect(destination);
|
|
414
|
+
oscillator.frequency.value = 400;
|
|
415
|
+
oscillator.type = "sine";
|
|
416
|
+
setInterval(() => {
|
|
417
|
+
if (oscillator.frequency.value <= 900) {
|
|
418
|
+
oscillator.frequency.value += 10;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
oscillator.frequency.value = 200;
|
|
422
|
+
}
|
|
423
|
+
}, 20);
|
|
424
|
+
oscillator.start();
|
|
425
|
+
return destination.stream;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let rotationAngle = 0;
|
|
429
|
+
function drawWebcamFrame(canvas) {
|
|
430
|
+
const context = canvas.getContext("2d");
|
|
431
|
+
if (!context) {
|
|
432
|
+
console.error("Canvas context not available");
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const wheelRadius = 100;
|
|
436
|
+
const wheelCenterX = canvas.width / 2;
|
|
437
|
+
const wheelCenterY = canvas.height / 2;
|
|
438
|
+
context.fillStyle = "darkgreen";
|
|
439
|
+
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
440
|
+
context.save();
|
|
441
|
+
context.translate(wheelCenterX, wheelCenterY);
|
|
442
|
+
context.rotate(rotationAngle);
|
|
443
|
+
const numSlices = 12;
|
|
444
|
+
const sliceAngle = (2 * Math.PI) / numSlices;
|
|
445
|
+
const colors = ["red", "orange", "yellow", "green", "blue", "purple"];
|
|
446
|
+
for (let i = 0; i < numSlices; i++) {
|
|
447
|
+
context.beginPath();
|
|
448
|
+
context.moveTo(0, 0);
|
|
449
|
+
context.arc(0, 0, wheelRadius, i * sliceAngle, (i + 1) * sliceAngle);
|
|
450
|
+
context.fillStyle = colors[i % colors.length];
|
|
451
|
+
context.fill();
|
|
452
|
+
context.closePath();
|
|
453
|
+
}
|
|
454
|
+
context.restore();
|
|
455
|
+
context.fillStyle = "white";
|
|
456
|
+
context.font = "42px Arial";
|
|
457
|
+
const topText = "Whereby Media Stream";
|
|
458
|
+
const topTextWidth = context.measureText(topText).width;
|
|
459
|
+
context.fillText(topText, canvas.width / 2 - topTextWidth / 2, 50);
|
|
460
|
+
context.font = "32px Arial";
|
|
461
|
+
const now = new Date();
|
|
462
|
+
const timeText = `time: ${now.getHours().toString().padStart(2, "0")}:${now
|
|
463
|
+
.getMinutes()
|
|
464
|
+
.toString()
|
|
465
|
+
.padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}.${now
|
|
466
|
+
.getMilliseconds()
|
|
467
|
+
.toString()
|
|
468
|
+
.padStart(3, "0")}`;
|
|
469
|
+
context.fillText(timeText, 10, canvas.height - 20);
|
|
470
|
+
context.fillText(`rotation angle: ${rotationAngle.toFixed(2)}`, canvas.width - canvas.width / 2, canvas.height - 20);
|
|
471
|
+
rotationAngle += 0.01;
|
|
472
|
+
}
|
|
473
|
+
function fakeWebcamFrame(canvas) {
|
|
474
|
+
drawWebcamFrame(canvas);
|
|
475
|
+
requestAnimationFrame(() => fakeWebcamFrame(canvas));
|
|
476
|
+
}
|
|
477
|
+
|
|
407
478
|
function debounce(fn, { delay = 500, edges } = {}) {
|
|
408
479
|
let timeout;
|
|
409
480
|
let nCalls = 0;
|
|
@@ -423,6 +494,25 @@ function debounce(fn, { delay = 500, edges } = {}) {
|
|
|
423
494
|
};
|
|
424
495
|
}
|
|
425
496
|
|
|
497
|
+
function parseRoomUrlAndSubdomain(roomAttribute, subdomainAttribute) {
|
|
498
|
+
if (!roomAttribute) {
|
|
499
|
+
throw new Error("Missing room attribute");
|
|
500
|
+
}
|
|
501
|
+
const m = /https:\/\/([^.]+)(\.whereby\.com|-ip-\d+-\d+-\d+-\d+.hereby.dev:4443)\/.+/.exec(roomAttribute);
|
|
502
|
+
const subdomain = (m && m[1]) || subdomainAttribute;
|
|
503
|
+
if (!subdomain) {
|
|
504
|
+
throw new Error("Missing subdomain attribute");
|
|
505
|
+
}
|
|
506
|
+
if (!m) {
|
|
507
|
+
throw new Error("Could not parse room URL");
|
|
508
|
+
}
|
|
509
|
+
const roomUrl = new URL(roomAttribute);
|
|
510
|
+
return {
|
|
511
|
+
subdomain,
|
|
512
|
+
roomUrl,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
|
|
426
516
|
const initialLocalMediaState = {
|
|
427
517
|
busyDeviceIds: [],
|
|
428
518
|
cameraEnabled: false,
|
|
@@ -1327,7 +1417,7 @@ const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
|
|
|
1327
1417
|
const roomName = selectAppRoomName(state);
|
|
1328
1418
|
const roomKey = selectAppRoomKey(state);
|
|
1329
1419
|
const displayName = selectAppDisplayName(state);
|
|
1330
|
-
const
|
|
1420
|
+
const userAgent = selectAppUserAgent(state);
|
|
1331
1421
|
const externalId = selectAppExternalId(state);
|
|
1332
1422
|
const organizationId = selectOrganizationId(state);
|
|
1333
1423
|
socket === null || socket === void 0 ? void 0 : socket.emit("knock_room", {
|
|
@@ -1345,7 +1435,7 @@ const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
|
|
|
1345
1435
|
roomKey,
|
|
1346
1436
|
roomName,
|
|
1347
1437
|
selfId: "",
|
|
1348
|
-
userAgent
|
|
1438
|
+
userAgent,
|
|
1349
1439
|
externalId,
|
|
1350
1440
|
});
|
|
1351
1441
|
dispatch(connectionStatusChanged("knocking"));
|
|
@@ -1356,7 +1446,7 @@ const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
|
|
|
1356
1446
|
const roomName = selectAppRoomName(state);
|
|
1357
1447
|
const roomKey = selectAppRoomKey(state);
|
|
1358
1448
|
const displayName = selectAppDisplayName(state);
|
|
1359
|
-
const
|
|
1449
|
+
const userAgent = selectAppUserAgent(state);
|
|
1360
1450
|
const externalId = selectAppExternalId(state);
|
|
1361
1451
|
const organizationId = selectOrganizationId(state);
|
|
1362
1452
|
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
@@ -1369,7 +1459,8 @@ const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
|
|
|
1369
1459
|
}, deviceCapabilities: { canScreenshare: true }, displayName, isCoLocated: false, isDevicePermissionDenied: false, kickFromOtherRooms: false, organizationId,
|
|
1370
1460
|
roomKey,
|
|
1371
1461
|
roomName,
|
|
1372
|
-
selfId }, (!!clientClaim && { clientClaim })), { userAgent
|
|
1462
|
+
selfId }, (!!clientClaim && { clientClaim })), { userAgent,
|
|
1463
|
+
externalId }));
|
|
1373
1464
|
dispatch(connectionStatusChanged("connecting"));
|
|
1374
1465
|
});
|
|
1375
1466
|
const selectRoomConnectionRaw = (state) => state.roomConnection;
|
|
@@ -2968,8 +3059,6 @@ class LocalParticipant extends RoomParticipant {
|
|
|
2968
3059
|
}
|
|
2969
3060
|
}
|
|
2970
3061
|
|
|
2971
|
-
const sdkVersion = "0.8.0";
|
|
2972
|
-
|
|
2973
3062
|
const API_BASE_URL = "https://api.whereby.dev" ;
|
|
2974
3063
|
function createServices() {
|
|
2975
3064
|
const credentialsService = CredentialsService.create({ baseUrl: API_BASE_URL });
|
|
@@ -2995,4 +3084,4 @@ function createServices() {
|
|
|
2995
3084
|
};
|
|
2996
3085
|
}
|
|
2997
3086
|
|
|
2998
|
-
export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, appLeft, appSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppJoin, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKnockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSetDevice, doSetDisplayName, doSetLocalParticipant, doSignalDisconnect, doSignalIdentifyDevice, doSignalReconnect, doSignalSocketConnect, doStartCloudRecording, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doUpdateDeviceList, initialCloudRecordingState, initialLocalMediaState, isAcceptingStreams, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, observeStore, organizationSlice, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, resolutionReported, roomConnectionSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized,
|
|
3087
|
+
export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, appLeft, appSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, debounce, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppJoin, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKnockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSetDevice, doSetDisplayName, doSetLocalParticipant, doSignalDisconnect, doSignalIdentifyDevice, doSignalReconnect, doSignalSocketConnect, doStartCloudRecording, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doUpdateDeviceList, fakeAudioStream, fakeWebcamFrame, initialCloudRecordingState, initialLocalMediaState, isAcceptingStreams, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, observeStore, organizationSlice, parseRoomUrlAndSubdomain, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, resolutionReported, roomConnectionSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, selectAppDisplayName, selectAppExternalId, selectAppIsNodeSdk, selectAppRaw, selectAppRoomKey, selectAppRoomName, selectAppRoomUrl, selectAppUserAgent, selectAppWantsToJoin, selectBusyDeviceIds, selectCameraDeviceError, selectCameraDevices, selectChatMessages, selectChatRaw, selectCloudRecordingError, selectCloudRecordingRaw, selectCloudRecordingStartedAt, selectCloudRecordingStatus, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectDeviceCredentialsRaw, selectDeviceId, selectHasFetchedDeviceCredentials, selectIsAcceptingStreams, selectIsCameraEnabled, selectIsCloudRecording, selectIsLocalMediaStarting, selectIsMicrophoneEnabled, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsToggleCamera, selectLocalMediaConstraintsOptions, selectLocalMediaDevices, selectLocalMediaIsSwitchingStream, selectLocalMediaOptions, selectLocalMediaOwnsStream, selectLocalMediaRaw, selectLocalMediaShouldStartWithOptions, selectLocalMediaShouldStop, selectLocalMediaStartError, selectLocalMediaStatus, selectLocalMediaStream, selectLocalParticipantClientClaim, selectLocalParticipantIsScreenSharing, selectLocalParticipantRaw, selectLocalParticipantRole, selectLocalScreenshareRaw, selectLocalScreenshareStatus, selectLocalScreenshareStream, selectMicrophoneDeviceError, selectMicrophoneDevices, selectOrganizationId, selectOrganizationRaw, selectRemoteParticipants, selectRemoteParticipantsRaw, selectRoomConnectionError, selectRoomConnectionRaw, selectRoomConnectionSession, selectRoomConnectionSessionId, selectRoomConnectionStatus, selectRtcConnectionRaw, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectRtcManager, selectRtcManagerInitialized, selectRtcStatus, selectScreenshares, selectSelfId, selectShouldConnectRoom, selectShouldConnectRtc, selectShouldConnectSignal, selectShouldDisconnectRtc, selectShouldFetchDeviceCredentials, selectShouldFetchOrganization, selectShouldIdentifyDevice, selectShouldInitializeRtc, selectSignalConnectionDeviceIdentified, selectSignalConnectionRaw, selectSignalConnectionSocket, selectSignalIsIdentifyingDevice, selectSignalStatus, selectSpeakerDevices, selectStreamingRaw, selectStreamsToAccept, selectWaitingParticipants, selectWaitingParticipantsRaw, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setLocalMediaOptions, setLocalMediaStream, setRoomKey, signalConnectionSlice, socketConnected, socketConnecting, socketDisconnected, socketReconnecting, startAppListening, stopScreenshare, streamStatusUpdated, streamingSlice, toggleCameraEnabled, toggleMicrophoneEnabled, updateReportedValues, waitingParticipantsSlice };
|
package/package.json
CHANGED
|
@@ -2,43 +2,39 @@
|
|
|
2
2
|
"name": "@whereby.com/core",
|
|
3
3
|
"description": "Core library for whereby.com sdk",
|
|
4
4
|
"author": "Whereby AS",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.9.1",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "rimraf dist && rollup -c rollup.config.js",
|
|
9
9
|
"test": "yarn test:lint && yarn test:unit",
|
|
10
10
|
"test:lint": "eslint src/",
|
|
11
11
|
"test:unit": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js",
|
|
12
|
-
"test:unit:watch": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --watch"
|
|
12
|
+
"test:unit:watch": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --watch",
|
|
13
|
+
"test:attw": "attw --pack . -f table"
|
|
13
14
|
},
|
|
14
15
|
"publishConfig": {
|
|
15
16
|
"access": "public"
|
|
16
17
|
},
|
|
17
18
|
"files": [
|
|
18
|
-
"dist
|
|
19
|
+
"dist/*.cjs",
|
|
19
20
|
"dist/*.mjs",
|
|
20
|
-
"dist/*.d.ts"
|
|
21
|
+
"dist/*.d.ts",
|
|
22
|
+
"dist/*.d.cts",
|
|
23
|
+
"dist/*.d.mts"
|
|
21
24
|
],
|
|
22
|
-
"main": "
|
|
25
|
+
"main": "dist/index.cjs",
|
|
26
|
+
"module": "dist/legacy-esm.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
23
28
|
"exports": {
|
|
24
29
|
".": {
|
|
25
|
-
"import":
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"types": "dist/index.d.ts",
|
|
34
|
-
"typesVersions": {
|
|
35
|
-
"*": {
|
|
36
|
-
"*": [
|
|
37
|
-
"dist/index.d.ts"
|
|
38
|
-
],
|
|
39
|
-
"utils": [
|
|
40
|
-
"dist/utils.d.ts"
|
|
41
|
-
]
|
|
30
|
+
"import": {
|
|
31
|
+
"default": "./dist/index.mjs",
|
|
32
|
+
"types": "./dist/index.d.mts"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"default": "./dist/index.cjs",
|
|
36
|
+
"types": "./dist/index.d.cts"
|
|
37
|
+
}
|
|
42
38
|
}
|
|
43
39
|
},
|
|
44
40
|
"devDependencies": {
|
package/dist/cjs/utils.cjs
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function fakeAudioStream() {
|
|
4
|
-
const audioCtx = new AudioContext();
|
|
5
|
-
const oscillator = audioCtx.createOscillator();
|
|
6
|
-
const destination = audioCtx.createMediaStreamDestination();
|
|
7
|
-
oscillator.connect(destination);
|
|
8
|
-
oscillator.frequency.value = 400;
|
|
9
|
-
oscillator.type = "sine";
|
|
10
|
-
setInterval(() => {
|
|
11
|
-
if (oscillator.frequency.value <= 900) {
|
|
12
|
-
oscillator.frequency.value += 10;
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
oscillator.frequency.value = 200;
|
|
16
|
-
}
|
|
17
|
-
}, 20);
|
|
18
|
-
oscillator.start();
|
|
19
|
-
return destination.stream;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let rotationAngle = 0;
|
|
23
|
-
function drawWebcamFrame(canvas) {
|
|
24
|
-
const context = canvas.getContext("2d");
|
|
25
|
-
if (!context) {
|
|
26
|
-
console.error("Canvas context not available");
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const wheelRadius = 100;
|
|
30
|
-
const wheelCenterX = canvas.width / 2;
|
|
31
|
-
const wheelCenterY = canvas.height / 2;
|
|
32
|
-
context.fillStyle = "darkgreen";
|
|
33
|
-
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
34
|
-
context.save();
|
|
35
|
-
context.translate(wheelCenterX, wheelCenterY);
|
|
36
|
-
context.rotate(rotationAngle);
|
|
37
|
-
const numSlices = 12;
|
|
38
|
-
const sliceAngle = (2 * Math.PI) / numSlices;
|
|
39
|
-
const colors = ["red", "orange", "yellow", "green", "blue", "purple"];
|
|
40
|
-
for (let i = 0; i < numSlices; i++) {
|
|
41
|
-
context.beginPath();
|
|
42
|
-
context.moveTo(0, 0);
|
|
43
|
-
context.arc(0, 0, wheelRadius, i * sliceAngle, (i + 1) * sliceAngle);
|
|
44
|
-
context.fillStyle = colors[i % colors.length];
|
|
45
|
-
context.fill();
|
|
46
|
-
context.closePath();
|
|
47
|
-
}
|
|
48
|
-
context.restore();
|
|
49
|
-
context.fillStyle = "white";
|
|
50
|
-
context.font = "42px Arial";
|
|
51
|
-
const topText = "Whereby Media Stream";
|
|
52
|
-
const topTextWidth = context.measureText(topText).width;
|
|
53
|
-
context.fillText(topText, canvas.width / 2 - topTextWidth / 2, 50);
|
|
54
|
-
context.font = "32px Arial";
|
|
55
|
-
const now = new Date();
|
|
56
|
-
const timeText = `time: ${now.getHours().toString().padStart(2, "0")}:${now
|
|
57
|
-
.getMinutes()
|
|
58
|
-
.toString()
|
|
59
|
-
.padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}.${now
|
|
60
|
-
.getMilliseconds()
|
|
61
|
-
.toString()
|
|
62
|
-
.padStart(3, "0")}`;
|
|
63
|
-
context.fillText(timeText, 10, canvas.height - 20);
|
|
64
|
-
context.fillText(`rotation angle: ${rotationAngle.toFixed(2)}`, canvas.width - canvas.width / 2, canvas.height - 20);
|
|
65
|
-
rotationAngle += 0.01;
|
|
66
|
-
}
|
|
67
|
-
function fakeWebcamFrame(canvas) {
|
|
68
|
-
drawWebcamFrame(canvas);
|
|
69
|
-
requestAnimationFrame(() => fakeWebcamFrame(canvas));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function debounce(fn, { delay = 500, edges } = {}) {
|
|
73
|
-
let timeout;
|
|
74
|
-
let nCalls = 0;
|
|
75
|
-
return (...args) => {
|
|
76
|
-
nCalls += 1;
|
|
77
|
-
if (edges && nCalls === 1) {
|
|
78
|
-
fn(...args);
|
|
79
|
-
}
|
|
80
|
-
clearTimeout(timeout);
|
|
81
|
-
timeout = setTimeout(() => {
|
|
82
|
-
if (!edges || nCalls > 1) {
|
|
83
|
-
fn(...args);
|
|
84
|
-
}
|
|
85
|
-
timeout = undefined;
|
|
86
|
-
nCalls = 0;
|
|
87
|
-
}, delay);
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function parseRoomUrlAndSubdomain(roomAttribute, subdomainAttribute) {
|
|
92
|
-
if (!roomAttribute) {
|
|
93
|
-
throw new Error("Missing room attribute");
|
|
94
|
-
}
|
|
95
|
-
const m = /https:\/\/([^.]+)(\.whereby\.com|-ip-\d+-\d+-\d+-\d+.hereby.dev:4443)\/.+/.exec(roomAttribute);
|
|
96
|
-
const subdomain = (m && m[1]) || subdomainAttribute;
|
|
97
|
-
if (!subdomain) {
|
|
98
|
-
throw new Error("Missing subdomain attribute");
|
|
99
|
-
}
|
|
100
|
-
if (!m) {
|
|
101
|
-
throw new Error("Could not parse room URL");
|
|
102
|
-
}
|
|
103
|
-
const roomUrl = new URL(roomAttribute);
|
|
104
|
-
return {
|
|
105
|
-
subdomain,
|
|
106
|
-
roomUrl,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
exports.debounce = debounce;
|
|
111
|
-
exports.fakeAudioStream = fakeAudioStream;
|
|
112
|
-
exports.fakeWebcamFrame = fakeWebcamFrame;
|
|
113
|
-
exports.parseRoomUrlAndSubdomain = parseRoomUrlAndSubdomain;
|
package/dist/utils.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
declare function fakeAudioStream(): MediaStream;
|
|
2
|
-
|
|
3
|
-
declare function fakeWebcamFrame(canvas: HTMLCanvasElement): void;
|
|
4
|
-
|
|
5
|
-
interface Options {
|
|
6
|
-
delay?: number;
|
|
7
|
-
edges?: boolean;
|
|
8
|
-
}
|
|
9
|
-
interface DebouncedFunction {
|
|
10
|
-
(...args: any[]): void;
|
|
11
|
-
}
|
|
12
|
-
declare function debounce(fn: DebouncedFunction, { delay, edges }?: Options): DebouncedFunction;
|
|
13
|
-
|
|
14
|
-
declare function parseRoomUrlAndSubdomain(roomAttribute?: string, subdomainAttribute?: string): {
|
|
15
|
-
subdomain: string;
|
|
16
|
-
roomUrl: URL;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export { debounce, fakeAudioStream, fakeWebcamFrame, parseRoomUrlAndSubdomain };
|
package/dist/utils.mjs
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
function fakeAudioStream() {
|
|
2
|
-
const audioCtx = new AudioContext();
|
|
3
|
-
const oscillator = audioCtx.createOscillator();
|
|
4
|
-
const destination = audioCtx.createMediaStreamDestination();
|
|
5
|
-
oscillator.connect(destination);
|
|
6
|
-
oscillator.frequency.value = 400;
|
|
7
|
-
oscillator.type = "sine";
|
|
8
|
-
setInterval(() => {
|
|
9
|
-
if (oscillator.frequency.value <= 900) {
|
|
10
|
-
oscillator.frequency.value += 10;
|
|
11
|
-
}
|
|
12
|
-
else {
|
|
13
|
-
oscillator.frequency.value = 200;
|
|
14
|
-
}
|
|
15
|
-
}, 20);
|
|
16
|
-
oscillator.start();
|
|
17
|
-
return destination.stream;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let rotationAngle = 0;
|
|
21
|
-
function drawWebcamFrame(canvas) {
|
|
22
|
-
const context = canvas.getContext("2d");
|
|
23
|
-
if (!context) {
|
|
24
|
-
console.error("Canvas context not available");
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
const wheelRadius = 100;
|
|
28
|
-
const wheelCenterX = canvas.width / 2;
|
|
29
|
-
const wheelCenterY = canvas.height / 2;
|
|
30
|
-
context.fillStyle = "darkgreen";
|
|
31
|
-
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
32
|
-
context.save();
|
|
33
|
-
context.translate(wheelCenterX, wheelCenterY);
|
|
34
|
-
context.rotate(rotationAngle);
|
|
35
|
-
const numSlices = 12;
|
|
36
|
-
const sliceAngle = (2 * Math.PI) / numSlices;
|
|
37
|
-
const colors = ["red", "orange", "yellow", "green", "blue", "purple"];
|
|
38
|
-
for (let i = 0; i < numSlices; i++) {
|
|
39
|
-
context.beginPath();
|
|
40
|
-
context.moveTo(0, 0);
|
|
41
|
-
context.arc(0, 0, wheelRadius, i * sliceAngle, (i + 1) * sliceAngle);
|
|
42
|
-
context.fillStyle = colors[i % colors.length];
|
|
43
|
-
context.fill();
|
|
44
|
-
context.closePath();
|
|
45
|
-
}
|
|
46
|
-
context.restore();
|
|
47
|
-
context.fillStyle = "white";
|
|
48
|
-
context.font = "42px Arial";
|
|
49
|
-
const topText = "Whereby Media Stream";
|
|
50
|
-
const topTextWidth = context.measureText(topText).width;
|
|
51
|
-
context.fillText(topText, canvas.width / 2 - topTextWidth / 2, 50);
|
|
52
|
-
context.font = "32px Arial";
|
|
53
|
-
const now = new Date();
|
|
54
|
-
const timeText = `time: ${now.getHours().toString().padStart(2, "0")}:${now
|
|
55
|
-
.getMinutes()
|
|
56
|
-
.toString()
|
|
57
|
-
.padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}.${now
|
|
58
|
-
.getMilliseconds()
|
|
59
|
-
.toString()
|
|
60
|
-
.padStart(3, "0")}`;
|
|
61
|
-
context.fillText(timeText, 10, canvas.height - 20);
|
|
62
|
-
context.fillText(`rotation angle: ${rotationAngle.toFixed(2)}`, canvas.width - canvas.width / 2, canvas.height - 20);
|
|
63
|
-
rotationAngle += 0.01;
|
|
64
|
-
}
|
|
65
|
-
function fakeWebcamFrame(canvas) {
|
|
66
|
-
drawWebcamFrame(canvas);
|
|
67
|
-
requestAnimationFrame(() => fakeWebcamFrame(canvas));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function debounce(fn, { delay = 500, edges } = {}) {
|
|
71
|
-
let timeout;
|
|
72
|
-
let nCalls = 0;
|
|
73
|
-
return (...args) => {
|
|
74
|
-
nCalls += 1;
|
|
75
|
-
if (edges && nCalls === 1) {
|
|
76
|
-
fn(...args);
|
|
77
|
-
}
|
|
78
|
-
clearTimeout(timeout);
|
|
79
|
-
timeout = setTimeout(() => {
|
|
80
|
-
if (!edges || nCalls > 1) {
|
|
81
|
-
fn(...args);
|
|
82
|
-
}
|
|
83
|
-
timeout = undefined;
|
|
84
|
-
nCalls = 0;
|
|
85
|
-
}, delay);
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function parseRoomUrlAndSubdomain(roomAttribute, subdomainAttribute) {
|
|
90
|
-
if (!roomAttribute) {
|
|
91
|
-
throw new Error("Missing room attribute");
|
|
92
|
-
}
|
|
93
|
-
const m = /https:\/\/([^.]+)(\.whereby\.com|-ip-\d+-\d+-\d+-\d+.hereby.dev:4443)\/.+/.exec(roomAttribute);
|
|
94
|
-
const subdomain = (m && m[1]) || subdomainAttribute;
|
|
95
|
-
if (!subdomain) {
|
|
96
|
-
throw new Error("Missing subdomain attribute");
|
|
97
|
-
}
|
|
98
|
-
if (!m) {
|
|
99
|
-
throw new Error("Could not parse room URL");
|
|
100
|
-
}
|
|
101
|
-
const roomUrl = new URL(roomAttribute);
|
|
102
|
-
return {
|
|
103
|
-
subdomain,
|
|
104
|
-
roomUrl,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export { debounce, fakeAudioStream, fakeWebcamFrame, parseRoomUrlAndSubdomain };
|