react-native-theoplayer 8.13.1 → 8.15.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 (54) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +17 -0
  3. package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +13 -7
  4. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +7 -0
  5. package/ios/THEOplayerRCTView.swift +24 -1
  6. package/ios/ads/THEOplayerRCTSourceDescriptionBuilder+Ads.swift +32 -21
  7. package/ios/ads/THEOplayerRCTView+Ads.swift +5 -3
  8. package/ios/backgroundAudio/THEOplayerRCTNowPlayingManager.swift +2 -1
  9. package/ios/casting/THEOplayerRCTView+Casting.swift +4 -2
  10. package/ios/presentationMode/THEOplayerRCTPresentationModeManager.swift +10 -19
  11. package/ios/theoAds/THEOplayerRCTSourceDescriptionBuilder+TheoAds.swift +62 -0
  12. package/ios/theoAds/THEOplayerRCTView+TheoAds.swift +23 -0
  13. package/lib/commonjs/api/theolive/TheoLiveConfiguration.js +2 -0
  14. package/lib/commonjs/api/theolive/TheoLiveConfiguration.js.map +1 -0
  15. package/lib/commonjs/api/theolive/barrel.js +11 -0
  16. package/lib/commonjs/api/theolive/barrel.js.map +1 -1
  17. package/lib/commonjs/internal/THEOplayerView.web.js +16 -5
  18. package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
  19. package/lib/commonjs/internal/adapter/WebEventForwarder.js +0 -1
  20. package/lib/commonjs/internal/adapter/WebEventForwarder.js.map +1 -1
  21. package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js +11 -27
  22. package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
  23. package/lib/commonjs/manifest.json +1 -1
  24. package/lib/module/api/theolive/TheoLiveConfiguration.js +2 -0
  25. package/lib/module/api/theolive/TheoLiveConfiguration.js.map +1 -0
  26. package/lib/module/api/theolive/barrel.js +1 -0
  27. package/lib/module/api/theolive/barrel.js.map +1 -1
  28. package/lib/module/internal/THEOplayerView.web.js +16 -5
  29. package/lib/module/internal/THEOplayerView.web.js.map +1 -1
  30. package/lib/module/internal/adapter/WebEventForwarder.js +0 -1
  31. package/lib/module/internal/adapter/WebEventForwarder.js.map +1 -1
  32. package/lib/module/internal/adapter/web/WebPresentationModeManager.js +11 -27
  33. package/lib/module/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
  34. package/lib/module/manifest.json +1 -1
  35. package/lib/typescript/api/config/PlayerConfiguration.d.ts +7 -0
  36. package/lib/typescript/api/config/PlayerConfiguration.d.ts.map +1 -1
  37. package/lib/typescript/api/theolive/TheoLiveConfiguration.d.ts +38 -0
  38. package/lib/typescript/api/theolive/TheoLiveConfiguration.d.ts.map +1 -0
  39. package/lib/typescript/api/theolive/barrel.d.ts +1 -0
  40. package/lib/typescript/api/theolive/barrel.d.ts.map +1 -1
  41. package/lib/typescript/internal/THEOplayerView.web.d.ts.map +1 -1
  42. package/lib/typescript/internal/adapter/WebEventForwarder.d.ts.map +1 -1
  43. package/lib/typescript/internal/adapter/web/WebPresentationModeManager.d.ts +1 -2
  44. package/lib/typescript/internal/adapter/web/WebPresentationModeManager.d.ts.map +1 -1
  45. package/package.json +1 -1
  46. package/react-native-theoplayer.json +1 -1
  47. package/react-native-theoplayer.podspec +6 -1
  48. package/src/api/config/PlayerConfiguration.ts +8 -0
  49. package/src/api/theolive/TheoLiveConfiguration.ts +40 -0
  50. package/src/api/theolive/barrel.ts +1 -0
  51. package/src/internal/THEOplayerView.web.tsx +5 -2
  52. package/src/internal/adapter/WebEventForwarder.ts +0 -1
  53. package/src/internal/adapter/web/WebPresentationModeManager.ts +11 -28
  54. package/src/manifest.json +1 -1
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The configuration THEOlive playback.
3
+ *
4
+ * @public
5
+ */
6
+ export interface TheoLiveConfiguration {
7
+ /**
8
+ * An id used to report usage analytics, if not explicitly given a random UUID is used.
9
+ *
10
+ * @remarks
11
+ * <br/> - Available on Web and Android only.
12
+ */
13
+ readonly externalSessionId?: string;
14
+
15
+ /**
16
+ * Whether this player should fallback or not when it has a fallback configured.
17
+ *
18
+ * @remarks
19
+ * <br/> - Available on Web only.
20
+ */
21
+ readonly fallbackEnabled?: boolean;
22
+
23
+ /**
24
+ * An optional header that can be passed during discovery.
25
+ *
26
+ * @remarks
27
+ * <br/> - Available on Web only.
28
+ */
29
+ readonly discoveryHeader?: string;
30
+
31
+ /**
32
+ * Whether THEOlive analytics should be disabled or not.
33
+ *
34
+ * @remarks
35
+ * <br/> - Available on Android only.
36
+ *
37
+ * @defaultValue `false`
38
+ */
39
+ readonly analyticsDisabled?: boolean;
40
+ }
@@ -1 +1,2 @@
1
1
  export * from './TheoLiveSource';
