@playkit-js/rapt 0.4.10-canary.0-878cdb7

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.
@@ -0,0 +1,236 @@
1
+ import { RaptConfig } from "./Kip";
2
+ import { PlaybackPreset } from "./ui/PlaybackPreset";
3
+ import { Dispatcher } from "./helpers/Dispatcher";
4
+ import { KipFullscreen } from "./PlayersManager";
5
+ import { PlayersDomManager } from "./PlayersDomManager";
6
+ import { log } from "./helpers/logger";
7
+
8
+ export class KalturaPlayer {
9
+ private static instanceCounter = 1;
10
+ public id;
11
+ private isDestroyed = false;
12
+
13
+ constructor(public player: any, public container: HTMLElement) {
14
+ this.id = `kaltura-player__${KalturaPlayer.instanceCounter}`;
15
+ KalturaPlayer.instanceCounter++;
16
+ }
17
+
18
+ destroy() {
19
+ if (this.isDestroyed) {
20
+ return;
21
+ }
22
+
23
+ this.isDestroyed = true;
24
+ try {
25
+ this.player.destroy();
26
+ }catch(e){
27
+ log("log", "pf_destroy", "could not destroy ",this.player);
28
+ }
29
+
30
+ const parentElement = this.container.parentElement;
31
+ if (parentElement) {
32
+ parentElement.removeChild(this.container);
33
+ }
34
+ }
35
+ }
36
+
37
+ export class PlayersFactory extends Dispatcher {
38
+ readonly secondsToBuffer: number = 6;
39
+ readonly playbackPreset: any;
40
+ readonly playbackPresetWithPlayButton: any;
41
+
42
+ constructor(
43
+ readonly domManager: PlayersDomManager,
44
+ readonly raptProjectId: string,
45
+ readonly playerLibrary: any,
46
+ private analyticsInterruptFunc: any,
47
+ private config: any
48
+ ) {
49
+ super();
50
+ if (config.rapt && config.rapt.bufferTime) {
51
+ this.secondsToBuffer = parseInt(config.rapt.bufferTime);
52
+ }
53
+ let deviceModel = undefined;
54
+ try {
55
+ deviceModel =
56
+ playerLibrary.core.Env.device && playerLibrary.core.Env.device.model; // desktops will be undefined
57
+ } catch (error) {
58
+ log("log", "pf_constructor", "could not get device model");
59
+ }
60
+
61
+ this.playbackPreset = new PlaybackPreset(
62
+ this.playerLibrary.ui.h,
63
+ this.playerLibrary.ui.Components,
64
+ () => this.toggleFullscreen(),
65
+ config.rapt,
66
+ deviceModel
67
+ ).preset;
68
+ // this is for autoplay=false. We want to show the large play button
69
+ this.playbackPresetWithPlayButton = new PlaybackPreset(
70
+ this.playerLibrary.ui.h,
71
+ this.playerLibrary.ui.Components,
72
+ () => this.toggleFullscreen(),
73
+ config.rapt,
74
+ deviceModel
75
+ ).presetWithPlayButton;
76
+ }
77
+
78
+ /**
79
+ *
80
+ * @param entryId
81
+ * @param cachePlayer - whether this player is a cache-player or not. If not - it will set autoplay to true
82
+ */
83
+ public createPlayer(
84
+ entryId: string,
85
+ playImmediate: boolean,
86
+ persistencyObject?: any,
87
+ showPoster?: boolean,
88
+ startTime?: number
89
+ ): KalturaPlayer {
90
+ // TODO 3 check if the id already exists and if so throw exception
91
+ const {
92
+ id: playerContainerId,
93
+ container: playerContainer
94
+ } = this.domManager.createKalturaPlayerContainer();
95
+
96
+ if(this.config.rapt.showTimers){
97
+ playerContainer.classList.add("has-timers");
98
+ }
99
+
100
+ let conf: any = this.getPlayerConf(
101
+ playerContainerId,
102
+ playImmediate,
103
+ showPoster
104
+ );
105
+
106
+ // persistancy logic of new creation. If a new player is created - push the relevant persistancy attribute to config
107
+ if (persistencyObject) {
108
+ if (persistencyObject) {
109
+ conf.playback.audioLanguage = persistencyObject.audio;
110
+ }
111
+ if (persistencyObject.captions) {
112
+ conf.playback.textLanguage = persistencyObject.captions;
113
+ }
114
+ if (persistencyObject.rate) {
115
+ // todo 5 - find how to initiate this
116
+ }
117
+ // only if this was set, change the logic. If this is not defined leave it as-is
118
+ if (persistencyObject.mute !== undefined) {
119
+ conf.playback.muted = persistencyObject.mute;
120
+ }
121
+ }
122
+ if(startTime){
123
+ conf.playback.startTime = startTime;
124
+ }
125
+
126
+ const newPlayer = this.playerLibrary.setup(conf);
127
+ // if initialBitrate was define, switch back to ABR mode
128
+ if (this.config.rapt.initialBitrate) {
129
+ newPlayer.addEventListener(newPlayer.Event.Core.FIRST_PLAY, e =>
130
+ this.onFirstPlay(e)
131
+ );
132
+ }
133
+
134
+ newPlayer.loadMedia({ entryId: entryId });
135
+ return new KalturaPlayer(newPlayer, playerContainer);
136
+ }
137
+
138
+ // Resets the ABR to work as default.
139
+ public onFirstPlay(e) {
140
+ try {
141
+ e.target.removeEventListener(e.target.Event.Core.FIRST_PLAY, e =>
142
+ this.onFirstPlay(e)
143
+ );
144
+ // TODO - follow up with player team - once they expose this with a method - we will switch this ugly code
145
+ e.target._localPlayer._engine._mediaSourceAdapter._hls.config.minAutoBitrate = 0;
146
+ } catch (e) {
147
+ log("log", "pf_createPlayer", "couldn't switch to ABR ", e);
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Extract the player configuration from the KIV generic config: remove the rapt element and add specific target id
153
+ * @param entryId
154
+ * @param playImmediate - if set to true, the config will use autoPlay=true;
155
+ */
156
+ private getPlayerConf(
157
+ divName: string,
158
+ playImmediate: boolean = false,
159
+ showPoster: boolean = false,
160
+ ): object {
161
+ // clone the base config
162
+ let newConf: RaptConfig = Object.assign({}, this.config);
163
+ newConf.targetId = divName;
164
+ // > v 0.35
165
+ newConf.plugins = newConf.plugins ? newConf.plugins : {};
166
+ newConf.plugins.kava = newConf.plugins.kava ? newConf.plugins.kava : {};
167
+ newConf.plugins.kava.tamperAnalyticsHandler = this.analyticsInterruptFunc;
168
+
169
+ let playback = newConf.playback ? newConf.playback : {};
170
+ if (!showPoster) {
171
+ newConf.sources = { poster: "" }; // for buffering players - we do not need to load the poster
172
+ }
173
+ if (!playImmediate) {
174
+ playback = {
175
+ autoplay: false,
176
+ preload: "auto",
177
+ options: {
178
+ html5: {
179
+ hls: {
180
+ maxMaxBufferLength: this.secondsToBuffer
181
+ }
182
+ }
183
+ }
184
+ };
185
+ } else {
186
+ playback.autoplay = true;
187
+ }
188
+ newConf.playback = playback;
189
+ if (this.config.rapt.initialBitrate) {
190
+ log(
191
+ "error",
192
+ "pf_getPlayerConf",
193
+ "setting initialBitrate to " + this.config.rapt.initialBitrate
194
+ );
195
+ newConf.abr = {
196
+ defaultBandwidthEstimate: this.config.rapt.initialBitrate,
197
+ restrictions: {
198
+ minBitrate: this.config.rapt.initialBitrate
199
+ }
200
+ };
201
+ }
202
+
203
+ try {
204
+ let uis;
205
+ if (showPoster) {
206
+ // this is autoplay=false
207
+ uis = [
208
+ {
209
+ template: props => this.playbackPresetWithPlayButton(props)
210
+ }
211
+ ];
212
+ } else {
213
+ uis = [
214
+ {
215
+ template: props => this.playbackPreset(props)
216
+ }
217
+ ];
218
+ }
219
+ newConf.ui = newConf.ui || {};
220
+ newConf.ui.components = {
221
+ fullscreen: {
222
+ disableDoubleClick: true
223
+ }
224
+ },
225
+ newConf.ui.customPreset = uis;
226
+ } catch (e) {
227
+ log("error", "pf_getPlayerConf", "failed applying V3 custom preset");
228
+ }
229
+ delete newConf.rapt;
230
+ return newConf;
231
+ }
232
+
233
+ toggleFullscreen(): void {
234
+ this.dispatch({ type: KipFullscreen.FULL_SCREEN_CLICKED });
235
+ }
236
+ }