@arcware-cloud/pixelstreaming-websdk 1.3.8 → 1.3.9

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/README.md CHANGED
@@ -80,6 +80,10 @@ For more detailed examples and advanced usage, please refer to our documentation
80
80
 
81
81
  # Changelog
82
82
 
83
+ ### 1.3.9
84
+
85
+ - added an event handler to check if video is streaming if cloud requests evidence
86
+
83
87
  ### 1.3.8
84
88
 
85
89
  - fixed error handling in SDK to back of reconnects if connection was intentionally terminated by cloud
package/index.cjs.js CHANGED
@@ -23420,7 +23420,7 @@ class ArcwareConfig extends lib_pixelstreamingfrontend_ue5_5_1.Config {
23420
23420
  if (!config.initialSettings.ss)
23421
23421
  config.initialSettings.ss = exports.DefaultUrl;
23422
23422
  super(config);
23423
- this.VERSION = "1.3.8";
23423
+ this.VERSION = "1.3.9";
23424
23424
  this.settings = settings;
23425
23425
  this.session = new Session_1.Session();
23426
23426
  this._initialSettings = config.initialSettings;
@@ -23725,6 +23725,7 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
23725
23725
  this.addMessageHandler("ping", shared_pixelstreaming_websdk_1.Messages.ZPing, this.onPing);
23726
23726
  this.addMessageHandler("queue", shared_pixelstreaming_websdk_1.Messages.ZQueue, this.onQueue);
23727
23727
  this.addMessageHandler("version", shared_pixelstreaming_websdk_1.Messages.ZVersion, this.onVersion);
23728
+ this.addMessageHandler("render", shared_pixelstreaming_websdk_1.Messages.ZRender, this.onRender);
23728
23729
  // Create a debounced version of the handleResolutionChange function
23729
23730
  const debouncedResolutionChange = (0, debounce_1.default)(() => {
23730
23731
  this.handleResolutionChange();
@@ -23791,6 +23792,64 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
23791
23792
  }
23792
23793
  });
23793
23794
  }
23795
+ isVideoRenderingNow(video) {
23796
+ if (!video)
23797
+ return false;
23798
+ const hasDims = video.videoWidth > 0 && video.videoHeight > 0;
23799
+ const hasData = video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA; // ≥2
23800
+ const playing = !video.paused && !video.ended;
23801
+ // Be conservative: require at least two signals to avoid metadata-only false positives
23802
+ return (hasDims && hasData) || (hasDims && playing) || (hasData && playing);
23803
+ }
23804
+ waitForFirstFrameWithTimeout(ms = 2000) {
23805
+ var _a, _b, _c;
23806
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
23807
+ const video = (_c = (_b = (_a = this.webRtcController) === null || _a === void 0 ? void 0 : _a.videoPlayer) === null || _b === void 0 ? void 0 : _b.getVideoElement) === null || _c === void 0 ? void 0 : _c.call(_b);
23808
+ if (this.isVideoRenderingNow(video))
23809
+ return true;
23810
+ let t;
23811
+ const ok = yield Promise.race([
23812
+ new Promise((resolve) => {
23813
+ var _a, _b;
23814
+ const done = () => {
23815
+ cleanup();
23816
+ resolve(true);
23817
+ };
23818
+ const cleanup = () => {
23819
+ var _a, _b;
23820
+ video.removeEventListener("playing", onPlaying);
23821
+ video.removeEventListener("resize", onResize);
23822
+ if ("cancelVideoFrameCallback" in HTMLVideoElement.prototype && rvfcId != null) {
23823
+ (_b = (_a = video).cancelVideoFrameCallback) === null || _b === void 0 ? void 0 : _b.call(_a, rvfcId);
23824
+ }
23825
+ };
23826
+ const onPlaying = () => this.isVideoRenderingNow(video) && done();
23827
+ const onResize = () => this.isVideoRenderingNow(video) && done();
23828
+ video.addEventListener("playing", onPlaying, { once: true });
23829
+ video.addEventListener("resize", onResize, { once: true });
23830
+ const rvfcId = "requestVideoFrameCallback" in HTMLVideoElement.prototype
23831
+ ? (_b = (_a = video).requestVideoFrameCallback) === null || _b === void 0 ? void 0 : _b.call(_a, () => done())
23832
+ : null;
23833
+ }),
23834
+ new Promise((resolve) => {
23835
+ t = window.setTimeout(() => resolve(false), ms);
23836
+ })
23837
+ ]);
23838
+ if (t)
23839
+ clearTimeout(t);
23840
+ return ok;
23841
+ });
23842
+ }
23843
+ onRender(_msg) {
23844
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
23845
+ const isRendering = yield this.waitForFirstFrameWithTimeout();
23846
+ const payload = {
23847
+ type: "render",
23848
+ isRendering: isRendering
23849
+ };
23850
+ this.send(payload); // uses buffered send
23851
+ });
23852
+ }
23794
23853
  /** On ping the session creation timestamp will be updated. */
