senza-sdk 4.2.7 → 4.2.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "senza-sdk",
3
- "version": "4.2.7",
3
+ "version": "4.2.8",
4
4
  "main": "./src/api.js",
5
5
  "description": "API for Senza application",
6
6
  "license": "MIT",
package/src/lifecycle.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { getPlatformInfo } from "./api";
2
- import { getFCID, isAudioSyncEnabled, sdkLogger } from "./utils";
2
+ import { getFCID, isAudioSyncEnabled, sdkLogger, StreamType, SwitchMode } from "./utils";
3
3
  import { sessionInfo } from "./SessionInfo";
4
4
  import { remotePlayer } from "./remotePlayer";
5
5
 
@@ -152,6 +152,35 @@ class Lifecycle extends EventTarget {
152
152
  return Promise.resolve(false);
153
153
  }
154
154
  this._inTransition = true;
155
+
156
+ if (sessionInfo.sessionInfoObj?.settings?.["ui-streamer"]?.remotePlayerApiVersion >= 2) {
157
+ return new Promise((resolve, reject) => {
158
+ const FCID = getFCID();
159
+ const logger = sdkLogger.withFields({ FCID });
160
+ logger.log("lifecycle moveToForeground: sending stop action");
161
+ const message = {
162
+ type: "remotePlayer.stop",
163
+ class: "remotePlayer",
164
+ action: "stop",
165
+ streamType: isAudioSyncEnabled() ? StreamType.VIDEO | StreamType.SUBTITLE : StreamType.AUDIO | StreamType.VIDEO | StreamType.SUBTITLE
166
+ };
167
+ window.cefQuery({
168
+ request: JSON.stringify({ target: "TC", waitForResponse: false, internalAction: "uiActive", message: JSON.stringify(message) }),
169
+ persistent: false,
170
+ onSuccess: () => {
171
+ logger.log("stop successfully sent");
172
+ this._inTransition = false;
173
+ resolve(true);
174
+ },
175
+ onFailure: (code, msg) => {
176
+ logger.error(`stop failed: ${code} ${msg}`);
177
+ this._inTransition = false;
178
+ reject(`stop failed: ${code} ${msg}`);
179
+ }
180
+ });
181
+ });
182
+ }
183
+
155
184
  return new Promise((resolve, reject) => {
156
185
  const FCID = getFCID();
157
186
  const logger = sdkLogger.withFields({ FCID });
@@ -205,8 +234,24 @@ class Lifecycle extends EventTarget {
205
234
  const configuration = remotePlayer.getConfiguration();
206
235
  const audioLanguage = remotePlayer._selectedAudioTrack || configuration.preferredAudioLanguage || "";
207
236
  const subtitlesLanguage = remotePlayer._selectedSubtitlesTrack || configuration.preferredSubtitlesLanguage || "";
237
+ let request;
238
+ const message = {
239
+ action: "play",
240
+ fcid: FCID,
241
+ audioLanguage,
242
+ subtitlesLanguage
243
+ };
244
+ if (sessionInfo.sessionInfoObj?.settings?.["ui-streamer"]?.remotePlayerApiVersion >= 2) {
245
+ message.type = "remotePlayer.play";
246
+ message.class = "remotePlayer";
247
+ message.switchMode = isAudioSyncEnabled() ? SwitchMode.SEAMLESS : SwitchMode.NON_SEAMLESS;
248
+ message.streamType = StreamType.AUDIO | StreamType.VIDEO | StreamType.SUBTITLE;
249
+ request = { target: "TC", waitForResponse: false, internalAction: "uiExit", message: JSON.stringify(message) };
250
+ } else {
251
+ request = message;
252
+ }
208
253
  window.cefQuery({
209
- request: JSON.stringify({ action: "play", fcid: FCID, audioLanguage, subtitlesLanguage }),
254
+ request: JSON.stringify(request),
210
255
  persistent: false,
211
256
  onSuccess: () => {
212
257
  logger.log("[ moveToBackground ] play successfully sent");
@@ -239,7 +284,7 @@ class Lifecycle extends EventTarget {
239
284
  if (window.cefQuery) {
240
285
  return new Promise((resolve, reject) => {
241
286
  const FCID = getFCID();
242
- const request = { target: "TC", waitForResponse: false, message: JSON.stringify({ type: "uiStandbyRequest", fcid: FCID }) };
287
+ const request = { target: "TC", waitForResponse: false, internalAction: "uiExit", message: JSON.stringify({ type: "uiStandbyRequest", fcid: FCID }) };
243
288
  const logger = sdkLogger.withFields({ FCID });
244
289
  logger.log("lifecycle moveToUiStandby: sending uiStandbyRequest");
245
290
  window.cefQuery({
@@ -1,8 +1,9 @@
1
1
 
2
- import { getFCID, isAudioSyncEnabled, sdkLogger } from "./utils";
2
+ import { getFCID, isAudioSyncEnabled, sdkLogger, StreamType, SwitchMode } from "./utils";
3
3
  import { lifecycle } from "./lifecycle";
4
4
  import { writeLicenseResponse } from "./api";
5
5
  import { mergeAutoTranslationLanguages } from "./subtitlesUtils";
6
+ import { sessionInfo } from "./SessionInfo";
6
7
 
7
8
  const INVALID_SET_PLAYABLE_URI_CODE = 99;
8
9
  const DEFAULT_SET_PLAYABLE_URI_TIMEOUT = 5000;
@@ -128,6 +129,20 @@ class RemotePlayer extends EventTarget {
128
129
  * });
129
130
  * */
130
131
 
132
+ /**
133
+ * @event RemotePlayer#loadedmetadata
134
+ * @description loadedmetadata event will be dispatched when the remote player metadata is loaded
135
+ * and the audio/video tracks are available
136
+ * @example
137
+ * remotePlayer.addEventListener("loadedmetadata", () => {
138
+ * console.info("remotePlayer loadedmetadata", remotePlayer.getAudioTracks(), remotePlayer.getTextTracks());
139
+ * });
140
+ * */
141
+ typeof document !== "undefined" && document.addEventListener("hs/remotePlayerEvent", (e) => {
142
+ sdkLogger.info("Got hs/remotePlayerEvent event with detail", JSON.stringify(e?.detail));
143
+ this.dispatchEvent(new Event(e?.detail?.eventName));
144
+ });
145
+
131
146
  /**
132
147
  *
133
148
  * @event RemotePlayer#timeupdate
@@ -578,13 +593,19 @@ class RemotePlayer extends EventTarget {
578
593
  const logger = sdkLogger.withFields({ FCID, loadUrl: url, playbackPosition });
579
594
  logger.log("remotePlayer load: sending setPlayableUri request");
580
595
  const message = {
581
- type: "setPlayableUri",
582
596
  url,
583
597
  timeout: this._setPlayableUriTimeout,
584
598
  autoPlay: false,
585
599
  playbackPosition,
586
600
  fcid: FCID
587
601
  };
602
+ if (sessionInfo.sessionInfoObj?.settings?.["ui-streamer"]?.remotePlayerApiVersion >= 2) {
603
+ message.type = "remotePlayer.load";
604
+ message.class = "remotePlayer";
605
+ message.action = "load";
606
+ } else {
607
+ message.type = "setPlayableUri";
608
+ }
588
609
  const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
589
610
  let timerId = 0;
590
611
  const timeBeforeSendingRequest = Date.now();
@@ -745,6 +766,15 @@ class RemotePlayer extends EventTarget {
745
766
  subtitlesLanguage,
746
767
  playbackPosition: this.currentTime
747
768
  };
769
+ if (sessionInfo.sessionInfoObj?.settings?.["ui-streamer"]?.remotePlayerApiVersion >= 2) {
770
+ if (isAudioSyncEnabled()) {
771
+ message.switchMode = SwitchMode.SEAMLESS;
772
+ message.streamType = StreamType.AUDIO;
773
+ } else {
774
+ logger.log("remotePlayer play request ignored and will be sent with the lifecycle.moveToBackground()");
775
+ return Promise.resolve();
776
+ }
777
+ }
748
778
  const request = { target: "TC", waitForResponse: false, message: JSON.stringify(message) };
749
779
  return new Promise((resolve, reject) => {
750
780
  window.cefQuery({
package/src/utils.js CHANGED
@@ -94,3 +94,16 @@ export function isAudioSyncEnabled() {
94
94
  const clientUiAudioSettings = sessionInfo.sessionInfoObj?.settings?.client?.["ui_audio"];
95
95
  return clientUiAudioSettings?.enabled && clientUiAudioSettings?.from_cdn && clientUiAudioSettings?.ui_sync_enabled;
96
96
  }
97
+
98
+ // These StreamType constants are used as a mask for the client to play/stop the specific types
99
+ export const StreamType = Object.freeze({
100
+ NONE: 0,
101
+ AUDIO: 1,
102
+ VIDEO: 2,
103
+ SUBTITLE: 4
104
+ });
105
+
106
+ export const SwitchMode = Object.freeze({
107
+ NON_SEAMLESS: 0,
108
+ SEAMLESS: 1
109
+ });