@dialtribe/react-sdk 0.1.0-alpha.20 → 0.1.0-alpha.21

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.
@@ -203,13 +203,33 @@ declare class WebSocketStreamer {
203
203
  private onBytesUpdate?;
204
204
  private onStateChange?;
205
205
  private onError?;
206
+ private canvasState;
206
207
  constructor(options: WebSocketStreamerOptions);
208
+ /**
209
+ * Calculate scaled dimensions for fitting video into canvas.
210
+ * @param mode - "contain" fits video inside canvas, "cover" fills canvas (cropping)
211
+ */
212
+ private calculateScaledDimensions;
213
+ /**
214
+ * Invalidate cached scaling dimensions (call when video source changes)
215
+ */
216
+ private invalidateScalingCache;
207
217
  /**
208
218
  * Validate stream key format
209
219
  * Stream keys must follow format: {tierCode}{foreignId}_{randomKey}
210
220
  * Tier codes: a (audio shared), b (audio VIP), v (video shared), w (video VIP)
211
221
  */
212
222
  private validateStreamKeyFormat;
223
+ /**
224
+ * Set up canvas-based rendering pipeline for video streams.
225
+ * This allows seamless camera flips by changing the video source
226
+ * without affecting MediaRecorder (which records from the canvas).
227
+ */
228
+ private setupCanvasRendering;
229
+ /**
230
+ * Clean up canvas rendering resources
231
+ */
232
+ private cleanupCanvasRendering;
213
233
  /**
214
234
  * Build WebSocket URL from stream key
215
235
  */
@@ -226,16 +246,20 @@ declare class WebSocketStreamer {
226
246
  * Get total bytes sent
227
247
  */
228
248
  getBytesSent(): number;
249
+ /**
250
+ * Get the current source media stream.
251
+ * This may change after replaceVideoTrack() is called.
252
+ */
253
+ getMediaStream(): MediaStream;
229
254
  /**
230
255
  * Get current diagnostics
231
256
  */
232
257
  private getDiagnostics;
233
258
  /**
234
- * Replace the video track in the current MediaStream without stopping MediaRecorder.
235
- * This avoids sending a new WebM header, which FFmpeg can't handle mid-stream.
259
+ * Replace the video track for camera flips.
236
260
  *
237
- * IMPORTANT: This is the preferred method for camera flips as it maintains
238
- * continuous WebM stream without container restarts.
261
+ * When using canvas-based rendering (video streams), this updates the video
262
+ * element source. The canvas continues drawing, and MediaRecorder is unaffected.
239
263
  *
240
264
  * @param newVideoTrack - The new video track from the flipped camera
241
265
  */
@@ -247,46 +271,12 @@ declare class WebSocketStreamer {
247
271
  */
248
272
  replaceAudioTrack(newAudioTrack: MediaStreamTrack): void;
249
273
  /**
250
- * Prepare for a hot-swap by stopping the MediaRecorder
251
- * Call this BEFORE requesting a new camera stream on iOS
252
- * This prevents iOS Safari from interfering with the active MediaRecorder
253
- *
254
- * IMPORTANT: This is async because we must wait for the MediaRecorder's 'stop'
255
- * event to fire BEFORE proceeding. Otherwise there's a race condition where
256
- * the stop event fires after isHotSwapping is set to false, causing the
257
- * WebSocket to close unexpectedly.
258
- *
259
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
260
- */
261
- prepareForHotSwap(): Promise<void>;
262
- /**
263
- * Cancel a prepared hot-swap (e.g., if camera switch failed)
264
- * Restarts the MediaRecorder with the existing stream
265
- *
266
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
267
- */
268
- cancelHotSwap(): void;
269
- /**
270
- * Complete the hot-swap with a new media stream
271
- * Call this AFTER successfully obtaining a new camera stream
272
- *
273
- * Note: Errors are thrown to the caller, not sent to onError callback
274
- * This allows the caller to handle camera flip failures gracefully
275
- *
276
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
277
- */
278
- completeHotSwap(newMediaStream: MediaStream): void;
279
- /**
280
- * Update the media stream (e.g., when flipping camera)
281
- * This keeps the WebSocket connection alive while swapping the media source
282
- *
283
- * Note: On iOS, prefer using prepareForHotSwap() + completeHotSwap() to avoid
284
- * issues where getUserMedia interferes with the active MediaRecorder.
285
- *
286
- * Note: Errors are thrown to the caller, not sent to onError callback
287
- * This allows the caller to handle camera flip failures gracefully
274
+ * Update the media stream (e.g., when switching devices from settings)
275
+ * This keeps the WebSocket connection alive while swapping the media source.
276
+ * Restarts the MediaRecorder with the new stream.
288
277
  *
289
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
278
+ * Note: For camera flips, prefer replaceVideoTrack() which doesn't restart MediaRecorder.
279
+ * Note: Errors are thrown to the caller, not sent to onError callback.
290
280
  */
291
281
  updateMediaStream(newMediaStream: MediaStream): Promise<void>;
292
282
  /**
@@ -203,13 +203,33 @@ declare class WebSocketStreamer {
203
203
  private onBytesUpdate?;
204
204
  private onStateChange?;
205
205
  private onError?;
206
+ private canvasState;
206
207
  constructor(options: WebSocketStreamerOptions);
208
+ /**
209
+ * Calculate scaled dimensions for fitting video into canvas.
210
+ * @param mode - "contain" fits video inside canvas, "cover" fills canvas (cropping)
211
+ */
212
+ private calculateScaledDimensions;
213
+ /**
214
+ * Invalidate cached scaling dimensions (call when video source changes)
215
+ */
216
+ private invalidateScalingCache;
207
217
  /**
208
218
  * Validate stream key format
209
219
  * Stream keys must follow format: {tierCode}{foreignId}_{randomKey}
210
220
  * Tier codes: a (audio shared), b (audio VIP), v (video shared), w (video VIP)
211
221
  */
212
222
  private validateStreamKeyFormat;
223
+ /**
224
+ * Set up canvas-based rendering pipeline for video streams.
225
+ * This allows seamless camera flips by changing the video source
226
+ * without affecting MediaRecorder (which records from the canvas).
227
+ */
228
+ private setupCanvasRendering;
229
+ /**
230
+ * Clean up canvas rendering resources
231
+ */
232
+ private cleanupCanvasRendering;
213
233
  /**
214
234
  * Build WebSocket URL from stream key
215
235
  */
@@ -226,16 +246,20 @@ declare class WebSocketStreamer {
226
246
  * Get total bytes sent
227
247
  */
228
248
  getBytesSent(): number;
249
+ /**
250
+ * Get the current source media stream.
251
+ * This may change after replaceVideoTrack() is called.
252
+ */
253
+ getMediaStream(): MediaStream;
229
254
  /**
230
255
  * Get current diagnostics
231
256
  */
232
257
  private getDiagnostics;
233
258
  /**
234
- * Replace the video track in the current MediaStream without stopping MediaRecorder.
235
- * This avoids sending a new WebM header, which FFmpeg can't handle mid-stream.
259
+ * Replace the video track for camera flips.
236
260
  *
237
- * IMPORTANT: This is the preferred method for camera flips as it maintains
238
- * continuous WebM stream without container restarts.
261
+ * When using canvas-based rendering (video streams), this updates the video
262
+ * element source. The canvas continues drawing, and MediaRecorder is unaffected.
239
263
  *
240
264
  * @param newVideoTrack - The new video track from the flipped camera
241
265
  */
@@ -247,46 +271,12 @@ declare class WebSocketStreamer {
247
271
  */
248
272
  replaceAudioTrack(newAudioTrack: MediaStreamTrack): void;
249
273
  /**
250
- * Prepare for a hot-swap by stopping the MediaRecorder
251
- * Call this BEFORE requesting a new camera stream on iOS
252
- * This prevents iOS Safari from interfering with the active MediaRecorder
253
- *
254
- * IMPORTANT: This is async because we must wait for the MediaRecorder's 'stop'
255
- * event to fire BEFORE proceeding. Otherwise there's a race condition where
256
- * the stop event fires after isHotSwapping is set to false, causing the
257
- * WebSocket to close unexpectedly.
258
- *
259
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
260
- */
261
- prepareForHotSwap(): Promise<void>;
262
- /**
263
- * Cancel a prepared hot-swap (e.g., if camera switch failed)
264
- * Restarts the MediaRecorder with the existing stream
265
- *
266
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
267
- */
268
- cancelHotSwap(): void;
269
- /**
270
- * Complete the hot-swap with a new media stream
271
- * Call this AFTER successfully obtaining a new camera stream
272
- *
273
- * Note: Errors are thrown to the caller, not sent to onError callback
274
- * This allows the caller to handle camera flip failures gracefully
275
- *
276
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
277
- */
278
- completeHotSwap(newMediaStream: MediaStream): void;
279
- /**
280
- * Update the media stream (e.g., when flipping camera)
281
- * This keeps the WebSocket connection alive while swapping the media source
282
- *
283
- * Note: On iOS, prefer using prepareForHotSwap() + completeHotSwap() to avoid
284
- * issues where getUserMedia interferes with the active MediaRecorder.
285
- *
286
- * Note: Errors are thrown to the caller, not sent to onError callback
287
- * This allows the caller to handle camera flip failures gracefully
274
+ * Update the media stream (e.g., when switching devices from settings)
275
+ * This keeps the WebSocket connection alive while swapping the media source.
276
+ * Restarts the MediaRecorder with the new stream.
288
277
  *
289
- * @deprecated Prefer replaceVideoTrack() which doesn't restart MediaRecorder
278
+ * Note: For camera flips, prefer replaceVideoTrack() which doesn't restart MediaRecorder.
279
+ * Note: Errors are thrown to the caller, not sent to onError callback.
290
280
  */
291
281
  updateMediaStream(newMediaStream: MediaStream): Promise<void>;
292
282
  /**
@@ -1,4 +1,4 @@
1
1
  export { A as ApiClientConfig, h as AudioWaveform, B as Broadcast, C as CDN_DOMAIN, d as DIALTRIBE_API_BASE, c as DialtribeClient, a as DialtribeContextValue, i as DialtribeOverlay, k as DialtribeOverlayMode, j as DialtribeOverlayProps, e as DialtribePlayer, g as DialtribePlayerErrorBoundary, f as DialtribePlayerProps, D as DialtribeProvider, b as DialtribeProviderProps, E as ENDPOINTS, H as HTTP_STATUS, q as HttpStatusCode, L as LoadingSpinner, m as TranscriptData, l as TranscriptSegment, T as TranscriptWord, o as buildBroadcastCdnUrl, p as buildBroadcastS3KeyPrefix, n as formatTime, u as useDialtribe, r as useDialtribeOptional } from './dialtribe-player-CNriUtNi.mjs';
2
- export { j as DEFAULT_ENCODER_SERVER_URL, D as DialtribeStreamer, a as DialtribeStreamerProps, M as MediaConstraintsOptions, O as OpenDialtribeStreamerPopupOptions, P as PopupDimensions, w as PopupFallbackMode, f as StreamKeyDisplay, g as StreamKeyDisplayProps, h as StreamKeyInput, i as StreamKeyInputProps, e as StreamingControlState, c as StreamingControls, d as StreamingControlsProps, S as StreamingPreview, b as StreamingPreviewProps, t as UseDialtribeStreamerLauncherOptions, v as UseDialtribeStreamerLauncherReturn, U as UseDialtribeStreamerPopupReturn, W as WebSocketStreamer, k as WebSocketStreamerOptions, r as calculatePopupDimensions, o as checkBrowserCompatibility, m as getMediaConstraints, n as getMediaRecorderOptions, q as openBroadcastPopup, p as openDialtribeStreamerPopup, s as useDialtribeStreamerLauncher, u as useDialtribeStreamerPopup } from './dialtribe-streamer-DHr_bgtO.mjs';
2
+ export { j as DEFAULT_ENCODER_SERVER_URL, D as DialtribeStreamer, a as DialtribeStreamerProps, M as MediaConstraintsOptions, O as OpenDialtribeStreamerPopupOptions, P as PopupDimensions, w as PopupFallbackMode, f as StreamKeyDisplay, g as StreamKeyDisplayProps, h as StreamKeyInput, i as StreamKeyInputProps, e as StreamingControlState, c as StreamingControls, d as StreamingControlsProps, S as StreamingPreview, b as StreamingPreviewProps, t as UseDialtribeStreamerLauncherOptions, v as UseDialtribeStreamerLauncherReturn, U as UseDialtribeStreamerPopupReturn, W as WebSocketStreamer, k as WebSocketStreamerOptions, r as calculatePopupDimensions, o as checkBrowserCompatibility, m as getMediaConstraints, n as getMediaRecorderOptions, q as openBroadcastPopup, p as openDialtribeStreamerPopup, s as useDialtribeStreamerLauncher, u as useDialtribeStreamerPopup } from './dialtribe-streamer-DH23BseY.mjs';
3
3
  import 'react/jsx-runtime';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
1
  export { A as ApiClientConfig, h as AudioWaveform, B as Broadcast, C as CDN_DOMAIN, d as DIALTRIBE_API_BASE, c as DialtribeClient, a as DialtribeContextValue, i as DialtribeOverlay, k as DialtribeOverlayMode, j as DialtribeOverlayProps, e as DialtribePlayer, g as DialtribePlayerErrorBoundary, f as DialtribePlayerProps, D as DialtribeProvider, b as DialtribeProviderProps, E as ENDPOINTS, H as HTTP_STATUS, q as HttpStatusCode, L as LoadingSpinner, m as TranscriptData, l as TranscriptSegment, T as TranscriptWord, o as buildBroadcastCdnUrl, p as buildBroadcastS3KeyPrefix, n as formatTime, u as useDialtribe, r as useDialtribeOptional } from './dialtribe-player-CNriUtNi.js';
2
- export { j as DEFAULT_ENCODER_SERVER_URL, D as DialtribeStreamer, a as DialtribeStreamerProps, M as MediaConstraintsOptions, O as OpenDialtribeStreamerPopupOptions, P as PopupDimensions, w as PopupFallbackMode, f as StreamKeyDisplay, g as StreamKeyDisplayProps, h as StreamKeyInput, i as StreamKeyInputProps, e as StreamingControlState, c as StreamingControls, d as StreamingControlsProps, S as StreamingPreview, b as StreamingPreviewProps, t as UseDialtribeStreamerLauncherOptions, v as UseDialtribeStreamerLauncherReturn, U as UseDialtribeStreamerPopupReturn, W as WebSocketStreamer, k as WebSocketStreamerOptions, r as calculatePopupDimensions, o as checkBrowserCompatibility, m as getMediaConstraints, n as getMediaRecorderOptions, q as openBroadcastPopup, p as openDialtribeStreamerPopup, s as useDialtribeStreamerLauncher, u as useDialtribeStreamerPopup } from './dialtribe-streamer-DGDbUw0Z.js';
2
+ export { j as DEFAULT_ENCODER_SERVER_URL, D as DialtribeStreamer, a as DialtribeStreamerProps, M as MediaConstraintsOptions, O as OpenDialtribeStreamerPopupOptions, P as PopupDimensions, w as PopupFallbackMode, f as StreamKeyDisplay, g as StreamKeyDisplayProps, h as StreamKeyInput, i as StreamKeyInputProps, e as StreamingControlState, c as StreamingControls, d as StreamingControlsProps, S as StreamingPreview, b as StreamingPreviewProps, t as UseDialtribeStreamerLauncherOptions, v as UseDialtribeStreamerLauncherReturn, U as UseDialtribeStreamerPopupReturn, W as WebSocketStreamer, k as WebSocketStreamerOptions, r as calculatePopupDimensions, o as checkBrowserCompatibility, m as getMediaConstraints, n as getMediaRecorderOptions, q as openBroadcastPopup, p as openDialtribeStreamerPopup, s as useDialtribeStreamerLauncher, u as useDialtribeStreamerPopup } from './dialtribe-streamer-D9ulVBVb.js';
3
3
  import 'react/jsx-runtime';
4
4
  import 'react';