@dialtribe/react-sdk 0.1.0-alpha.12 → 0.1.0-alpha.15

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.mjs CHANGED
@@ -2260,7 +2260,10 @@ var WebSocketStreamer = class {
2260
2260
  this.websocket = null;
2261
2261
  this.mediaRecorder = null;
2262
2262
  this.bytesSent = 0;
2263
+ this.chunksSent = 0;
2263
2264
  this.userStopped = false;
2265
+ // Track if user initiated the stop
2266
+ this.startTime = 0;
2264
2267
  this.streamKey = options.streamKey;
2265
2268
  this.mediaStream = options.mediaStream;
2266
2269
  this.isVideo = options.isVideo;
@@ -2351,10 +2354,12 @@ Please check encoder server logs and DATABASE_URL configuration.`
2351
2354
  console.log("\u2705 WebSocket connected");
2352
2355
  this.setupWebSocketHandlers();
2353
2356
  const recorderOptions = getMediaRecorderOptions(this.isVideo);
2357
+ this.mimeType = recorderOptions.mimeType;
2354
2358
  this.mediaRecorder = new MediaRecorder(this.mediaStream, recorderOptions);
2355
2359
  console.log("\u{1F399}\uFE0F MediaRecorder created with options:", recorderOptions);
2356
2360
  this.setupMediaRecorderHandlers();
2357
2361
  this.mediaRecorder.start(300);
2362
+ this.startTime = Date.now();
2358
2363
  console.log("\u{1F534} Recording started");
2359
2364
  this.onStateChange?.("live");
2360
2365
  } catch (error) {
@@ -2399,6 +2404,19 @@ Please check encoder server logs and DATABASE_URL configuration.`
2399
2404
  getBytesSent() {
2400
2405
  return this.bytesSent;
2401
2406
  }
2407
+ /**
2408
+ * Get current diagnostics
2409
+ */
2410
+ getDiagnostics(closeCode, closeReason) {
2411
+ return {
2412
+ mimeType: this.mimeType,
2413
+ chunksSent: this.chunksSent,
2414
+ bytesSent: this.bytesSent,
2415
+ elapsedMs: this.startTime ? Date.now() - this.startTime : 0,
2416
+ closeCode,
2417
+ closeReason
2418
+ };
2419
+ }
2402
2420
  /**
2403
2421
  * Update the media stream (e.g., when flipping camera)
2404
2422
  * This keeps the WebSocket connection alive while swapping the media source
@@ -2428,9 +2446,22 @@ Please check encoder server logs and DATABASE_URL configuration.`
2428
2446
  this.websocket.addEventListener("close", (event) => {
2429
2447
  console.log("\u{1F50C} WebSocket closed", { code: event.code, reason: event.reason });
2430
2448
  if (!this.userStopped) {
2431
- console.warn("\u26A0\uFE0F Stream was terminated remotely (not user-initiated)");
2449
+ const diagnostics = this.getDiagnostics(event.code, event.reason);
2450
+ console.warn("\u26A0\uFE0F Stream ended unexpectedly", diagnostics);
2451
+ let errorMessage;
2452
+ if (event.code === 1e3) {
2453
+ errorMessage = event.reason || "Stream ended by server";
2454
+ } else if (event.code === 1001) {
2455
+ errorMessage = "Connection closed - server going away";
2456
+ } else if (event.code === 1006) {
2457
+ errorMessage = "Connection lost unexpectedly";
2458
+ } else if (event.code >= 4e3 && event.code < 5e3) {
2459
+ errorMessage = event.reason || "Stream terminated by server";
2460
+ } else {
2461
+ errorMessage = `Connection closed (code: ${event.code})`;
2462
+ }
2432
2463
  this.onStateChange?.("terminated");
2433
- this.onError?.("Your stream was terminated by an administrator");
2464
+ this.onError?.(errorMessage, diagnostics);
2434
2465
  }
2435
2466
  if (this.mediaRecorder && this.mediaRecorder.state !== "inactive") {
2436
2467
  this.mediaRecorder.stop();
@@ -2451,8 +2482,9 @@ Please check encoder server logs and DATABASE_URL configuration.`
2451
2482
  if (event.data.size > 0 && this.websocket?.readyState === WebSocket.OPEN) {
2452
2483
  this.websocket.send(event.data);
2453
2484
  this.bytesSent += event.data.size;
2485
+ this.chunksSent += 1;
2454
2486
  this.onBytesUpdate?.(this.bytesSent);
2455
- console.log(`\u{1F4E4} Sent ${(event.data.size / 1024).toFixed(2)} KB (Total: ${(this.bytesSent / 1024 / 1024).toFixed(2)} MB)`);
2487
+ console.log(`\u{1F4E4} Sent chunk #${this.chunksSent}: ${(event.data.size / 1024).toFixed(2)} KB (Total: ${(this.bytesSent / 1024 / 1024).toFixed(2)} MB)`);
2456
2488
  }
2457
2489
  });
2458
2490
  this.mediaRecorder.addEventListener("error", (event) => {
@@ -3085,6 +3117,7 @@ function DialtribeStreamer({
3085
3117
  }
3086
3118
  }, [initialStreamKey]);
3087
3119
  const [error, setError] = useState(null);
3120
+ const [diagnostics, setDiagnostics] = useState(null);
3088
3121
  const [mediaStream, setMediaStream] = useState(null);
3089
3122
  const [streamer, setStreamer] = useState(null);
3090
3123
  const [bytesSent, setBytesSent] = useState(0);
@@ -3281,9 +3314,11 @@ function DialtribeStreamer({
3281
3314
  setState("error");
3282
3315
  }
3283
3316
  },
3284
- onError: (errorMsg) => {
3317
+ onError: (errorMsg, diag) => {
3285
3318
  setError(errorMsg);
3286
- setState("error");
3319
+ if (diag) {
3320
+ setDiagnostics(diag);
3321
+ }
3287
3322
  }
3288
3323
  });
3289
3324
  await newStreamer.start();
@@ -3568,13 +3603,37 @@ function DialtribeStreamer({
3568
3603
  )
3569
3604
  }
3570
3605
  ) }),
3571
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-black dark:text-white mb-2", children: "Stream Terminated" }),
3572
- /* @__PURE__ */ jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-2", children: error || "Your broadcast was terminated by an administrator." }),
3573
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-6", children: [
3606
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-black dark:text-white mb-2", children: "Stream Ended" }),
3607
+ /* @__PURE__ */ jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-2", children: error || "Connection closed unexpectedly" }),
3608
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-2", children: [
3574
3609
  "Total sent: ",
3575
3610
  (bytesSent / 1024 / 1024).toFixed(2),
3576
3611
  " MB"
3577
3612
  ] }),
