react-native-theoplayer 2.6.0 → 2.8.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 (80) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/android/build.gradle +1 -1
  3. package/android/local/com/theoplayer/android-connector/mediasession/5.2.0-local/mediasession-5.2.0-local.aar +0 -0
  4. package/android/local/com/theoplayer/android-connector/mediasession/{4.12.0-local/mediasession-4.12.0-local.pom → 5.2.0-local/mediasession-5.2.0-local.pom} +1 -1
  5. package/android/local/com/theoplayer/android-connector/mediasession/maven-metadata-local.xml +4 -4
  6. package/android/src/main/AndroidManifest.xml +2 -2
  7. package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +1 -1
  8. package/android/src/main/java/com/theoplayer/ReactTHEOplayerContext.kt +36 -20
  9. package/android/src/main/java/com/theoplayer/media/CustomMediaButtonReceiver.kt +25 -0
  10. package/android/src/main/java/com/theoplayer/{audio → media}/MediaNotificationBuilder.kt +1 -1
  11. package/android/src/main/java/com/theoplayer/{audio → media}/MediaPlaybackService.kt +8 -3
  12. package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +12 -0
  13. package/android/src/main/java/com/theoplayer/track/TrackListAdapter.kt +17 -13
  14. package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +9 -1
  15. package/ios/THEOplayerRCTDebug.swift +3 -3
  16. package/ios/THEOplayerRCTMainEventHandler.swift +59 -59
  17. package/ios/THEOplayerRCTMediaTrackEventHandler.swift +18 -18
  18. package/ios/THEOplayerRCTNetworkUtils.swift +1 -1
  19. package/ios/THEOplayerRCTPlayerAPI.swift +14 -14
  20. package/ios/THEOplayerRCTPrintUtils.swift +16 -0
  21. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +6 -6
  22. package/ios/THEOplayerRCTTextTrackEventHandler.swift +21 -21
  23. package/ios/THEOplayerRCTView.swift +29 -29
  24. package/ios/ads/THEOplayerRCTAdsAPI+DAI.swift +6 -6
  25. package/ios/ads/THEOplayerRCTAdsAPI.swift +13 -13
  26. package/ios/ads/THEOplayerRCTAdsEventHandler.swift +27 -27
  27. package/ios/ads/THEOplayerRCTSourceDescriptionBuilder+Ads.swift +5 -5
  28. package/ios/backgroundAudio/THEOplayerRCTNowPlayingManager.swift +16 -15
  29. package/ios/backgroundAudio/THEOplayerRCTRemoteCommandsManager.swift +16 -16
  30. package/ios/casting/THEOplayerRCTCastAPI+Airplay.swift +6 -6
  31. package/ios/casting/THEOplayerRCTCastAPI+Chromecast.swift +10 -10
  32. package/ios/casting/THEOplayerRCTCastAPI.swift +1 -1
  33. package/ios/casting/THEOplayerRCTCastEventHandler.swift +11 -11
  34. package/ios/contentprotection/THEOplayerRCTContentProtectionAPI.swift +1 -1
  35. package/ios/pip/THEOplayerRCTPipControlsManager.swift +1 -1
  36. package/lib/commonjs/api/source/dash/DashPlaybackConfiguration.js.map +1 -1
  37. package/lib/commonjs/api/track/TextTrack.js.map +1 -1
  38. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js +58 -10
  39. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js.map +1 -1
  40. package/lib/commonjs/internal/adapter/web/FullscreenAPI.js +41 -0
  41. package/lib/commonjs/internal/adapter/web/FullscreenAPI.js.map +1 -0
  42. package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js +45 -39
  43. package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
  44. package/lib/commonjs/internal/utils/CommonUtils.js +10 -0
  45. package/lib/commonjs/internal/utils/CommonUtils.js.map +1 -0
  46. package/lib/commonjs/ui/components/seekbar/thumbnail/Urlpolyfill.web.js +4 -11
  47. package/lib/commonjs/ui/components/seekbar/thumbnail/Urlpolyfill.web.js.map +1 -1
  48. package/lib/module/api/source/dash/DashPlaybackConfiguration.js.map +1 -1
  49. package/lib/module/api/track/TextTrack.js.map +1 -1
  50. package/lib/module/internal/adapter/THEOplayerAdapter.js +59 -11
  51. package/lib/module/internal/adapter/THEOplayerAdapter.js.map +1 -1
  52. package/lib/module/internal/adapter/web/FullscreenAPI.js +34 -0
  53. package/lib/module/internal/adapter/web/FullscreenAPI.js.map +1 -0
  54. package/lib/module/internal/adapter/web/WebPresentationModeManager.js +45 -39
  55. package/lib/module/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
  56. package/lib/module/internal/utils/CommonUtils.js +4 -0
  57. package/lib/module/internal/utils/CommonUtils.js.map +1 -0
  58. package/lib/module/ui/components/seekbar/thumbnail/Urlpolyfill.web.js +3 -2
  59. package/lib/module/ui/components/seekbar/thumbnail/Urlpolyfill.web.js.map +1 -1
  60. package/lib/typescript/api/source/dash/DashPlaybackConfiguration.d.ts +52 -0
  61. package/lib/typescript/api/track/TextTrack.d.ts +2 -2
  62. package/lib/typescript/internal/adapter/THEOplayerAdapter.d.ts +3 -0
  63. package/lib/typescript/internal/adapter/web/FullscreenAPI.d.ts +9 -0
  64. package/lib/typescript/internal/utils/CommonUtils.d.ts +1 -0
  65. package/lib/typescript/ui/components/seekbar/thumbnail/Urlpolyfill.web.d.ts +8 -1
  66. package/package.json +1 -1
  67. package/src/api/source/dash/DashPlaybackConfiguration.ts +56 -0
  68. package/src/api/track/TextTrack.ts +2 -2
  69. package/src/internal/adapter/THEOplayerAdapter.ts +63 -10
  70. package/src/internal/adapter/web/FullscreenAPI.ts +59 -0
  71. package/src/internal/adapter/web/WebPresentationModeManager.ts +29 -22
  72. package/src/internal/utils/CommonUtils.ts +3 -0
  73. package/src/ui/components/seekbar/thumbnail/Urlpolyfill.web.ts +3 -2
  74. package/android/local/com/theoplayer/android-connector/mediasession/4.12.0-local/mediasession-4.12.0-local.aar +0 -0
  75. package/lib/commonjs/web/platform/BrowserDetection.js +0 -34
  76. package/lib/commonjs/web/platform/BrowserDetection.js.map +0 -1
  77. package/lib/module/web/platform/BrowserDetection.js +0 -27
  78. package/lib/module/web/platform/BrowserDetection.js.map +0 -1
  79. package/lib/typescript/web/platform/BrowserDetection.d.ts +0 -23
  80. package/src/web/platform/BrowserDetection.ts +0 -38