23795
23854
  onPing(message) {
23796
23855
  var _a, _b;
@@ -26427,6 +26486,20 @@ exports.ZQueue = zod_1.z.object({
26427
26486
  });
26428
26487
 
26429
26488
 
26489
+ /***/ }),
26490
+
26491
+ /***/ 1919:
26492
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
26493
+
26494
+
26495
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
26496
+ exports.ZRender = void 0;
26497
+ const zod_1 = __webpack_require__(8754);
26498
+ exports.ZRender = zod_1.z.object({
26499
+ type: zod_1.z.literal("render")
26500
+ });
26501
+
26502
+
26430
26503
  /***/ }),
26431
26504
 
26432
26505
  /***/ 4201:
@@ -26784,9 +26857,10 @@ tslib_1.__exportStar(__webpack_require__(1224), exports);
26784
26857
  tslib_1.__exportStar(__webpack_require__(4882), exports);
26785
26858
  tslib_1.__exportStar(__webpack_require__(3751), exports);
26786
26859
  tslib_1.__exportStar(__webpack_require__(9864), exports);
26860
+ tslib_1.__exportStar(__webpack_require__(1919), exports);
26787
26861
  const Stats_1 = __webpack_require__(3403);
26788
26862
  exports.Send = {
26789
- stats: Stats_1.ZStats,
26863
+ stats: Stats_1.ZStats
26790
26864
  };
26791
26865
 
26792
26866
 
package/index.esm.js CHANGED
@@ -23428,7 +23428,7 @@ class ArcwareConfig extends _epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBP
23428
23428
  if (!config.initialSettings.ss)
23429
23429
  config.initialSettings.ss = DefaultUrl;
23430
23430
  super(config);
23431
- this.VERSION = "1.3.8";
23431
+ this.VERSION = "1.3.9";
23432
23432
  this.settings = settings;
23433
23433
  this.session = new _domain_Session__WEBPACK_IMPORTED_MODULE_0__.Session();
23434
23434
  this._initialSettings = config.initialSettings;
@@ -23750,6 +23750,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
23750
23750
  this.addMessageHandler("ping", _arcware_cloud_shared_pixelstreaming_websdk__WEBPACK_IMPORTED_MODULE_0__.Messages.ZPing, this.onPing);
23751
23751
  this.addMessageHandler("queue", _arcware_cloud_shared_pixelstreaming_websdk__WEBPACK_IMPORTED_MODULE_0__.Messages.ZQueue, this.onQueue);
23752
23752
  this.addMessageHandler("version", _arcware_cloud_shared_pixelstreaming_websdk__WEBPACK_IMPORTED_MODULE_0__.Messages.ZVersion, this.onVersion);
23753
+ this.addMessageHandler("render", _arcware_cloud_shared_pixelstreaming_websdk__WEBPACK_IMPORTED_MODULE_0__.Messages.ZRender, this.onRender);
23753
23754
  // Create a debounced version of the handleResolutionChange function
23754
23755
  const debouncedResolutionChange = (0,_domain_debounce__WEBPACK_IMPORTED_MODULE_8__["default"])(() => {
23755
23756
  this.handleResolutionChange();
@@ -23816,6 +23817,64 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
23816
23817
  }
23817
23818
  });
23818
23819
  }
