@applicaster/zapp-react-native-utils 12.0.0-rc.77 → 12.0.0-rc.78
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/appUtils/platform/const.ts +7 -0
- package/appUtils/platform/index.ts +2 -0
- package/appUtils/platform/platformUtils.ts +223 -1
- package/appUtils/playerManager/index.ts +5 -5
- package/appUtils/playerManager/player.ts +0 -3
- package/appUtils/playerManager/playerNative.ts +2 -2
- package/package.json +2 -2
- package/appUtils/platform/platformUtils.web.ts +0 -49
|
@@ -16,3 +16,10 @@ export const PLATFORMS = {
|
|
|
16
16
|
smartcast: "SmartCast",
|
|
17
17
|
conjure: "Conjure",
|
|
18
18
|
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Keys used to store the platform / device state in the session storage
|
|
22
|
+
*/
|
|
23
|
+
export const PLATFORM_KEYS = {
|
|
24
|
+
deviceClosedCaptioningEnabled: "device_closed_captioning_enabled",
|
|
25
|
+
};
|
|
@@ -1 +1,223 @@
|
|
|
1
|
-
|
|
1
|
+
import { BehaviorSubject } from "rxjs";
|
|
2
|
+
|
|
3
|
+
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
4
|
+
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
|
|
5
|
+
import { PlayerWebController } from "@applicaster/zapp-react-native-default-player/src/playerFactory/players/playerWebController";
|
|
6
|
+
|
|
7
|
+
import { PLATFORM_KEYS, PLATFORMS } from "./const";
|
|
8
|
+
import { createLogger, utilsLogger } from "../../logger";
|
|
9
|
+
|
|
10
|
+
declare global {
|
|
11
|
+
interface Window {
|
|
12
|
+
VIZIO?: {
|
|
13
|
+
exitApplication: () => void;
|
|
14
|
+
setClosedCaptionHandler: (
|
|
15
|
+
callback: (isCCEnabled: boolean) => void
|
|
16
|
+
) => void;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { log_debug, log_error } = createLogger({
|
|
22
|
+
category: "General",
|
|
23
|
+
subsystem: "PlatformUtils",
|
|
24
|
+
parent: utilsLogger,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export const getUserAgent = () =>
|
|
28
|
+
window?.navigator?.userAgent || global?.navigator?.userAgent;
|
|
29
|
+
|
|
30
|
+
/** VIZIO UTILS */
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Checks if we are on the Vizio platform by using the userAgent string
|
|
34
|
+
*
|
|
35
|
+
* Use this method when you need to identify the platform on runtime
|
|
36
|
+
* before the VIZIO Companion Library has loaded
|
|
37
|
+
*/
|
|
38
|
+
export const isVizioPlatform = () => {
|
|
39
|
+
const userAgent = getUserAgent();
|
|
40
|
+
|
|
41
|
+
const isVizioAgent =
|
|
42
|
+
userAgent.includes(PLATFORMS.vizio) ||
|
|
43
|
+
userAgent.includes(PLATFORMS.smartcast) ||
|
|
44
|
+
userAgent.includes(PLATFORMS.conjure);
|
|
45
|
+
|
|
46
|
+
return isVizioAgent;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Checks if we are on the Vizio platform by checking for the global VIZIO object
|
|
51
|
+
* and the VIZIO Companion Library. This method does not use the userAgent string,
|
|
52
|
+
* because it mainly checks whether we have access to apis, which may not be available yet
|
|
53
|
+
*/
|
|
54
|
+
export const hasVizioAPIs = () => {
|
|
55
|
+
const hasAPIs =
|
|
56
|
+
typeof window.VIZIO !== "undefined" &&
|
|
57
|
+
window?.applicaster?.vizioLibraryDidLoad;
|
|
58
|
+
|
|
59
|
+
return hasAPIs;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Manages device based closed captioning state
|
|
64
|
+
* Returns an observable that emits the current state and updates whenever it changes
|
|
65
|
+
*/
|
|
66
|
+
class ClosedCaptioningManager {
|
|
67
|
+
private ccState$ = new BehaviorSubject<boolean>(false);
|
|
68
|
+
private static ccManagerInstance: ClosedCaptioningManager;
|
|
69
|
+
|
|
70
|
+
private constructor() {
|
|
71
|
+
this.initialize();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static getInstance(): ClosedCaptioningManager {
|
|
75
|
+
if (!ClosedCaptioningManager.ccManagerInstance) {
|
|
76
|
+
ClosedCaptioningManager.ccManagerInstance = new ClosedCaptioningManager();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return ClosedCaptioningManager.ccManagerInstance;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async initialize() {
|
|
83
|
+
const existingState = await sessionStorage.getItem(
|
|
84
|
+
PLATFORM_KEYS.deviceClosedCaptioningEnabled
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
log_debug("Initializing closed captioning manager", { existingState });
|
|
88
|
+
|
|
89
|
+
if (existingState !== null) {
|
|
90
|
+
this.ccState$.next(existingState === "true" || existingState === true);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (hasVizioAPIs()) {
|
|
94
|
+
window.VIZIO!.setClosedCaptionHandler((isCCEnabled) => {
|
|
95
|
+
log_debug("CC state changed", { isCCEnabled });
|
|
96
|
+
|
|
97
|
+
sessionStorage.setItem(
|
|
98
|
+
PLATFORM_KEYS.deviceClosedCaptioningEnabled,
|
|
99
|
+
isCCEnabled
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
this.ccState$.next(isCCEnabled);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
getCurrentState(): boolean {
|
|
108
|
+
return this.ccState$.getValue();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getStateAsObservable() {
|
|
112
|
+
return this.ccState$.asObservable();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Subscribe to closed captioning state changes
|
|
118
|
+
* @returns Observable<boolean>
|
|
119
|
+
* @example
|
|
120
|
+
* const subscription = getClosedCaptionState().subscribe(
|
|
121
|
+
* isEnabled => setClosedCaptionState(isEnabled)
|
|
122
|
+
* );
|
|
123
|
+
* subscription.unsubscribe(), []);
|
|
124
|
+
*/
|
|
125
|
+
export const getClosedCaptionState = () => {
|
|
126
|
+
const ccManager = ClosedCaptioningManager.getInstance();
|
|
127
|
+
|
|
128
|
+
return ccManager.getStateAsObservable();
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export class TextTrackManager {
|
|
132
|
+
private controller?: PlayerWebController;
|
|
133
|
+
private static instance: TextTrackManager;
|
|
134
|
+
|
|
135
|
+
private constructor() {}
|
|
136
|
+
|
|
137
|
+
static getInstance(): TextTrackManager {
|
|
138
|
+
if (!TextTrackManager.instance) {
|
|
139
|
+
TextTrackManager.instance = new TextTrackManager();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return TextTrackManager.instance;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
initialize(controller: PlayerWebController) {
|
|
146
|
+
if (!controller) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
"Controller is required for TextTrackManager initialization"
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.controller = controller;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async setTextTrackBasedOnCaptions(closedCaptionsState: boolean) {
|
|
156
|
+
if (!this.controller) {
|
|
157
|
+
log_error("Controller is not initialized");
|
|
158
|
+
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (closedCaptionsState) {
|
|
163
|
+
const textTracks = this.controller.getTracksState().textTracks;
|
|
164
|
+
const preferredTextTrack = await this.getPreferredTextTrack(textTracks);
|
|
165
|
+
|
|
166
|
+
if (preferredTextTrack) {
|
|
167
|
+
this.controller.selectTrack(preferredTextTrack);
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
this.controller.selectTrack(null);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async getPreferredTextTrack(
|
|
175
|
+
textTracks: QuickBrickPlayer.TextTrack[]
|
|
176
|
+
): Promise<QuickBrickPlayer.TextTrack | undefined> {
|
|
177
|
+
if (!this.controller) return;
|
|
178
|
+
|
|
179
|
+
const userPreferredTextLanguageLocalStorage = await localStorage.getItem(
|
|
180
|
+
"preferred_text_language",
|
|
181
|
+
"user_preferences"
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
let userPreferredTextLanguage;
|
|
185
|
+
|
|
186
|
+
if (userPreferredTextLanguageLocalStorage) {
|
|
187
|
+
userPreferredTextLanguage = textTracks.find(
|
|
188
|
+
(track) => track.language === userPreferredTextLanguageLocalStorage
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (userPreferredTextLanguage?.id) {
|
|
193
|
+
return userPreferredTextLanguage;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const enableAutoTextTrackSelection =
|
|
197
|
+
this.controller.getPluginConfiguration()
|
|
198
|
+
?.enable_auto_text_track_selection ||
|
|
199
|
+
this.controller.getTracksState().textTracks.length > 0;
|
|
200
|
+
|
|
201
|
+
if (enableAutoTextTrackSelection) {
|
|
202
|
+
const languageCode = await sessionStorage.getItem("languageCode");
|
|
203
|
+
|
|
204
|
+
if (languageCode) {
|
|
205
|
+
const chosenTextTrackBySystemLanguage = textTracks.find(
|
|
206
|
+
(track) => track.language === languageCode
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
if (chosenTextTrackBySystemLanguage?.id) {
|
|
210
|
+
return chosenTextTrackBySystemLanguage;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return textTracks?.[0];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
isTextTrackEnabled(): boolean {
|
|
219
|
+
if (!this.controller) return false;
|
|
220
|
+
|
|
221
|
+
return this.controller.getTracksState().textTrackId !== null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -366,9 +366,9 @@ export class PlayerManager {
|
|
|
366
366
|
// TODO: Remove
|
|
367
367
|
if (this.castingReceiver) {
|
|
368
368
|
this.castingReceiver.rewind(deltaTime);
|
|
369
|
+
} else {
|
|
370
|
+
this.getActivePlayer()?.rewind(deltaTime);
|
|
369
371
|
}
|
|
370
|
-
|
|
371
|
-
this.getActivePlayer()?.rewind(deltaTime);
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
public forward(deltaTime = null) {
|
|
@@ -376,9 +376,9 @@ export class PlayerManager {
|
|
|
376
376
|
|
|
377
377
|
if (this.castingReceiver) {
|
|
378
378
|
this.castingReceiver.forward(deltaTime);
|
|
379
|
+
} else {
|
|
380
|
+
this.getActivePlayer()?.forward(deltaTime);
|
|
379
381
|
}
|
|
380
|
-
|
|
381
|
-
this.getActivePlayer()?.forward(deltaTime);
|
|
382
382
|
}
|
|
383
383
|
|
|
384
384
|
public seeking(time) {
|
|
@@ -441,7 +441,7 @@ export class PlayerManager {
|
|
|
441
441
|
}
|
|
442
442
|
|
|
443
443
|
// Call method on player just in case
|
|
444
|
-
return this.getActivePlayer()?.
|
|
444
|
+
return this.getActivePlayer()?.selectTrack(track);
|
|
445
445
|
}
|
|
446
446
|
|
|
447
447
|
public isRegistered() {
|
|
@@ -684,9 +684,6 @@ export class Player {
|
|
|
684
684
|
play = () => {};
|
|
685
685
|
pause = () => {};
|
|
686
686
|
disableBufferAnimation = (): boolean => true;
|
|
687
|
-
setLanguage = (
|
|
688
|
-
_selected?: QuickBrickPlayer.TextTrack | QuickBrickPlayer.AudioTrack
|
|
689
|
-
) => {};
|
|
690
687
|
|
|
691
688
|
setPlaybackRate = (_rate) => {};
|
|
692
689
|
startSleepTimer = (_timestamp) => {};
|
|
@@ -188,10 +188,10 @@ export class PlayerNative extends Player {
|
|
|
188
188
|
|
|
189
189
|
disableBufferAnimation = (): boolean => false;
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
selectTrack = (
|
|
192
192
|
selected: QuickBrickPlayer.TextTrack | QuickBrickPlayer.AudioTrack
|
|
193
193
|
) => {
|
|
194
|
-
this.currentPlayerComponent()?.["
|
|
194
|
+
this.currentPlayerComponent()?.["selectTrack"]?.(selected);
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
setPlaybackRate = (rate: number) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "12.0.0-rc.
|
|
3
|
+
"version": "12.0.0-rc.78",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "12.0.0-rc.
|
|
31
|
+
"@applicaster/applicaster-types": "12.0.0-rc.78",
|
|
32
32
|
"buffer": "^5.2.1",
|
|
33
33
|
"camelize": "^1.0.0",
|
|
34
34
|
"create-react-context": "^0.2.3",
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { PLATFORMS } from "./const";
|
|
2
|
-
|
|
3
|
-
declare global {
|
|
4
|
-
interface Window {
|
|
5
|
-
applicaster: {
|
|
6
|
-
vizioLibraryDidLoad: boolean;
|
|
7
|
-
useOnScreenKeyboard: boolean;
|
|
8
|
-
};
|
|
9
|
-
VIZIO?: {
|
|
10
|
-
exitApplication: () => void;
|
|
11
|
-
setClosedCaptionHandler: (
|
|
12
|
-
callback: (isCCEnabled: boolean) => void
|
|
13
|
-
) => void;
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const getUserAgent = () =>
|
|
19
|
-
window?.navigator?.userAgent || global?.navigator?.userAgent;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Checks if we are on the Vizio platform by using the userAgent string
|
|
23
|
-
*
|
|
24
|
-
* Use this method when you need to identify the platform on runtime
|
|
25
|
-
* before the VIZIO Companion Library has loaded
|
|
26
|
-
*/
|
|
27
|
-
export const isVizioPlatform = () => {
|
|
28
|
-
const userAgent = getUserAgent();
|
|
29
|
-
|
|
30
|
-
const isVizioAgent =
|
|
31
|
-
userAgent.includes(PLATFORMS.vizio) ||
|
|
32
|
-
userAgent.includes(PLATFORMS.smartcast) ||
|
|
33
|
-
userAgent.includes(PLATFORMS.conjure);
|
|
34
|
-
|
|
35
|
-
return isVizioAgent;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Checks if we are on the Vizio platform by checking for the global VIZIO object
|
|
40
|
-
* and the VIZIO Companion Library. This method does not use the userAgent string,
|
|
41
|
-
* because it mainly checks whether we have access to apis, which may not be available yet
|
|
42
|
-
*/
|
|
43
|
-
export const hasVizioAPIs = () => {
|
|
44
|
-
const hasAPIs =
|
|
45
|
-
typeof window.VIZIO !== "undefined" &&
|
|
46
|
-
window?.applicaster?.vizioLibraryDidLoad;
|
|
47
|
-
|
|
48
|
-
return hasAPIs;
|
|
49
|
-
};
|