3613
+ diagnostics && /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-400 dark:text-gray-500 mb-6 font-mono bg-gray-100 dark:bg-zinc-800 rounded p-2 text-left", children: [
3614
+ /* @__PURE__ */ jsxs("div", { children: [
3615
+ "Codec: ",
3616
+ diagnostics.mimeType || "unknown"
3617
+ ] }),
3618
+ /* @__PURE__ */ jsxs("div", { children: [
3619
+ "Chunks: ",
3620
+ diagnostics.chunksSent,
3621
+ " (",
3622
+ (diagnostics.bytesSent / 1024).toFixed(1),
3623
+ " KB)"
3624
+ ] }),
3625
+ /* @__PURE__ */ jsxs("div", { children: [
3626
+ "Duration: ",
3627
+ (diagnostics.elapsedMs / 1e3).toFixed(1),
3628
+ "s"
3629
+ ] }),
3630
+ /* @__PURE__ */ jsxs("div", { children: [
3631
+ "Close code: ",
3632
+ diagnostics.closeCode ?? "N/A",
3633
+ diagnostics.closeReason ? ` (${diagnostics.closeReason})` : ""
3634
+ ] })
3635
+ ] }),
3636
+ !diagnostics && /* @__PURE__ */ jsx("div", { className: "mb-6" }),
3578
3637
  /* @__PURE__ */ jsx(
3579
3638
  "button",
3580
3639
  {