23820
+ isVideoRenderingNow(video) {
23821
+ if (!video)
23822
+ return false;
23823
+ const hasDims = video.videoWidth > 0 && video.videoHeight > 0;
23824
+ const hasData = video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA; // ≥2
23825
+ const playing = !video.paused && !video.ended;
23826
+ // Be conservative: require at least two signals to avoid metadata-only false positives
23827
+ return (hasDims && hasData) || (hasDims && playing) || (hasData && playing);
23828
+ }
23829
+ waitForFirstFrameWithTimeout(ms = 2000) {
23830
+ var _a, _b, _c;
23831
+ return (0,tslib__WEBPACK_IMPORTED_MODULE_9__.__awaiter)(this, void 0, void 0, function* () {
23832
+ const video = (_c = (_b = (_a = this.webRtcController) === null || _a === void 0 ? void 0 : _a.videoPlayer) === null || _b === void 0 ? void 0 : _b.getVideoElement) === null || _c === void 0 ? void 0 : _c.call(_b);
23833
+ if (this.isVideoRenderingNow(video))
23834
+ return true;
23835
+ let t;
23836
+ const ok = yield Promise.race([
23837
+ new Promise((resolve) => {
23838
+ var _a, _b;
23839
+ const done = () => {
23840
+ cleanup();
23841
+ resolve(true);
23842
+ };
23843
+ const cleanup = () => {
23844
+ var _a, _b;
23845
+ video.removeEventListener("playing", onPlaying);
23846
+ video.removeEventListener("resize", onResize);
23847
+ if ("cancelVideoFrameCallback" in HTMLVideoElement.prototype && rvfcId != null) {
23848
+ (_b = (_a = video).cancelVideoFrameCallback) === null || _b === void 0 ? void 0 : _b.call(_a, rvfcId);
23849
+ }
23850
+ };
23851
+ const onPlaying = () => this.isVideoRenderingNow(video) && done();
23852
+ const onResize = () => this.isVideoRenderingNow(video) && done();
23853
+ video.addEventListener("playing", onPlaying, { once: true });
23854
+ video.addEventListener("resize", onResize, { once: true });
23855
+ const rvfcId = "requestVideoFrameCallback" in HTMLVideoElement.prototype
23856
+ ? (_b = (_a = video).requestVideoFrameCallback) === null || _b === void 0 ? void 0 : _b.call(_a, () => done())
23857
+ : null;
23858
+ }),
23859
+ new Promise((resolve) => {
23860
+ t = window.setTimeout(() => resolve(false), ms);
23861
+ })
23862
+ ]);
23863
+ if (t)
23864
+ clearTimeout(t);
23865
+ return ok;
23866
+ });
23867
+ }
23868
+ onRender(_msg) {
23869
+ return (0,tslib__WEBPACK_IMPORTED_MODULE_9__.__awaiter)(this, void 0, void 0, function* () {
23870
+ const isRendering = yield this.waitForFirstFrameWithTimeout();
23871
+ const payload = {
23872
+ type: "render",
23873
+ isRendering: isRendering
23874
+ };
23875
+ this.send(payload); // uses buffered send
23876
+ });
23877
+ }
23819
23878
  /** On ping the session creation timestamp will be updated. */
23820
23879
  onPing(message) {
23821
23880
  var _a, _b;
@@ -26492,6 +26551,22 @@ const ZQueue = zod__WEBPACK_IMPORTED_MODULE_0__.z.object({
26492
26551
  });
26493
26552
 
26494
26553
 
26554
+ /***/ }),
26555
+
26556
+ /***/ 1919:
26557
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
26558
+
26559
+ __webpack_require__.r(__webpack_exports__);
26560
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
26561
+ /* harmony export */ "ZRender": () => (/* binding */ ZRender)
26562
+ /* harmony export */ });
26563
+ /* harmony import */ var zod__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1604);
26564
+
26565
+ const ZRender = zod__WEBPACK_IMPORTED_MODULE_0__.z.object({
26566
+ type: zod__WEBPACK_IMPORTED_MODULE_0__.z.literal("render")
26567
+ });
26568
+
26569
+
26495
26570
  /***/ }),
26496
26571
 
26497
26572
  /***/ 4201:
@@ -26829,6 +26904,7 @@ __webpack_require__.r(__webpack_exports__);
26829
26904
  /* harmony export */ "ZLoveLetter": () => (/* reexport safe */ _LoveLetter__WEBPACK_IMPORTED_MODULE_1__.ZLoveLetter),
26830
26905
  /* harmony export */ "ZPing": () => (/* reexport safe */ _Ping__WEBPACK_IMPORTED_MODULE_5__.ZPing),
26831
26906
  /* harmony export */ "ZQueue": () => (/* reexport safe */ _Queue__WEBPACK_IMPORTED_MODULE_6__.ZQueue),
26907
+ /* harmony export */ "ZRender": () => (/* reexport safe */ _Render__WEBPACK_IMPORTED_MODULE_9__.ZRender),
26832
26908
  /* harmony export */ "ZSessionId": () => (/* reexport safe */ _SessionId__WEBPACK_IMPORTED_MODULE_2__.ZSessionId),
26833
26909
  /* harmony export */ "ZStats": () => (/* reexport safe */ _Stats__WEBPACK_IMPORTED_MODULE_4__.ZStats),