2
+ export * from './TheoLiveConfiguration';
@@ -66,14 +66,17 @@ export function THEOplayerView(props: React.PropsWithChildren<THEOplayerViewProp
66
66
 
67
67
  const chromeless = config?.chromeless === undefined || config?.chromeless;
68
68
  return (
69
- <>
69
+ // Note: display: contents causes an element's children to appear as if they were direct children of the element's parent,
70
+ // ignoring the element itself.
71
+ // It's necessary to make sure we do not interfere with the IMA container
72
+ <div id={'theoplayer-root-container'} style={{ display: 'contents' }}>
70
73
  <div
71
74
  ref={container}
72
75
  style={styles.container}
73
76
  className={chromeless ? 'theoplayer-container' : 'theoplayer-container video-js theoplayer-skin'}
74
77
  />
75
78
  {children}
76
- </>
79
+ </div>
77
80
  );
78
81
  }
79
82
 
@@ -88,7 +88,6 @@ export class WebEventForwarder {
88
88
  this._player.addEventListener('segmentnotfound', this.onSegmentNotFound);
89
89
  this._player.addEventListener('volumechange', this.onVolumeChangeEvent);
90
90
  this._player.addEventListener('dimensionchange', this.onDimensionChange);
91
- this._player.presentation.addEventListener('presentationmodechange', this.onPresentationModeChange);
92
91
 
93
92
  this._player.textTracks.addEventListener('addtrack', this.onAddTextTrack);
94
93
  this._player.textTracks.addEventListener('removetrack', this.onRemoveTextTrack);
@@ -9,13 +9,13 @@ import { noOp } from '../../utils/CommonUtils';
9
9
  export class WebPresentationModeManager {
10
10
  private readonly _player: ChromelessPlayer;
11
11
  private _presentationMode: PresentationMode = PresentationMode.inline;
12
- private _element: HTMLVideoElement | undefined = undefined;
13
12
  private _eventForwarder: DefaultEventDispatcher<PlayerEventMap>;
14
13
 
15
14
  constructor(player: ChromelessPlayer, eventForwarder: DefaultEventDispatcher<PlayerEventMap>) {
16
15
  this._player = player;
17
16
  this._eventForwarder = eventForwarder;
18
17
  this._player.presentation.addEventListener('presentationmodechange', this.updatePresentationMode);
18
+ this.maybePrepareForPresentationModeChanges();
19
19
  }
20
20
 
21
21
  get presentationMode(): PresentationMode {
@@ -24,57 +24,40 @@ export class WebPresentationModeManager {
24
24
 
25
25
  set presentationMode(presentationMode: PresentationMode) {
26
26
  if (presentationMode === this._presentationMode) {
27
+ // Ignore if presentationMode did not change.
27
28
  return;
28
29
  }
29
30
 
30
- this.prepareForPresentationModeChanges();
31
-
32
31
  if (fullscreenAPI !== undefined) {
33
- // All other browsers
32
+ // If the browser supports the fullscreenAPI, put the element that encloses the player & UI in fullscreen.
34
33
  if (presentationMode === PresentationMode.fullscreen) {
35
- const appElement = document.getElementById('app') ?? document.getElementById('root');
34
+ const appElement = document.getElementById('theoplayer-root-container');
36
35
  if (appElement !== null) {
37
- const promise = appElement[fullscreenAPI.requestFullscreen_]();
38
- if (promise && promise.then) {
39
- promise.then(noOp, noOp);
40
- }
36
+ appElement[fullscreenAPI.requestFullscreen_]()?.then?.(noOp, noOp);
41
37
  }
42
38
  } else if (presentationMode === PresentationMode.pip) {
43
39
  this._player.presentation.requestMode('native-picture-in-picture');
44
40
  } else {
45
41
  if (this._presentationMode === PresentationMode.fullscreen) {
46
- const promise = document[fullscreenAPI.exitFullscreen_]();
47
- if (promise && promise.then) {
48
- promise.then(noOp, noOp);
49
- }
42
+ document[fullscreenAPI.exitFullscreen_]()?.then?.(noOp, noOp);
50
43
  }
51
44
  if (this._presentationMode === PresentationMode.pip) {
52
- void document.exitPictureInPicture();
45
+ this._player.presentation.requestMode(PresentationMode.inline);
53
46
  }
54
47
  }
55
48
  } else {
56
- // iOS Safari doesn't properly support fullscreen, use native fullscreen instead
49
+ // Some browsers, like iOS Safari, can only put a videoElement in fullscreen; let the player decide which one.
57
50
  if (presentationMode === PresentationMode.fullscreen) {
58
- this._element?.webkitEnterFullscreen?.();
51
+ this._player.presentation.requestMode(PresentationMode.fullscreen);
59
52
  } else if (presentationMode === PresentationMode.pip) {
60
53
  this._player.presentation.requestMode('native-picture-in-picture');
61
54
  } else {
62
- this._element?.webkitSetPresentationMode?.(PresentationMode.inline);
55
+ this._player.presentation.requestMode(PresentationMode.inline);
63
56
  }
64
57
  }
65
58
  }
66
59
 
67
- private prepareForPresentationModeChanges() {
68
- const elements = this._player.element.children;
69
- for (const element of Array.from(elements)) {
70
- if (element.tagName === 'VIDEO') {
71
- const videoElement = element as HTMLVideoElement;
72
- if ((videoElement.src !== null && videoElement.src !== '') || videoElement.srcObject !== null) {
73
- this._element = videoElement;
74
- break;
75
- }
76
- }
77
- }
60
+ private maybePrepareForPresentationModeChanges() {
78
61
  // listen for fullscreen updates on document
79
62
  if (fullscreenAPI !== undefined) {
80
63
  document.addEventListener(fullscreenAPI.fullscreenchange_, this.updatePresentationMode);
package/src/manifest.json CHANGED
@@ -1 +1 @@
1
- {"version":"8.13.1","buildDate":"2025-01-27T12:46:49.795Z"}
1
+ {"version":"8.15.0","buildDate":"2025-02-12T15:09:50.188Z"}