react-native-theoplayer 2.5.0 → 2.7.0

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.
Files changed (56) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +9 -15
  3. package/android/src/main/java/com/theoplayer/util/PayloadBuilder.kt +2 -1
  4. package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +9 -1
  5. package/ios/THEOplayerRCTDebug.swift +3 -3
  6. package/ios/THEOplayerRCTMainEventHandler.swift +59 -59
  7. package/ios/THEOplayerRCTMediaTrackEventHandler.swift +18 -18
  8. package/ios/THEOplayerRCTNetworkUtils.swift +1 -1
  9. package/ios/THEOplayerRCTPlayerAPI.swift +14 -14
  10. package/ios/THEOplayerRCTPrintUtils.swift +16 -0
  11. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +6 -6
  12. package/ios/THEOplayerRCTTextTrackEventHandler.swift +21 -21
  13. package/ios/THEOplayerRCTView.swift +29 -29
  14. package/ios/ads/THEOplayerRCTAdsAPI+DAI.swift +6 -6
  15. package/ios/ads/THEOplayerRCTAdsAPI.swift +13 -13
  16. package/ios/ads/THEOplayerRCTAdsEventHandler.swift +27 -27
  17. package/ios/ads/THEOplayerRCTSourceDescriptionBuilder+Ads.swift +5 -5
  18. package/ios/backgroundAudio/THEOplayerRCTNowPlayingManager.swift +63 -37
  19. package/ios/backgroundAudio/THEOplayerRCTRemoteCommandsManager.swift +16 -16
  20. package/ios/casting/THEOplayerRCTCastAPI+Airplay.swift +6 -6
  21. package/ios/casting/THEOplayerRCTCastAPI+Chromecast.swift +10 -10
  22. package/ios/casting/THEOplayerRCTCastAPI.swift +1 -1
  23. package/ios/casting/THEOplayerRCTCastEventHandler.swift +11 -11
  24. package/ios/contentprotection/THEOplayerRCTContentProtectionAPI.swift +1 -1
  25. package/ios/pip/THEOplayerRCTPipControlsManager.swift +1 -1
  26. package/lib/commonjs/api/abr/ABRConfiguration.js +25 -0
  27. package/lib/commonjs/api/abr/ABRConfiguration.js.map +1 -1
  28. package/lib/commonjs/api/track/Track.js +5 -1
  29. package/lib/commonjs/api/track/Track.js.map +1 -1
  30. package/lib/commonjs/internal/THEOplayerView.web.js +2 -6
  31. package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
  32. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js +41 -10
  33. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js.map +1 -1
  34. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js +105 -52
  35. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  36. package/lib/module/api/abr/ABRConfiguration.js +19 -0
  37. package/lib/module/api/abr/ABRConfiguration.js.map +1 -1
  38. package/lib/module/api/track/Track.js +4 -1
  39. package/lib/module/api/track/Track.js.map +1 -1
  40. package/lib/module/internal/THEOplayerView.web.js +2 -6
  41. package/lib/module/internal/THEOplayerView.web.js.map +1 -1
  42. package/lib/module/internal/adapter/THEOplayerAdapter.js +41 -10
  43. package/lib/module/internal/adapter/THEOplayerAdapter.js.map +1 -1
  44. package/lib/module/internal/adapter/THEOplayerWebAdapter.js +106 -53
  45. package/lib/module/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  46. package/lib/typescript/api/abr/ABRConfiguration.d.ts +5 -1
  47. package/lib/typescript/api/track/Track.d.ts +1 -0
  48. package/lib/typescript/internal/adapter/THEOplayerAdapter.d.ts +2 -0
  49. package/lib/typescript/internal/adapter/THEOplayerWebAdapter.d.ts +3 -3
  50. package/package.json +1 -1
  51. package/react-native-theoplayer.podspec +1 -1
  52. package/src/api/abr/ABRConfiguration.ts +5 -1
  53. package/src/api/track/Track.ts +5 -1
  54. package/src/internal/THEOplayerView.web.tsx +2 -6
  55. package/src/internal/adapter/THEOplayerAdapter.ts +44 -10
  56. package/src/internal/adapter/THEOplayerWebAdapter.ts +97 -50
@@ -11,7 +11,7 @@ import type {
11
11
  TextTrackStyle,
12
12
  THEOplayer,
13
13
  } from 'react-native-theoplayer';
14
- import { AspectRatio, PresentationMode } from 'react-native-theoplayer';
14
+ import { AspectRatio, PlayerEventType, PresentationMode } from 'react-native-theoplayer';
15
15
  import { THEOplayerWebAdsAdapter } from './ads/THEOplayerWebAdsAdapter';