26834
26910
  /* harmony export */ "ZStreamInfo": () => (/* reexport safe */ _StreamInfo__WEBPACK_IMPORTED_MODULE_3__.ZStreamInfo),
@@ -26843,6 +26919,8 @@ __webpack_require__.r(__webpack_exports__);
26843
26919
  /* harmony import */ var _Queue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4882);
26844
26920
  /* harmony import */ var _Version__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3751);
26845
26921
  /* harmony import */ var _WebSdkSettings__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(9864);
26922
+ /* harmony import */ var _Render__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(1919);
26923
+
26846
26924
 
26847
26925
 
26848
26926
 
@@ -26854,7 +26932,7 @@ __webpack_require__.r(__webpack_exports__);
26854
26932
 
26855
26933
 
26856
26934
  const Send = {
26857
- stats: _Stats__WEBPACK_IMPORTED_MODULE_4__.ZStats,
26935
+ stats: _Stats__WEBPACK_IMPORTED_MODULE_4__.ZStats
26858
26936
  };
26859
26937
 
26860
26938
 
package/index.umd.js CHANGED
@@ -23430,7 +23430,7 @@ class ArcwareConfig extends lib_pixelstreamingfrontend_ue5_5_1.Config {
23430
23430
  if (!config.initialSettings.ss)
23431
23431
  config.initialSettings.ss = exports.DefaultUrl;
23432
23432
  super(config);
23433
- this.VERSION = "1.3.8";
23433
+ this.VERSION = "1.3.9";
23434
23434
  this.settings = settings;
23435
23435
  this.session = new Session_1.Session();
23436
23436
  this._initialSettings = config.initialSettings;
@@ -23735,6 +23735,7 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
23735
23735
  this.addMessageHandler("ping", shared_pixelstreaming_websdk_1.Messages.ZPing, this.onPing);
23736
23736
  this.addMessageHandler("queue", shared_pixelstreaming_websdk_1.Messages.ZQueue, this.onQueue);
23737
23737
  this.addMessageHandler("version", shared_pixelstreaming_websdk_1.Messages.ZVersion, this.onVersion);
23738
+ this.addMessageHandler("render", shared_pixelstreaming_websdk_1.Messages.ZRender, this.onRender);
23738
23739
  // Create a debounced version of the handleResolutionChange function
23739
23740
  const debouncedResolutionChange = (0, debounce_1.default)(() => {
23740
23741
  this.handleResolutionChange();
@@ -23801,6 +23802,64 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
23801
23802
  }
23802
23803
  });
23803
23804
  }
23805
+ isVideoRenderingNow(video) {
23806
+ if (!video)
23807
+ return false;
23808
+ const hasDims = video.videoWidth > 0 && video.videoHeight > 0;
23809
+ const hasData = video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA; // ≥2
23810
+ const playing = !video.paused && !video.ended;
23811
+ // Be conservative: require at least two signals to avoid metadata-only false positives
23812
+ return (hasDims && hasData) || (hasDims && playing) || (hasData && playing);
23813
+ }
23814
+ waitForFirstFrameWithTimeout(ms = 2000) {
23815
+ var _a, _b, _c;
23816
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
23817
+ const video = (_c = (_b = (_a = this.webRtcController) === null || _a === void 0 ? void 0 : _a.videoPlayer) === null || _b === void 0 ? void 0 : _b.getVideoElement) === null || _c === void 0 ? void 0 : _c.call(_b);
23818
+ if (this.isVideoRenderingNow(video))
23819
+ return true;
23820
+ let t;
23821
+ const ok = yield Promise.race([
23822
+ new Promise((resolve) => {
23823
+ var _a, _b;
23824
+ const done = () => {
23825
+ cleanup();
23826
+ resolve(true);
23827
+ };
23828
+ const cleanup = () => {
23829
+ var _a, _b;
23830
+ video.removeEventListener("playing", onPlaying);
23831
+ video.removeEventListener("resize", onResize);
23832
+ if ("cancelVideoFrameCallback" in HTMLVideoElement.prototype && rvfcId != null) {
23833
+ (_b = (_a = video).cancelVideoFrameCallback) === null || _b === void 0 ? void 0 : _b.call(_a, rvfcId);
23834
+ }
23835
+ };
23836
+ const onPlaying = () => this.isVideoRenderingNow(video) && done();
23837
+ const onResize = () => this.isVideoRenderingNow(video) && done();
23838
+ video.addEventListener("playing", onPlaying, { once: true });
23839
+ video.addEventListener("resize", onResize, { once: true });
23840
+ const rvfcId = "requestVideoFrameCallback" in HTMLVideoElement.prototype
23841
+ ? (_b = (_a = video).requestVideoFrameCallback) === null || _b === void 0 ? void 0 : _b.call(_a, () => done())
23842
+ : null;
23843
+ }),
23844
+ new Promise((resolve) => {
23845
+ t = window.setTimeout(() => resolve(false), ms);
23846
+ })
23847
+ ]);
23848
+ if (t)
23849
+ clearTimeout(t);
23850
+ return ok;
23851
+ });
23852
+ }
23853
+ onRender(_msg) {
23854
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
23855
+ const isRendering = yield this.waitForFirstFrameWithTimeout();
23856
+ const payload = {
23857
+ type: "render",
23858
+ isRendering: isRendering
23859
+ };
23860
+ this.send(payload); // uses buffered send
23861
+ });
23862
+ }
23804
23863
  /** On ping the session creation timestamp will be updated. */