@@ -0,0 +1,34 @@
1
+ export const fullscreenAPI = (() => {
2
+ if (!document) {
3
+ return;
4
+ }
5
+
6
+ // browser API methods
7
+ // map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js
8
+ const apiMap = [
9
+ // Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
10
+ ['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
11
+ // WebKit
12
+ ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
13
+ // Old WebKit (Safari 5.1)
14
+ ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
15
+ // Mozilla
16
+ ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
17
+ // Microsoft
18
+ ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
19
+ for (const browserMap of apiMap) {
20
+ // check for exitFullscreen function
21
+ if (browserMap[1] in document) {
22
+ return {
23
+ requestFullscreen_: browserMap[0],
24
+ exitFullscreen_: browserMap[1],
25
+ fullscreenElement_: browserMap[2],
26
+ fullscreenEnabled_: browserMap[3],
27
+ fullscreenchange_: browserMap[4],
28
+ fullscreenerror_: browserMap[5]
29
+ };
30
+ }
31
+ }
32
+ return undefined;
33
+ })();
34
+ //# sourceMappingURL=FullscreenAPI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["fullscreenAPI","document","apiMap","browserMap","requestFullscreen_","exitFullscreen_","fullscreenElement_","fullscreenEnabled_","fullscreenchange_","fullscreenerror_","undefined"],"sources":["FullscreenAPI.ts"],"sourcesContent":["export interface FullscreenAPIMap {\n requestFullscreen_: 'requestFullscreen';\n exitFullscreen_: 'exitFullscreen';\n fullscreenElement_: 'fullscreenElement';\n fullscreenEnabled_: 'fullscreenEnabled';\n fullscreenchange_: 'fullscreenchange';\n fullscreenerror_: 'fullscreenerror';\n}\n\nexport const fullscreenAPI: FullscreenAPIMap | undefined = (() => {\n if (!document) {\n return;\n }\n\n // browser API methods\n // map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js\n const apiMap: string[][] = [\n // Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html\n ['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],\n // WebKit\n [\n 'webkitRequestFullscreen',\n 'webkitExitFullscreen',\n 'webkitFullscreenElement',\n 'webkitFullscreenEnabled',\n 'webkitfullscreenchange',\n 'webkitfullscreenerror'\n ],\n // Old WebKit (Safari 5.1)\n [\n 'webkitRequestFullScreen',\n 'webkitCancelFullScreen',\n 'webkitCurrentFullScreenElement',\n 'webkitCancelFullScreen',\n 'webkitfullscreenchange',\n 'webkitfullscreenerror'\n ],\n // Mozilla\n ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],\n // Microsoft\n ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']\n ];\n\n for (const browserMap of apiMap) {\n // check for exitFullscreen function\n if (browserMap[1] in document) {\n return {\n requestFullscreen_: browserMap[0],\n exitFullscreen_: browserMap[1],\n fullscreenElement_: browserMap[2],\n fullscreenEnabled_: browserMap[3],\n fullscreenchange_: browserMap[4],\n fullscreenerror_: browserMap[5]\n } as FullscreenAPIMap;\n }\n }\n\n return undefined;\n})();\n"],"mappings":"AASA,OAAO,MAAMA,aAA2C,GAAG,CAAC,MAAM;EAChE,IAAI,CAACC,QAAQ,EAAE;IACb;EACF;;EAEA;EACA;EACA,MAAMC,MAAkB,GAAG;EACzB;EACA,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,CAAC;EACxH;EACA,CACE,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,CACxB;EACD;EACA,CACE,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,CACxB;EACD;EACA,CAAC,sBAAsB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,oBAAoB,CAAC;EAC5I;EACA,CAAC,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,CACrI;EAED,KAAK,MAAMC,UAAU,IAAID,MAAM,EAAE;IAC/B;IACA,IAAIC,UAAU,CAAC,CAAC,CAAC,IAAIF,QAAQ,EAAE;MAC7B,OAAO;QACLG,kBAAkB,EAAED,UAAU,CAAC,CAAC,CAAC;QACjCE,eAAe,EAAEF,UAAU,CAAC,CAAC,CAAC;QAC9BG,kBAAkB,EAAEH,UAAU,CAAC,CAAC,CAAC;QACjCI,kBAAkB,EAAEJ,UAAU,CAAC,CAAC,CAAC;QACjCK,iBAAiB,EAAEL,UAAU,CAAC,CAAC,CAAC;QAChCM,gBAAgB,EAAEN,UAAU,CAAC,CAAC;MAChC,CAAC;IACH;EACF;EAEA,OAAOO,SAAS;AAClB,CAAC,GAAG"}
@@ -3,13 +3,30 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
3
3
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
4
  import { PresentationMode } from 'react-native-theoplayer';
5
5
  import { DefaultPresentationModeChangeEvent } from '../event/PlayerEvents';
6
- import { browserDetection } from '../../../web/platform/BrowserDetection';
6
+ import { fullscreenAPI } from './FullscreenAPI';
7
+ import { noOp } from '../../utils/CommonUtils';
7
8
  export class WebPresentationModeManager {
8
9
  constructor(player, eventForwarder) {
9
10
  _defineProperty(this, "_player", void 0);
10
11
  _defineProperty(this, "_presentationMode", PresentationMode.inline);
11
12
  _defineProperty(this, "_element", undefined);
12
13
  _defineProperty(this, "_eventForwarder", void 0);
14
+ _defineProperty(this, "updatePresentationMode", () => {
15
+ // detect new presentation mode
16
+ let newPresentationMode = PresentationMode.inline;
17
+ if (fullscreenAPI !== undefined && document[fullscreenAPI.fullscreenElement_] !== null) {
18
+ newPresentationMode = PresentationMode.fullscreen;
19
+ } else if (document.pictureInPictureElement !== null) {
20
+ newPresentationMode = PresentationMode.pip;
21
+ }
22
+
23
+ // when changed, notify by dispatching presentationModeChange event
24
+ const previousPresentationMode = this._presentationMode;
25
+ if (newPresentationMode !== previousPresentationMode) {
26
+ this._presentationMode = newPresentationMode;
27
+ this._eventForwarder.dispatchEvent(new DefaultPresentationModeChangeEvent(this._presentationMode, previousPresentationMode));
28
+ }
29
+ });
13
30
  this._player = player;
14
31
  this._eventForwarder = eventForwarder;
15
32
  }
@@ -21,36 +38,40 @@ export class WebPresentationModeManager {
21
38
  return;
22
39
  }
23
40
  this.prepareForPresentationModeChanges();
24
-
25
- // on iOS Safari requestFullscreen isn't supported (https://caniuse.com/?search=requestFullscreen), where we need to use webkit methods on the video element
26
- if ( /*browserDetection.IS_IOS_ && */browserDetection.IS_SAFARI_) {
27
- if (presentationMode === PresentationMode.fullscreen) {
28
- var _this$_element, _this$_element$webkit;
29
- (_this$_element = this._element) === null || _this$_element === void 0 ? void 0 : (_this$_element$webkit = _this$_element.webkitEnterFullscreen) === null || _this$_element$webkit === void 0 ? void 0 : _this$_element$webkit.call(_this$_element);
30
- } else if (presentationMode === PresentationMode.pip) {
31
- var _this$_element2, _this$_element2$webki;
32
- (_this$_element2 = this._element) === null || _this$_element2 === void 0 ? void 0 : (_this$_element2$webki = _this$_element2.webkitSetPresentationMode) === null || _this$_element2$webki === void 0 ? void 0 : _this$_element2$webki.call(_this$_element2, PresentationMode.pip);
33
- } else {
34
- var _this$_element3, _this$_element3$webki;
35
- (_this$_element3 = this._element) === null || _this$_element3 === void 0 ? void 0 : (_this$_element3$webki = _this$_element3.webkitSetPresentationMode) === null || _this$_element3$webki === void 0 ? void 0 : _this$_element3$webki.call(_this$_element3, PresentationMode.inline);
36
- }
37
- } else {
38
- // other web-platformsyarn
39
-
41
+ if (fullscreenAPI !== undefined) {
42
+ // All other browsers
40
43
  if (presentationMode === PresentationMode.fullscreen) {
41
44
  const appElement = document.getElementById('app');
42
- void (appElement === null || appElement === void 0 ? void 0 : appElement.requestFullscreen());
45
+ const promise = appElement[fullscreenAPI.requestFullscreen_]();
46
+ if (promise && promise.then) {
47
+ promise.then(noOp, noOp);
48
+ }
43
49
  } else if (presentationMode === PresentationMode.pip) {
44
- var _this$_element4, _this$_element4$reque;
45
- void ((_this$_element4 = this._element) === null || _this$_element4 === void 0 ? void 0 : (_this$_element4$reque = _this$_element4.requestPictureInPicture) === null || _this$_element4$reque === void 0 ? void 0 : _this$_element4$reque.call(_this$_element4));
50
+ var _this$_element, _this$_element$reques;
51
+ void ((_this$_element = this._element) === null || _this$_element === void 0 ? void 0 : (_this$_element$reques = _this$_element.requestPictureInPicture) === null || _this$_element$reques === void 0 ? void 0 : _this$_element$reques.call(_this$_element));
46
52
  } else {
47
53
  if (this._presentationMode === PresentationMode.fullscreen) {
48
- void document.exitFullscreen();
54
+ const promise = document[fullscreenAPI.exitFullscreen_]();
55
+ if (promise && promise.then) {
56
+ promise.then(noOp, noOp);
57
+ }
49
58
  }
50
59
  if (this._presentationMode === PresentationMode.pip) {
51
60
  void document.exitPictureInPicture();
52
61
  }
53
62
  }
63
+ } else {
64
+ // iOS Safari doesn't properly support fullscreen, use native fullscreen instead
65
+ if (presentationMode === PresentationMode.fullscreen) {
66
+ var _this$_element2, _this$_element2$webki;
67
+ (_this$_element2 = this._element) === null || _this$_element2 === void 0 ? void 0 : (_this$_element2$webki = _this$_element2.webkitEnterFullscreen) === null || _this$_element2$webki === void 0 ? void 0 : _this$_element2$webki.call(_this$_element2);
68
+ } else if (presentationMode === PresentationMode.pip) {
69
+ var _this$_element3, _this$_element3$webki;
70
+ (_this$_element3 = this._element) === null || _this$_element3 === void 0 ? void 0 : (_this$_element3$webki = _this$_element3.webkitSetPresentationMode) === null || _this$_element3$webki === void 0 ? void 0 : _this$_element3$webki.call(_this$_element3, PresentationMode.pip);
71
+ } else {
72
+ var _this$_element4, _this$_element4$webki;
73
+ (_this$_element4 = this._element) === null || _this$_element4 === void 0 ? void 0 : (_this$_element4$webki = _this$_element4.webkitSetPresentationMode) === null || _this$_element4$webki === void 0 ? void 0 : _this$_element4$webki.call(_this$_element4, PresentationMode.inline);
74
+ }
54
75
  }
55
76
  }
56
77
  prepareForPresentationModeChanges() {
@@ -70,24 +91,9 @@ export class WebPresentationModeManager {
70
91
  };
71
92
  }
72
93
  // listen for fullscreen updates on document
73
- document.onfullscreenchange = () => {
74
- this.updatePresentationMode();
75
- };
76
- }
77
- updatePresentationMode() {
78
- // detect new presentation mode
79
- let newPresentationMode = PresentationMode.inline;
80
- if (document.fullscreenElement !== null) {
81
- newPresentationMode = PresentationMode.fullscreen;
82
- } else if (document.pictureInPictureElement !== null) {
83
- newPresentationMode = PresentationMode.pip;
84
- }
85
-
86
- // when changed, notify by dispatching presentationModeChange event
87
- const previousPresentationMode = this._presentationMode;
88
- if (newPresentationMode !== previousPresentationMode) {
89
- this._presentationMode = newPresentationMode;
90
- this._eventForwarder.dispatchEvent(new DefaultPresentationModeChangeEvent(this._presentationMode, previousPresentationMode));
94
+ if (fullscreenAPI !== undefined) {
95
+ document.addEventListener(fullscreenAPI.fullscreenchange_, this.updatePresentationMode);
96
+ document.addEventListener(fullscreenAPI.fullscreenerror_, this.updatePresentationMode);
91
97
  }
92
98
  }
93
99
  }
@@ -1 +1 @@
1
- {"version":3,"names":["PresentationMode","DefaultPresentationModeChangeEvent","browserDetection","WebPresentationModeManager","constructor","player","eventForwarder","_defineProperty","inline","undefined","_player","_eventForwarder","presentationMode","_presentationMode","prepareForPresentationModeChanges","IS_SAFARI_","fullscreen","_this$_element","_this$_element$webkit","_element","webkitEnterFullscreen","call","pip","_this$_element2","_this$_element2$webki","webkitSetPresentationMode","_this$_element3","_this$_element3$webki","appElement","document","getElementById","requestFullscreen","_this$_element4","_this$_element4$reque","requestPictureInPicture","exitFullscreen","exitPictureInPicture","elements","element","children","Array","from","tagName","attributes","getNamedItem","onenterpictureinpicture","updatePresentationMode","onleavepictureinpicture","onfullscreenchange","newPresentationMode","fullscreenElement","pictureInPictureElement","previousPresentationMode","dispatchEvent"],"sources":["WebPresentationModeManager.ts"],"sourcesContent":["import type { PlayerEventMap } from 'react-native-theoplayer';\nimport { PresentationMode } from 'react-native-theoplayer';\nimport type * as THEOplayerWeb from 'theoplayer';\nimport { DefaultPresentationModeChangeEvent } from '../event/PlayerEvents';\nimport { browserDetection } from '../../../web/platform/BrowserDetection';\nimport type { DefaultEventDispatcher } from '../event/DefaultEventDispatcher';\n\nexport class WebPresentationModeManager {\n private readonly _player: THEOplayerWeb.ChromelessPlayer;\n private _presentationMode: PresentationMode = PresentationMode.inline;\n private _element: HTMLVideoElement | undefined = undefined;\n private _eventForwarder: DefaultEventDispatcher<PlayerEventMap>;\n\n constructor(player: THEOplayerWeb.ChromelessPlayer, eventForwarder: DefaultEventDispatcher<PlayerEventMap>) {\n this._player = player;\n this._eventForwarder = eventForwarder;\n }\n\n get presentationMode(): PresentationMode {\n return this._presentationMode;\n }\n\n set presentationMode(presentationMode: PresentationMode) {\n if (presentationMode === this._presentationMode) {\n return;\n }\n\n this.prepareForPresentationModeChanges();\n\n // on iOS Safari requestFullscreen isn't supported (https://caniuse.com/?search=requestFullscreen), where we need to use webkit methods on the video element\n if (/*browserDetection.IS_IOS_ && */ browserDetection.IS_SAFARI_) {\n if (presentationMode === PresentationMode.fullscreen) {\n this._element?.webkitEnterFullscreen?.();\n } else if (presentationMode === PresentationMode.pip) {\n this._element?.webkitSetPresentationMode?.(PresentationMode.pip);\n } else {\n this._element?.webkitSetPresentationMode?.(PresentationMode.inline);\n }\n } else {\n // other web-platformsyarn\n\n if (presentationMode === PresentationMode.fullscreen) {\n const appElement = document.getElementById('app');\n void appElement?.requestFullscreen();\n } else if (presentationMode === PresentationMode.pip) {\n void this._element?.requestPictureInPicture?.();\n } else {\n if (this._presentationMode === PresentationMode.fullscreen) {\n void document.exitFullscreen();\n }\n if (this._presentationMode === PresentationMode.pip) {\n void document.exitPictureInPicture();\n }\n }\n }\n }\n\n private prepareForPresentationModeChanges() {\n const elements = this._player.element.children;\n for (const element of Array.from(elements)) {\n if (element.tagName === 'VIDEO' && element.attributes.getNamedItem('src') !== null) {\n this._element = element as HTMLVideoElement;\n }\n }\n // listen for pip updates on element\n if (this._element !== undefined) {\n this._element.onenterpictureinpicture = () => {\n this.updatePresentationMode();\n };\n this._element.onleavepictureinpicture = () => {\n this.updatePresentationMode();\n };\n }\n // listen for fullscreen updates on document\n document.onfullscreenchange = () => {\n this.updatePresentationMode();\n };\n }\n\n private updatePresentationMode() {\n // detect new presentation mode\n let newPresentationMode: PresentationMode = PresentationMode.inline;\n if (document.fullscreenElement !== null) {\n newPresentationMode = PresentationMode.fullscreen;\n } else if (document.pictureInPictureElement !== null) {\n newPresentationMode = PresentationMode.pip;\n }\n\n // when changed, notify by dispatching presentationModeChange event\n const previousPresentationMode = this._presentationMode;\n if (newPresentationMode !== previousPresentationMode) {\n this._presentationMode = newPresentationMode;\n this._eventForwarder.dispatchEvent(new DefaultPresentationModeChangeEvent(this._presentationMode, previousPresentationMode));\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["PresentationMode","DefaultPresentationModeChangeEvent","fullscreenAPI","noOp","WebPresentationModeManager","constructor","player","eventForwarder","_defineProperty","inline","undefined","newPresentationMode","document","fullscreenElement_","fullscreen","pictureInPictureElement","pip","previousPresentationMode","_presentationMode","_eventForwarder","dispatchEvent","_player","presentationMode","prepareForPresentationModeChanges","appElement","getElementById","promise","requestFullscreen_","then","_this$_element","_this$_element$reques","_element","requestPictureInPicture","call","exitFullscreen_","exitPictureInPicture","_this$_element2","_this$_element2$webki","webkitEnterFullscreen","_this$_element3","_this$_element3$webki","webkitSetPresentationMode","_this$_element4","_this$_element4$webki","elements","element","children","Array","from","tagName","attributes","getNamedItem","onenterpictureinpicture","updatePresentationMode","onleavepictureinpicture","addEventListener","fullscreenchange_","fullscreenerror_"],"sources":["WebPresentationModeManager.ts"],"sourcesContent":["import type { PlayerEventMap } from 'react-native-theoplayer';\nimport { PresentationMode } from 'react-native-theoplayer';\nimport type * as THEOplayerWeb from 'theoplayer';\nimport { DefaultPresentationModeChangeEvent } from '../event/PlayerEvents';\nimport type { DefaultEventDispatcher } from '../event/DefaultEventDispatcher';\nimport { fullscreenAPI } from './FullscreenAPI';\nimport { noOp } from '../../utils/CommonUtils';\n\nexport class WebPresentationModeManager {\n private readonly _player: THEOplayerWeb.ChromelessPlayer;\n private _presentationMode: PresentationMode = PresentationMode.inline;\n private _element: HTMLVideoElement | undefined = undefined;\n private _eventForwarder: DefaultEventDispatcher<PlayerEventMap>;\n\n constructor(player: THEOplayerWeb.ChromelessPlayer, eventForwarder: DefaultEventDispatcher<PlayerEventMap>) {\n this._player = player;\n this._eventForwarder = eventForwarder;\n }\n\n get presentationMode(): PresentationMode {\n return this._presentationMode;\n }\n\n set presentationMode(presentationMode: PresentationMode) {\n if (presentationMode === this._presentationMode) {\n return;\n }\n\n this.prepareForPresentationModeChanges();\n\n if (fullscreenAPI !== undefined) {\n // All other browsers\n if (presentationMode === PresentationMode.fullscreen) {\n const appElement = document.getElementById('app')!;\n const promise = appElement[fullscreenAPI.requestFullscreen_]();\n if (promise && promise.then) {\n promise.then(noOp, noOp);\n }\n } else if (presentationMode === PresentationMode.pip) {\n void this._element?.requestPictureInPicture?.();\n } else {\n if (this._presentationMode === PresentationMode.fullscreen) {\n const promise = document[fullscreenAPI.exitFullscreen_]();\n if (promise && promise.then) {\n promise.then(noOp, noOp);\n }\n }\n if (this._presentationMode === PresentationMode.pip) {\n void document.exitPictureInPicture();\n }\n }\n } else {\n // iOS Safari doesn't properly support fullscreen, use native fullscreen instead\n if (presentationMode === PresentationMode.fullscreen) {\n this._element?.webkitEnterFullscreen?.();\n } else if (presentationMode === PresentationMode.pip) {\n this._element?.webkitSetPresentationMode?.(PresentationMode.pip);\n } else {\n this._element?.webkitSetPresentationMode?.(PresentationMode.inline);\n }\n }\n }\n\n private prepareForPresentationModeChanges() {\n const elements = this._player.element.children;\n for (const element of Array.from(elements)) {\n if (element.tagName === 'VIDEO' && element.attributes.getNamedItem('src') !== null) {\n this._element = element as HTMLVideoElement;\n }\n }\n // listen for pip updates on element\n if (this._element !== undefined) {\n this._element.onenterpictureinpicture = () => {\n this.updatePresentationMode();\n };\n this._element.onleavepictureinpicture = () => {\n this.updatePresentationMode();\n };\n }\n // listen for fullscreen updates on document\n if (fullscreenAPI !== undefined) {\n document.addEventListener(fullscreenAPI.fullscreenchange_, this.updatePresentationMode);\n document.addEventListener(fullscreenAPI.fullscreenerror_, this.updatePresentationMode);\n }\n }\n\n private updatePresentationMode = () => {\n // detect new presentation mode\n let newPresentationMode: PresentationMode = PresentationMode.inline;\n if (fullscreenAPI !== undefined && document[fullscreenAPI.fullscreenElement_] !== null) {\n newPresentationMode = PresentationMode.fullscreen;\n } else if (document.pictureInPictureElement !== null) {\n newPresentationMode = PresentationMode.pip;\n }\n\n // when changed, notify by dispatching presentationModeChange event\n const previousPresentationMode = this._presentationMode;\n if (newPresentationMode !== previousPresentationMode) {\n this._presentationMode = newPresentationMode;\n this._eventForwarder.dispatchEvent(new DefaultPresentationModeChangeEvent(this._presentationMode, previousPresentationMode));\n }\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export function noOp() {
2
+ return;
3
+ }
4
+ //# sourceMappingURL=CommonUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["noOp"],"sources":["CommonUtils.ts"],"sourcesContent":["export function noOp(): void {\n return;\n}\n"],"mappings":"AAAA,OAAO,SAASA,IAAIA,CAAA,EAAS;EAC3B;AACF"}
@@ -1,3 +1,4 @@
1
- // @ts-ignore
2
- export * from 'url-polyfill';
1
+ import 'url-polyfill';
2
+ const URL = global.URL;
3
+ export { URL };
3
4
  //# sourceMappingURL=Urlpolyfill.web.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["Urlpolyfill.web.ts"],"sourcesContent":["// @ts-ignore\nexport * from 'url-polyfill';\n"],"mappings":"AAAA;AACA,cAAc,cAAc"}
1
+ {"version":3,"names":["URL","global"],"sources":["Urlpolyfill.web.ts"],"sourcesContent":["import 'url-polyfill';\nconst URL = global.URL;\nexport { URL };\n"],"mappings":"AAAA,OAAO,cAAc;AACrB,MAAMA,GAAG,GAAGC,MAAM,CAACD,GAAG;AACtB,SAASA,GAAG"}
@@ -24,6 +24,8 @@ export interface DashPlaybackConfiguration {
24
24
  * Whether to seamlessly switch between DASH periods.
25
25
  *
26
26
  * @remarks
27
+ * <br/> - Available on Web only.
28
+ *
27
29
  * The player supports two strategies for handling a switch between two periods in an MPEG-DASH stream:
28
30
  * <br/> - <strong>Seamless</strong>: Once the player is done buffering the current period, it immediately starts buffering the next period.
29
31
  * This requires that the current period and the next period have compatible codecs and content protection, or that the platform
@@ -41,4 +43,54 @@ export interface DashPlaybackConfiguration {
41
43
  * @defaultValue `'auto'`
42
44
  */
43
45
  useSeamlessPeriodSwitch?: SeamlessPeriodSwitchStrategy;
46
+ /**
47
+ * (Experimental) Whether the timescales of the media data need to be shifted,
48
+ * in order to work around platform-specific issues on certain smart TV platforms.
49
+ *
50
+ * @remarks
51
+ * <br/> - Available since v4.1.0.
52
+ * <br/> - Available on Web only.
53
+ * <br/> - On certain smart TV platforms (such as Tizen 2), playback issues may arise when
54
+ * the timescale of the media data changes across periods or discontinuities.
55
+ * In that case, the player may need to shift all the timescales first,
56
+ * however this strategy may not work for all streams.
57
+ * <br/> - When not specified, the player will decide whether or not to shift timescales
58
+ * based on the platform.
59
+ * <br/> - This is an experimental option. It should only be used after consulting with
60
+ * THEOplayer support or engineering.
61
+ */
62
+ needsTimescaleShifting?: boolean | null;
63
+ /**
64
+ * (Experimental) The desired timescale to which the media data should be shifted.
65
+ *
66
+ * @remarks
67
+ * <br/> - Available since v4.11.0.
68
+ * <br/> - Available on Web only.
69
+ * <br/> - When specified, if the player decides to shift the timescale (see {@link DashPlaybackConfiguration.needsTimescaleShifting}), the timescale will be set to the
70
+ * given desired timescale.
71
+ * <br/> - When not specified, if the player decides to shift timescale, the player will decide the timescale to which it should shift.
72
+ * <br/> - This is an experimental option. It should only be used after consulting with
73
+ * THEOplayer support or engineering.
74
+ */
75
+ desiredTimescale?: number;
76
+ /**
77
+ * Whether the player should try to force the seek on period switching to realign video and audio.
78
+ *
79
+ * @internal
80
+ *
81
+ * @remarks
82
+ * <br/> - Available on Web only.
83
+ */
84
+ forceSeekToSynchronize?: boolean;
85
+ /**
86
+ * (Experimental) Force the player to ignore the availability window of individual segments in the MPD,
87
+ * and instead consider every listed segment to be immediately available.
88
+ *
89
+ * @remarks
90
+ * <br/> - Available since v5.2.0.
91
+ * <br/> - Available on Web and Android.
92
+ * <br/> - This only applies to livestreams (with `<MPD type="dynamic">`).
93
+ * <br/> - This only applies to streams that use `<SegmentTimeline>`.
94
+ */
95
+ ignoreAvailabilityWindow?: boolean;
44
96
  }
@@ -95,6 +95,6 @@ export declare function filterThumbnailTracks(textTracks: TextTrack[] | undefine
95
95
  */
96
96
  export declare function isThumbnailTrack(textTrack: TextTrack | undefined): boolean;
97
97
  export declare function hasTextTrackCue(textTrack: TextTrack, cue: TextTrackCue): boolean;
98
- export declare function removeTextTrackCue(textTrack: TextTrack, cue: TextTrackCue): void;
99
- export declare function addTextTrackCue(textTrack: TextTrack, cue: TextTrackCue): void;
98
+ export declare function removeTextTrackCue(textTrack?: TextTrack, cue?: TextTrackCue): void;
99
+ export declare function addTextTrackCue(textTrack?: TextTrack, cue?: TextTrackCue): void;
100
100
  export declare function findTextTrackByUid(textTracks: TextTrack[], uid: number): TextTrack | undefined;
@@ -12,6 +12,7 @@ export declare class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEven
12
12
  private readonly _textTrackStyleAdapter;
13
13
  constructor(view: THEOplayerView, initialState?: NativePlayerState);
14
14
  private onSourceChange;
15
+ private hasValidSource;
15
16
  private onPause;
16
17
  private onPlaying;
17
18
  private onPresentationModeChange;
@@ -22,11 +23,13 @@ export declare class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEven
22
23
  private onSeeking;
23
24
  private onSeeked;
24
25
  private onProgress;
26
+ private onTextTrack;
25
27
  private onTextTrackList;
26
28
  private onMediaTrack;
27
29
  private onMediaTrackList;
28
30
  get abr(): ABRConfiguration | undefined;
29
31
  get ads(): AdsAPI;
32
+ private applyAutoplay;
30
33
  set autoplay(autoplay: boolean);
31
34
  get autoplay(): boolean;
32
35
  set preload(type: PreloadType);
@@ -0,0 +1,9 @@
1
+ export interface FullscreenAPIMap {
2
+ requestFullscreen_: 'requestFullscreen';
3
+ exitFullscreen_: 'exitFullscreen';
4
+ fullscreenElement_: 'fullscreenElement';
5
+ fullscreenEnabled_: 'fullscreenEnabled';
6
+ fullscreenchange_: 'fullscreenchange';
7
+ fullscreenerror_: 'fullscreenerror';
8
+ }
9
+ export declare const fullscreenAPI: FullscreenAPIMap | undefined;
@@ -0,0 +1 @@
1
+ export declare function noOp(): void;
@@ -1 +1,8 @@
1
- export * from 'url-polyfill';
1
+ import 'url-polyfill';
2
+ declare const URL: {
3
+ new (url: string | URL, base?: string | URL | undefined): URL;
4
+ prototype: URL;
5
+ createObjectURL(obj: Blob | MediaSource): string;
6
+ revokeObjectURL(url: string): void;
7
+ };
8
+ export { URL };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-theoplayer",
3
- "version": "2.6.0",
3
+ "version": "2.8.0",
4
4
  "description": "A THEOplayer video component for react-native.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -25,6 +25,8 @@ export interface DashPlaybackConfiguration {
25
25
  * Whether to seamlessly switch between DASH periods.
26
26
  *
27
27
  * @remarks
28
+ * <br/> - Available on Web only.
29
+ *
28
30
  * The player supports two strategies for handling a switch between two periods in an MPEG-DASH stream:
29
31
  * <br/> - <strong>Seamless</strong>: Once the player is done buffering the current period, it immediately starts buffering the next period.
30
32
  * This requires that the current period and the next period have compatible codecs and content protection, or that the platform
@@ -42,4 +44,58 @@ export interface DashPlaybackConfiguration {
42
44
  * @defaultValue `'auto'`
43
45
  */
44
46
  useSeamlessPeriodSwitch?: SeamlessPeriodSwitchStrategy;
47
+
48
+ /**
49
+ * (Experimental) Whether the timescales of the media data need to be shifted,
50
+ * in order to work around platform-specific issues on certain smart TV platforms.
51
+ *
52
+ * @remarks
53
+ * <br/> - Available since v4.1.0.
54
+ * <br/> - Available on Web only.
55
+ * <br/> - On certain smart TV platforms (such as Tizen 2), playback issues may arise when
56
+ * the timescale of the media data changes across periods or discontinuities.
57
+ * In that case, the player may need to shift all the timescales first,
58
+ * however this strategy may not work for all streams.
59
+ * <br/> - When not specified, the player will decide whether or not to shift timescales
60
+ * based on the platform.
61
+ * <br/> - This is an experimental option. It should only be used after consulting with
62
+ * THEOplayer support or engineering.
63
+ */
64
+ needsTimescaleShifting?: boolean | null;
65
+
66
+ /**
67
+ * (Experimental) The desired timescale to which the media data should be shifted.
68
+ *
69
+ * @remarks
70
+ * <br/> - Available since v4.11.0.
71
+ * <br/> - Available on Web only.
72
+ * <br/> - When specified, if the player decides to shift the timescale (see {@link DashPlaybackConfiguration.needsTimescaleShifting}), the timescale will be set to the
73
+ * given desired timescale.
74
+ * <br/> - When not specified, if the player decides to shift timescale, the player will decide the timescale to which it should shift.
75
+ * <br/> - This is an experimental option. It should only be used after consulting with
76
+ * THEOplayer support or engineering.
77
+ */
78
+ desiredTimescale?: number;
79
+
80
+ /**
81
+ * Whether the player should try to force the seek on period switching to realign video and audio.
82
+ *
83
+ * @internal
84
+ *
85
+ * @remarks
86
+ * <br/> - Available on Web only.
87
+ */
88
+ forceSeekToSynchronize?: boolean;
89
+
90
+ /**
91
+ * (Experimental) Force the player to ignore the availability window of individual segments in the MPD,
92
+ * and instead consider every listed segment to be immediately available.
93
+ *
94
+ * @remarks
95
+ * <br/> - Available since v5.2.0.
96
+ * <br/> - Available on Web and Android.
97
+ * <br/> - This only applies to livestreams (with `<MPD type="dynamic">`).
98
+ * <br/> - This only applies to streams that use `<SegmentTimeline>`.
99
+ */
100
+ ignoreAvailabilityWindow?: boolean;
45
101
  }
@@ -121,13 +121,13 @@ export function hasTextTrackCue(textTrack: TextTrack, cue: TextTrackCue): boolea
121
121
  return !!(textTrack.cues && cue && textTrack.cues.find((c) => cue.uid === c.uid));
122
122
  }
123
123
 
124
- export function removeTextTrackCue(textTrack: TextTrack, cue: TextTrackCue) {
124
+ export function removeTextTrackCue(textTrack?: TextTrack, cue?: TextTrackCue) {
125
125
  if (textTrack && textTrack.cues && cue && !hasTextTrackCue(textTrack, cue)) {
126
126
  textTrack.cues = textTrack.cues.filter((c) => c.uid !== cue.uid);
127
127
  }
128
128
  }
129
129
 
130
- export function addTextTrackCue(textTrack: TextTrack, cue: TextTrackCue) {
130
+ export function addTextTrackCue(textTrack?: TextTrack, cue?: TextTrackCue) {
131
131
  if (textTrack && textTrack.cues && cue && !hasTextTrackCue(textTrack, cue)) {
132
132
  textTrack.cues.push(cue);
133
133
  }
@@ -16,21 +16,26 @@ import type {
16
16
  RateChangeEvent,
17
17
  SourceDescription,
18
18
  TextTrack,
19
+ TextTrackEvent,
19
20
  TextTrackListEvent,
20
21
  THEOplayer,
21
22
  THEOplayerView,
22
23
  TimeUpdateEvent,
23
24
  } from 'react-native-theoplayer';
24
25
  import {
26
+ addTextTrackCue,
25
27
  addTrack,
26
28
  AspectRatio,
27
29
  findMediaTrackByUid,
30
+ findTextTrackByUid,
28
31
  MediaTrackEventType,
29
32
  MediaTrackType,
30
33
  PlayerEventType,
31
34
  PreloadType,
32
35
  PresentationMode,
36
+ removeTextTrackCue,
33
37
  removeTrack,
38
+ TextTrackEventType,
34
39
  TextTrackMode,
35
40
  TextTrackStyle,
36
41
  TrackListEventType,
@@ -97,19 +102,20 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
97
102
  this.addEventListener(PlayerEventType.SEEKED, this.onSeeked);
98
103
  this.addEventListener(PlayerEventType.PROGRESS, this.onProgress);
99
104
  this.addEventListener(PlayerEventType.TEXT_TRACK_LIST, this.onTextTrackList);
105
+ this.addEventListener(PlayerEventType.TEXT_TRACK, this.onTextTrack);
100
106
  this.addEventListener(PlayerEventType.MEDIA_TRACK, this.onMediaTrack);
101
107
  this.addEventListener(PlayerEventType.MEDIA_TRACK_LIST, this.onMediaTrackList);
102
108
  this.addEventListener(PlayerEventType.PRESENTATIONMODE_CHANGE, this.onPresentationModeChange);
103
109
  }
104
110
 
105
111
  private onSourceChange = () => {
106
- if (this._state.autoplay) {
107
- this.play();
108
- } else {
109
- this.pause();
110
- }
112
+ this.applyAutoplay();
111
113
  };
112
114
 
115
+ private hasValidSource(): boolean {
116
+ return this._state.source !== undefined;
117
+ }
118
+
113
119
  private onPause = () => {
114
120
  this._state.paused = true;
115
121
  };
@@ -157,6 +163,19 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
157
163
  this._state.buffered = event.buffered?.sort((a, b) => a.end - b.end);
158
164
  };
159
165
 
166
+ private onTextTrack = (event: TextTrackEvent) => {
167
+ const { subType, cue, trackUid } = event;
168
+ const track = findTextTrackByUid(this._state.textTracks, trackUid);
169
+ switch (subType) {
170
+ case TextTrackEventType.ADD_CUE:
171
+ addTextTrackCue(track, cue);
172
+ break;
173
+ case TextTrackEventType.REMOVE_CUE:
174
+ removeTextTrackCue(track, cue);
175
+ break;
176
+ }
177
+ };
178
+
160
179
  private onTextTrackList = (event: TextTrackListEvent) => {
161
180
  const { subType, track } = event;
162
181
  switch (subType) {
@@ -225,9 +244,23 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
225
244
  return this._adsAdapter;
226
245
  }
227
246
 
247
+ private applyAutoplay() {
248
+ if (!this.hasValidSource()) {
249
+ return;
250
+ }
251
+ if (this._state.autoplay) {
252
+ this.play();
253
+ } else {
254
+ this.pause();
255
+ }
256
+ }
257
+
228
258
  set autoplay(autoplay: boolean) {
229
259
  this._state.autoplay = autoplay;
230
- NativeModules.PlayerModule.setPaused(this._view.nativeHandle, !autoplay);
260
+
261
+ // Apply autoplay in case a source was already set.
262
+ // If autoplay is changed before setting a source, `onSourceChange` applies autoplay.
263
+ this.applyAutoplay();
231
264
  }
232
265
 
233
266
  get autoplay(): boolean {
@@ -265,6 +298,10 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
265
298
  }
266
299
 
267
300
  set currentTime(currentTime: number) {
301
+ if (!this.hasValidSource()) {
302
+ return;
303
+ }
304
+
268
305
  if (isNaN(currentTime)) {
269
306
  return;
270
307
  }
@@ -345,6 +382,9 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
345
382
  }
346
383
 
347
384
  set selectedAudioTrack(trackUid: number | undefined) {
385
+ if (!this.hasValidSource()) {
386
+ return;
387
+ }
348
388
  this._state.selectedAudioTrack = trackUid;
349
389
  NativeModules.PlayerModule.setSelectedAudioTrack(this._view.nativeHandle, trackUid || -1);
350
390
  }
@@ -358,6 +398,9 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
358
398
  }
359
399
 
360
400
  set selectedVideoTrack(trackUid: number | undefined) {
401
+ if (!this.hasValidSource()) {
402
+ return;
403
+ }
361
404
  this._state.selectedVideoTrack = trackUid;
362
405
  this._state.targetVideoQuality = undefined;
363
406
  NativeModules.PlayerModule.setSelectedVideoTrack(this._view.nativeHandle, trackUid || -1);
@@ -372,6 +415,9 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
372
415
  }
373
416
 
374
417
  set selectedTextTrack(trackUid: number | undefined) {
418
+ if (!this.hasValidSource()) {
419
+ return;
420
+ }
375
421
  this._state.selectedTextTrack = trackUid;
376
422
  this.textTracks.forEach((track) => {
377
423
  if (track.uid === trackUid) {
@@ -417,6 +463,9 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
417
463
  }
418
464
 
419
465
  set targetVideoQuality(target: number | number[] | undefined) {
466
+ if (!this.hasValidSource()) {
467
+ return;
468
+ }
420
469
  // Always pass an array for targetVideoQuality.
421
470
  this._state.targetVideoQuality = !target ? [] : Array.isArray(target) ? target : [target];
422
471
 
@@ -447,13 +496,17 @@ export class THEOplayerAdapter extends DefaultEventDispatcher<PlayerEventMap> im
447
496
  }
448
497
 
449
498
  pause(): void {
450
- this._state.paused = true;
451
- NativeModules.PlayerModule.setPaused(this._view.nativeHandle, true);
499
+ if (this.hasValidSource()) {
500
+ this._state.paused = true;
501
+ NativeModules.PlayerModule.setPaused(this._view.nativeHandle, true);
502
+ }
452
503
  }
453
504
 
454
505
  play(): void {
455
- this._state.paused = false;
456
- NativeModules.PlayerModule.setPaused(this._view.nativeHandle, false);
506
+ if (this.hasValidSource()) {
507
+ this._state.paused = false;
508
+ NativeModules.PlayerModule.setPaused(this._view.nativeHandle, false);
509
+ }
457
510
  }
458
511
 
459
512
  get nativeHandle(): NativeHandleType {