16
16
  import { THEOplayerWebCastAdapter } from './cast/THEOplayerWebCastAdapter';
17
17
  import type * as THEOplayerWeb from 'theoplayer';
@@ -23,6 +23,7 @@ import type { PiPConfiguration } from 'src/api/pip/PiPConfiguration';
23
23
  import type { BackgroundAudioConfiguration } from 'src/api/backgroundAudio/BackgroundAudioConfiguration';
24
24
  import { WebPresentationModeManager } from './web/WebPresentationModeManager';
25
25
  import { WebMediaSession } from './web/WebMediaSession';
26
+ import { BaseEvent } from './event/BaseEvent';
26
27
 
27
28
  const defaultBackgroundAudioConfiguration: BackgroundAudioConfiguration = {
28
29
  enabled: false,
@@ -33,12 +34,12 @@ const defaultPipConfiguration: PiPConfiguration = {
33
34
  };
34
35
 
35
36
  export class THEOplayerWebAdapter extends DefaultEventDispatcher<PlayerEventMap> implements THEOplayer {
36
- private readonly _player: THEOplayerWeb.ChromelessPlayer;
37
37
  private readonly _adsAdapter: THEOplayerWebAdsAdapter;
38
38
  private readonly _castAdapter: THEOplayerWebCastAdapter;
39
- private readonly _eventForwarder: WebEventForwarder;
40
39
  private readonly _presentationModeManager: WebPresentationModeManager;
41
- private readonly _mediaSession: WebMediaSession | undefined = undefined;
40
+ private _player: THEOplayerWeb.ChromelessPlayer | undefined;
41
+ private _eventForwarder: WebEventForwarder | undefined;
42
+ private _mediaSession: WebMediaSession | undefined = undefined;
42
43
  private _targetVideoQuality: number | number[] | undefined = undefined;
43
44
  private _backgroundAudioConfiguration: BackgroundAudioConfiguration = defaultBackgroundAudioConfiguration;
44
45
  private _pipConfiguration: PiPConfiguration = defaultPipConfiguration;
@@ -59,62 +60,76 @@ export class THEOplayerWebAdapter extends DefaultEventDispatcher<PlayerEventMap>
59
60
  }
60
61
 
61
62
  get abr(): ABRConfiguration | undefined {
62
- return this._player.abr;
63
+ return this._player?.abr as ABRConfiguration | undefined;
63
64
  }
64
65
 
65
66
  get source(): SourceDescription | undefined {
66
- return this._player.source as SourceDescription;
67
+ return this._player?.source as SourceDescription;
67
68
  }
68
69
 
69
70
  set source(source: SourceDescription | undefined) {
70
71
  this._targetVideoQuality = undefined;
71
- this._player.source = source;
72
+ if (this._player) {
73
+ this._player.source = source;
74
+ }
72
75
  }
73
76
 
74
77
  play(): void {
75
- this._player.play();
78
+ this._player?.play();
76
79
  }
77
80
 
78
81
  pause(): void {
79
- this._player.pause();
82
+ this._player?.pause();
80
83
  }
81
84
 
82
85
  get paused(): boolean {
83
- return this._player.paused;
86
+ return this._player ? this._player.paused : true;
84
87
  }
85
88
 
86
89
  get autoplay(): boolean {
87
- return this._player.autoplay;
90
+ return this._player ? this._player.autoplay : false;
88
91
  }
89
92
 
90
93
  set autoplay(autoplay: boolean) {
91
- this._player.autoplay = autoplay;
94
+ if (this._player) {
95
+ this._player.autoplay = autoplay;
96
+ }
92
97
  }
93
98
 
94
99
  set preload(type: PreloadType) {
95
- this._player.preload = type;
100
+ if (this._player) {
101
+ this._player.preload = type;
102
+ }
96
103
  }
97
104
 
98
105
  get preload(): PreloadType {
99
- return this._player.preload;
106
+ return this._player?.preload || 'none';
100
107
  }
101
108
 
102
109
  get seekable() {
110
+ if (!this._player) {
111
+ return [];
112
+ }
103
113
  const nativeRange = this._player.seekable;
104
114
  return [...Array(nativeRange.length)].map((_, index) => ({ start: 1e3 * nativeRange.start(index), end: 1e3 * nativeRange.end(index) }));
105
115
  }
106
116
 
107
117
  get buffered() {
118
+ if (!this._player) {
119
+ return [];
120
+ }
108
121
  const nativeRange = this._player.buffered;
109
122
  return [...Array(nativeRange.length)].map((_, index) => ({ start: 1e3 * nativeRange.start(index), end: 1e3 * nativeRange.end(index) }));
110
123
  }
111
124
 
112
125
  get playbackRate(): number {
113
- return this._player.playbackRate;
126
+ return this._player ? this._player.playbackRate : 1;
114
127
  }
115
128
 
116
129
  set playbackRate(playbackRate: number) {
117
- this._player.playbackRate = playbackRate;
130
+ if (this._player) {
131
+ this._player.playbackRate = playbackRate;
132
+ }
118
133
  }
119
134
 
120
135
  get pipConfiguration(): PiPConfiguration {
@@ -137,23 +152,27 @@ export class THEOplayerWebAdapter extends DefaultEventDispatcher<PlayerEventMap>
137
152
  }
138
153
 
139
154
  get volume(): number {
140
- return this._player.volume;
155
+ return this._player ? this._player.volume : 1;
141
156
  }
142
157
 
143
158
  set volume(volume: number) {
144
- this._player.volume = volume;
159
+ if (this._player) {
160
+ this._player.volume = volume;
161
+ }
145
162
  }
146
163
 
147
164
  get muted(): boolean {
148
- return this._player.muted;
165
+ return this._player ? this._player.muted : false;
149
166
  }
150
167
 
151
168
  set muted(muted: boolean) {
152
- this._player.muted = muted;
169
+ if (this._player) {
170
+ this._player.muted = muted;
171
+ }
153
172
  }
154
173
 
155
174
  get seeking(): boolean {
156
- return this._player.seeking;
175
+ return this._player ? this._player.seeking : false;
157
176
  }
158
177
 
159
178
  get presentationMode(): PresentationMode {
@@ -165,70 +184,90 @@ export class THEOplayerWebAdapter extends DefaultEventDispatcher<PlayerEventMap>
165
184
  }
166
185
 
167
186
  get audioTracks(): MediaTrack[] {
168
- return fromNativeMediaTrackList(this._player.audioTracks);
187
+ return this._player ? fromNativeMediaTrackList(this._player.audioTracks) : [];
169
188
  }
170
189
 
171
190
  get videoTracks(): MediaTrack[] {
172
- return fromNativeMediaTrackList(this._player.videoTracks);
191
+ return this._player ? fromNativeMediaTrackList(this._player.videoTracks) : [];
173
192
  }
174
193
 
175
194
  get textTracks(): TextTrack[] {
176
- return fromNativeTextTrackList(this._player.textTracks);
195
+ return this._player ? fromNativeTextTrackList(this._player.textTracks) : [];
177
196
  }
178
197
 
179
198
  get selectedTextTrack(): number | undefined {
180
- return this._player.textTracks.find((textTrack: NativeTextTrack) => {
181
- return textTrack.mode === 'showing';
182
- })?.uid;
199
+ if (this._player) {
200
+ return this._player.textTracks.find((textTrack: NativeTextTrack) => {
201
+ return textTrack.mode === 'showing';
202
+ })?.uid;
203
+ }
204
+ return undefined;
183
205
  }
184
206
 
185
207
  set selectedTextTrack(selectedTextTrack: number | undefined) {
186
- this._player.textTracks.forEach((textTrack: NativeTextTrack) => {
187
- textTrack.mode = textTrack.uid === selectedTextTrack ? 'showing' : 'disabled';
188
- });
208
+ if (this._player) {
209
+ this._player.textTracks.forEach((textTrack: NativeTextTrack) => {
210
+ textTrack.mode = textTrack.uid === selectedTextTrack ? 'showing' : 'disabled';
211
+ });
212
+ }
189
213
  }
190
214
 
191
215
  get textTrackStyle(): TextTrackStyle {
192
- return this._player.textTrackStyle as TextTrackStyle;
216
+ return this._player?.textTrackStyle as TextTrackStyle;
193
217
  }
194
218
 
195
219
  get selectedVideoTrack(): number | undefined {
196
- return this._player.videoTracks.find((videoTrack: NativeMediaTrack) => videoTrack.enabled)?.uid;
220
+ if (this._player) {
221
+ return this._player.videoTracks.find((videoTrack: NativeMediaTrack) => videoTrack.enabled)?.uid;
222
+ }
223
+ return undefined;
197
224
  }
198
225
 
199
226
  set selectedVideoTrack(selectedVideoTrack: number | undefined) {
200
- this._targetVideoQuality = undefined;
201
- this._player.videoTracks.forEach((videoTrack: NativeMediaTrack) => {
202
- videoTrack.enabled = videoTrack.uid === selectedVideoTrack;
203
- });
227
+ if (this._player) {
228
+ this._targetVideoQuality = undefined;
229
+ this._player.videoTracks.forEach((videoTrack: NativeMediaTrack) => {
230
+ videoTrack.enabled = videoTrack.uid === selectedVideoTrack;
231
+ });
232
+ }
204
233
  }
205
234
 
206
235
  get selectedAudioTrack(): number | undefined {
207
- return this._player.audioTracks.find((audioTrack: NativeMediaTrack) => {
208
- return audioTrack.enabled;
209
- })?.uid;
236
+ if (this._player) {
237
+ return this._player.audioTracks.find((audioTrack: NativeMediaTrack) => {
238
+ return audioTrack.enabled;
239
+ })?.uid;
240
+ }
241
+ return undefined;
210
242
  }
211
243
 
212
244
  set selectedAudioTrack(selectedAudioTrack: number | undefined) {
213
- this._player.audioTracks.forEach((audioTrack: NativeMediaTrack) => {
214
- audioTrack.enabled = audioTrack.uid === selectedAudioTrack;
215
- });
245
+ if (this._player) {
246
+ this._player.audioTracks.forEach((audioTrack: NativeMediaTrack) => {
247
+ audioTrack.enabled = audioTrack.uid === selectedAudioTrack;
248
+ });
249
+ }
216
250
  }
217
251
 
218
252
  get targetVideoQuality(): number | number[] | undefined {
219
- return this._targetVideoQuality;
253
+ if (this._player) {
254
+ return this._targetVideoQuality;
255
+ }
256
+ return undefined;
220
257
  }
221
258
 
222
259
  set targetVideoQuality(targetVideoQuality: number | number[] | undefined) {
223
- const enabledVideoTrack = this._player.videoTracks.find((videoTrack: NativeMediaTrack) => videoTrack.enabled);
224
- if (enabledVideoTrack) {
225
- enabledVideoTrack.targetQuality = findNativeQualitiesByUid(enabledVideoTrack, targetVideoQuality);
260
+ if (this._player) {
261
+ const enabledVideoTrack = this._player.videoTracks.find((videoTrack: NativeMediaTrack) => videoTrack.enabled);
262
+ if (enabledVideoTrack) {
263
+ enabledVideoTrack.targetQuality = findNativeQualitiesByUid(enabledVideoTrack, targetVideoQuality);
264
+ }
265
+ this._targetVideoQuality = targetVideoQuality;
226
266
  }
227
- this._targetVideoQuality = targetVideoQuality;
228
267
  }
229
268
 
230
269
  get currentTime(): number {
231
- return 1e3 * this._player.currentTime;
270
+ return this._player ? 1e3 * this._player.currentTime : NaN;
232
271
  }
233
272
 
234
273
  set currentTime(currentTime: number) {
@@ -249,7 +288,7 @@ export class THEOplayerWebAdapter extends DefaultEventDispatcher<PlayerEventMap>
249
288
  }
250
289
 
251
290
  get duration(): number {
252
- return this._player.duration * 1e3;
291
+ return this._player ? this._player.duration * 1e3 : NaN;
253
292
  }
254
293
 
255
294
  public get ads(): AdsAPI {
@@ -261,9 +300,14 @@ export class THEOplayerWebAdapter extends DefaultEventDispatcher<PlayerEventMap>
261
300
  }
262
301
 
263
302
  destroy(): void {
264
- this._eventForwarder.unload();
303
+ this.dispatchEvent(new BaseEvent(PlayerEventType.DESTROY));
304
+ this._eventForwarder?.unload();
265
305
  this._mediaSession?.destroy();
266
306
  document.removeEventListener('visibilitychange', this.onVisibilityChange);
307
+ this._eventForwarder = undefined;
308
+ this._mediaSession = undefined;
309
+ this._player?.destroy();
310
+ this._player = undefined;
267
311
  }
268
312
 
269
313
  get nativeHandle(): NativeHandleType {
@@ -271,6 +315,9 @@ export class THEOplayerWebAdapter extends DefaultEventDispatcher<PlayerEventMap>
271
315
  }
272
316
 
273
317
  private readonly onVisibilityChange = () => {
318
+ if (!this._player) {
319
+ return;
320
+ }
274
321
  if (document.visibilityState !== 'visible') {
275
322
  // Apply background configuration: by default, pause when going to background, unless in pip
276
323
  if (this.presentationMode !== PresentationMode.pip && !this.backgroundAudioConfiguration.enabled) {