23805
23864
  onPing(message) {
23806
23865
  var _a, _b;
@@ -26437,6 +26496,20 @@ exports.ZQueue = zod_1.z.object({
26437
26496
  });
26438
26497
 
26439
26498
 
26499
+ /***/ }),
26500
+
26501
+ /***/ 1919:
26502
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
26503
+
26504
+
26505
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
26506
+ exports.ZRender = void 0;
26507
+ const zod_1 = __webpack_require__(8754);
26508
+ exports.ZRender = zod_1.z.object({
26509
+ type: zod_1.z.literal("render")
26510
+ });
26511
+
26512
+
26440
26513
  /***/ }),
26441
26514
 
26442
26515
  /***/ 4201:
@@ -26794,9 +26867,10 @@ tslib_1.__exportStar(__webpack_require__(1224), exports);
26794
26867
  tslib_1.__exportStar(__webpack_require__(4882), exports);
26795
26868
  tslib_1.__exportStar(__webpack_require__(3751), exports);
26796
26869
  tslib_1.__exportStar(__webpack_require__(9864), exports);
26870
+ tslib_1.__exportStar(__webpack_require__(1919), exports);
26797
26871
  const Stats_1 = __webpack_require__(3403);
26798
26872
  exports.Send = {
26799
- stats: Stats_1.ZStats,
26873
+ stats: Stats_1.ZStats
26800
26874
  };
26801
26875
 
26802
26876
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arcware-cloud/pixelstreaming-websdk",
3
3
  "description": "WebSDK for easy implementation of pixel streaming with Arcware Cloud Services. Heavily based on the '@epicgames-ps' library.",
4
- "version": "1.3.8",
4
+ "version": "1.3.9",
5
5
  "type": "commonjs",
6
6
  "main": "./index.umd.js",
7
7
  "module": "./index.umd.js",
@@ -26,7 +26,7 @@ export declare class ArcwareConfig extends Config {
26
26
  readonly session: Session;
27
27
  readonly settings: Settings;
28
28
  private _initialSettings;
29
- readonly VERSION = "1.3.8";
29
+ readonly VERSION = "1.3.9";
30
30
  constructor(config: ArcwareConfigParams);
31
31
  /** Setup connection string. */
32
32
  get urlFlags(): string;
@@ -50,6 +50,9 @@ export declare class ArcwarePixelStreaming extends PixelStreaming {
50
50
  */
51
51
  /** On version requested, the version of the WebSDK would be returned. */
52
52
  private onVersion;
53
+ private isVideoRenderingNow;
54
+ private waitForFirstFrameWithTimeout;
55
+ private onRender;
53
56
  /** On ping the session creation timestamp will be updated. */
54
57
  private onPing;
55
58
  /** Handle incoming configurations. */
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ export declare const ZRender: z.ZodObject<{
3
+ type: z.ZodLiteral<"render">;
4
+ }, "strip", z.ZodTypeAny, {
5
+ type?: "render";
6
+ }, {
7
+ type?: "render";
8
+ }>;
9
+ export type Render = z.infer<typeof ZRender>;
@@ -7,6 +7,7 @@ export * from "./Ping";
7
7
  export * from "./Queue";
8
8
  export * from "./Version";
9
9
  export * from "./WebSdkSettings";
10
+ export * from "./Render";
10
11
  export declare const Send: {
11
12
  stats: import("zod").ZodObject<{
12
13
  type: import("zod").ZodLiteral<"stats">;