bitmovin-player-react-native 0.44.1-alpha.0 → 1.0.0-alpha.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 (497) hide show
  1. package/.eslintignore +11 -0
  2. package/.eslintrc.js +7 -0
  3. package/.gitattributes +3 -0
  4. package/.prettierignore +11 -0
  5. package/.ruby-version +1 -0
  6. package/.swiftlint.yml +171 -0
  7. package/Brewfile +2 -0
  8. package/CHANGELOG.md +627 -0
  9. package/CONTRIBUTING.md +255 -0
  10. package/TODO.md +0 -0
  11. package/android/.editorconfig +8 -0
  12. package/android/build.gradle +78 -75
  13. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  14. package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  15. package/android/gradle.properties +1 -0
  16. package/android/gradlew +248 -0
  17. package/android/gradlew.bat +92 -0
  18. package/android/ktlint.gradle +31 -0
  19. package/android/src/main/java/com/bitmovin/player/reactnative/ActivityLifecycleListener.kt +51 -0
  20. package/android/src/main/java/com/bitmovin/player/reactnative/BitmovinCastManagerModule.kt +32 -55
  21. package/android/src/main/java/com/bitmovin/player/reactnative/BufferModule.kt +33 -45
  22. package/android/src/main/java/com/bitmovin/player/reactnative/CustomMessageHandlerModule.kt +84 -0
  23. package/android/src/main/java/com/bitmovin/player/reactnative/DebugModule.kt +6 -14
  24. package/android/src/main/java/com/bitmovin/player/reactnative/DecoderConfigModule.kt +89 -44
  25. package/android/src/main/java/com/bitmovin/player/reactnative/DrmModule.kt +80 -99
  26. package/android/src/main/java/com/bitmovin/player/reactnative/EventSubscription.kt +22 -0
  27. package/android/src/main/java/com/bitmovin/player/reactnative/FullscreenHandlerModule.kt +100 -0
  28. package/android/src/main/java/com/bitmovin/player/reactnative/MediaSessionPlaybackManager.kt +5 -5
  29. package/android/src/main/java/com/bitmovin/player/reactnative/NetworkModule.kt +98 -56
  30. package/android/src/main/java/com/bitmovin/player/reactnative/OfflineModule.kt +132 -186
  31. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerAnalyticsModule.kt +37 -36
  32. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +252 -528
  33. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerPackage.kt +11 -0
  34. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +558 -213
  35. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +99 -286
  36. package/android/src/main/java/com/bitmovin/player/reactnative/ResultWaiter.kt +58 -0
  37. package/android/src/main/java/com/bitmovin/player/reactnative/SourceModule.kt +77 -151
  38. package/android/src/main/java/com/bitmovin/player/reactnative/Types.kt +44 -0
  39. package/android/src/main/java/com/bitmovin/player/reactnative/UuidModule.kt +12 -15
  40. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +296 -456
  41. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ListExtension.kt +89 -0
  42. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/MapExtension.kt +95 -0
  43. package/android/src/main/java/com/bitmovin/player/reactnative/offline/OfflineContentManagerBridge.kt +20 -52
  44. package/android/src/main/java/com/bitmovin/player/reactnative/ui/CustomMessageHandlerBridge.kt +10 -20
  45. package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerBridge.kt +4 -9
  46. package/app.plugin.js +21 -0
  47. package/build/BitmovinPlayerReactNative.types.d.ts +18 -0
  48. package/build/BitmovinPlayerReactNative.types.d.ts.map +1 -0
  49. package/build/BitmovinPlayerReactNative.types.js +2 -0
  50. package/build/BitmovinPlayerReactNative.types.js.map +1 -0
  51. package/build/adaptationConfig.d.ts +18 -0
  52. package/build/adaptationConfig.d.ts.map +1 -0
  53. package/build/adaptationConfig.js +2 -0
  54. package/build/adaptationConfig.js.map +1 -0
  55. package/build/advertising.d.ts +175 -0
  56. package/build/advertising.d.ts.map +1 -0
  57. package/build/advertising.js +37 -0
  58. package/build/advertising.js.map +1 -0
  59. package/build/analytics/config.d.ts +194 -0
  60. package/build/analytics/config.d.ts.map +1 -0
  61. package/build/analytics/config.js +2 -0
  62. package/build/analytics/config.js.map +1 -0
  63. package/build/analytics/index.d.ts +3 -0
  64. package/build/analytics/index.d.ts.map +1 -0
  65. package/build/analytics/index.js +3 -0
  66. package/build/analytics/index.js.map +1 -0
  67. package/build/analytics/player.d.ts +24 -0
  68. package/build/analytics/player.d.ts.map +1 -0
  69. package/build/analytics/player.js +30 -0
  70. package/build/analytics/player.js.map +1 -0
  71. package/build/analytics/playerAnalyticsModule.d.ts +13 -0
  72. package/build/analytics/playerAnalyticsModule.d.ts.map +1 -0
  73. package/build/analytics/playerAnalyticsModule.js +3 -0
  74. package/build/analytics/playerAnalyticsModule.js.map +1 -0
  75. package/build/audioSession.d.ts +33 -0
  76. package/build/audioSession.d.ts.map +1 -0
  77. package/build/audioSession.js +21 -0
  78. package/build/audioSession.js.map +1 -0
  79. package/build/audioTrack.d.ts +39 -0
  80. package/build/audioTrack.d.ts.map +1 -0
  81. package/build/audioTrack.js +2 -0
  82. package/build/audioTrack.js.map +1 -0
  83. package/build/bitmovinCastManager.d.ts +58 -0
  84. package/build/bitmovinCastManager.d.ts.map +1 -0
  85. package/build/bitmovinCastManager.js +64 -0
  86. package/build/bitmovinCastManager.js.map +1 -0
  87. package/build/bufferApi.d.ts +85 -0
  88. package/build/bufferApi.d.ts.map +1 -0
  89. package/build/bufferApi.js +60 -0
  90. package/build/bufferApi.js.map +1 -0
  91. package/build/bufferConfig.d.ts +42 -0
  92. package/build/bufferConfig.d.ts.map +1 -0
  93. package/build/bufferConfig.js +2 -0
  94. package/build/bufferConfig.js.map +1 -0
  95. package/build/components/PlayerView/events.d.ts +310 -0
  96. package/build/components/PlayerView/events.d.ts.map +1 -0
  97. package/build/components/PlayerView/events.js +2 -0
  98. package/build/components/PlayerView/events.js.map +1 -0
  99. package/build/components/PlayerView/index.d.ts +10 -0
  100. package/build/components/PlayerView/index.d.ts.map +1 -0
  101. package/build/components/PlayerView/index.js +72 -0
  102. package/build/components/PlayerView/index.js.map +1 -0
  103. package/build/components/PlayerView/native.d.ts +30 -0
  104. package/build/components/PlayerView/native.d.ts.map +1 -0
  105. package/build/components/PlayerView/native.js +6 -0
  106. package/build/components/PlayerView/native.js.map +1 -0
  107. package/build/components/PlayerView/nativeEvents.d.ts +437 -0
  108. package/build/components/PlayerView/nativeEvents.d.ts.map +1 -0
  109. package/build/components/PlayerView/nativeEvents.js +2 -0
  110. package/build/components/PlayerView/nativeEvents.js.map +1 -0
  111. package/build/components/PlayerView/pictureInPictureConfig.d.ts +22 -0
  112. package/build/components/PlayerView/pictureInPictureConfig.d.ts.map +1 -0
  113. package/build/components/PlayerView/pictureInPictureConfig.js +2 -0
  114. package/build/components/PlayerView/pictureInPictureConfig.js.map +1 -0
  115. package/build/components/PlayerView/playerViewConfig.d.ts +111 -0
  116. package/build/components/PlayerView/playerViewConfig.d.ts.map +1 -0
  117. package/build/components/PlayerView/playerViewConfig.js +51 -0
  118. package/build/components/PlayerView/playerViewConfig.js.map +1 -0
  119. package/build/components/PlayerView/properties.d.ts +61 -0
  120. package/build/components/PlayerView/properties.d.ts.map +1 -0
  121. package/build/components/PlayerView/properties.js +2 -0
  122. package/build/components/PlayerView/properties.js.map +1 -0
  123. package/build/components/index.d.ts +5 -0
  124. package/build/components/index.d.ts.map +1 -0
  125. package/build/components/index.js +5 -0
  126. package/build/components/index.js.map +1 -0
  127. package/build/debug.d.ts +46 -0
  128. package/build/debug.d.ts.map +1 -0
  129. package/build/debug.js +52 -0
  130. package/build/debug.js.map +1 -0
  131. package/build/decoder/decoderConfig.d.ts +96 -0
  132. package/build/decoder/decoderConfig.d.ts.map +1 -0
  133. package/build/decoder/decoderConfig.js +6 -0
  134. package/build/decoder/decoderConfig.js.map +1 -0
  135. package/build/decoder/decoderConfigModule.d.ts +14 -0
  136. package/build/decoder/decoderConfigModule.d.ts.map +1 -0
  137. package/build/decoder/decoderConfigModule.js +31 -0
  138. package/build/decoder/decoderConfigModule.js.map +1 -0
  139. package/build/decoder/index.d.ts +26 -0
  140. package/build/decoder/index.d.ts.map +1 -0
  141. package/build/decoder/index.js +50 -0
  142. package/build/decoder/index.js.map +1 -0
  143. package/build/drm/drmModule.d.ts +55 -0
  144. package/build/drm/drmModule.d.ts.map +1 -0
  145. package/build/drm/drmModule.js +3 -0
  146. package/build/drm/drmModule.js.map +1 -0
  147. package/build/drm/fairplayConfig.d.ts +91 -0
  148. package/build/drm/fairplayConfig.d.ts.map +1 -0
  149. package/build/drm/fairplayConfig.js +2 -0
  150. package/build/drm/fairplayConfig.js.map +1 -0
  151. package/build/drm/index.d.ts +112 -0
  152. package/build/drm/index.d.ts.map +1 -0
  153. package/build/drm/index.js +191 -0
  154. package/build/drm/index.js.map +1 -0
  155. package/build/drm/widevineConfig.d.ts +58 -0
  156. package/build/drm/widevineConfig.d.ts.map +1 -0
  157. package/build/drm/widevineConfig.js +2 -0
  158. package/build/drm/widevineConfig.js.map +1 -0
  159. package/build/events.d.ts +692 -0
  160. package/build/events.d.ts.map +1 -0
  161. package/build/events.js +2 -0
  162. package/build/events.js.map +1 -0
  163. package/build/hooks/index.d.ts +2 -0
  164. package/build/hooks/index.d.ts.map +1 -0
  165. package/build/hooks/index.js +2 -0
  166. package/build/hooks/index.js.map +1 -0
  167. package/build/hooks/usePlayer.d.ts +8 -0
  168. package/build/hooks/usePlayer.d.ts.map +1 -0
  169. package/build/hooks/usePlayer.js +10 -0
  170. package/build/hooks/usePlayer.js.map +1 -0
  171. package/build/hooks/useProxy.d.ts +18 -0
  172. package/build/hooks/useProxy.d.ts.map +1 -0
  173. package/build/hooks/useProxy.js +16 -0
  174. package/build/hooks/useProxy.js.map +1 -0
  175. package/build/index.d.ts +32 -0
  176. package/build/index.d.ts.map +1 -0
  177. package/build/index.js +32 -0
  178. package/build/index.js.map +1 -0
  179. package/build/liveConfig.d.ts +13 -0
  180. package/build/liveConfig.d.ts.map +1 -0
  181. package/build/liveConfig.js +2 -0
  182. package/build/liveConfig.js.map +1 -0
  183. package/build/media.d.ts +85 -0
  184. package/build/media.d.ts.map +1 -0
  185. package/build/media.js +2 -0
  186. package/build/media.js.map +1 -0
  187. package/build/mediaControlConfig.d.ts +62 -0
  188. package/build/mediaControlConfig.d.ts.map +1 -0
  189. package/build/mediaControlConfig.js +2 -0
  190. package/build/mediaControlConfig.js.map +1 -0
  191. package/build/mediaTrackRole.d.ts +28 -0
  192. package/build/mediaTrackRole.d.ts.map +1 -0
  193. package/build/mediaTrackRole.js +2 -0
  194. package/build/mediaTrackRole.js.map +1 -0
  195. package/build/modules/AudioSessionModule.d.ts +8 -0
  196. package/build/modules/AudioSessionModule.d.ts.map +1 -0
  197. package/build/modules/AudioSessionModule.js +7 -0
  198. package/build/modules/AudioSessionModule.js.map +1 -0
  199. package/build/modules/BitmovinCastManagerModule.d.ts +11 -0
  200. package/build/modules/BitmovinCastManagerModule.d.ts.map +1 -0
  201. package/build/modules/BitmovinCastManagerModule.js +3 -0
  202. package/build/modules/BitmovinCastManagerModule.js.map +1 -0
  203. package/build/modules/BufferModule.d.ts +16 -0
  204. package/build/modules/BufferModule.d.ts.map +1 -0
  205. package/build/modules/BufferModule.js +3 -0
  206. package/build/modules/BufferModule.js.map +1 -0
  207. package/build/modules/DebugModule.d.ts +8 -0
  208. package/build/modules/DebugModule.d.ts.map +1 -0
  209. package/build/modules/DebugModule.js +3 -0
  210. package/build/modules/DebugModule.js.map +1 -0
  211. package/build/modules/PlayerModule.d.ts +188 -0
  212. package/build/modules/PlayerModule.d.ts.map +1 -0
  213. package/build/modules/PlayerModule.js +3 -0
  214. package/build/modules/PlayerModule.js.map +1 -0
  215. package/build/modules/SourceModule.d.ts +51 -0
  216. package/build/modules/SourceModule.d.ts.map +1 -0
  217. package/build/modules/SourceModule.js +3 -0
  218. package/build/modules/SourceModule.js.map +1 -0
  219. package/build/modules/UuidModule.d.ts +8 -0
  220. package/build/modules/UuidModule.d.ts.map +1 -0
  221. package/build/modules/UuidModule.js +3 -0
  222. package/build/modules/UuidModule.js.map +1 -0
  223. package/build/nativeInstance.d.ts +49 -0
  224. package/build/nativeInstance.d.ts.map +1 -0
  225. package/build/nativeInstance.js +20 -0
  226. package/build/nativeInstance.js.map +1 -0
  227. package/build/network/index.d.ts +50 -0
  228. package/build/network/index.d.ts.map +1 -0
  229. package/build/network/index.js +102 -0
  230. package/build/network/index.js.map +1 -0
  231. package/build/network/networkConfig.d.ts +151 -0
  232. package/build/network/networkConfig.d.ts.map +1 -0
  233. package/build/network/networkConfig.js +21 -0
  234. package/build/network/networkConfig.js.map +1 -0
  235. package/build/network/networkModule.d.ts +29 -0
  236. package/build/network/networkModule.d.ts.map +1 -0
  237. package/build/network/networkModule.js +3 -0
  238. package/build/network/networkModule.js.map +1 -0
  239. package/build/offline/index.d.ts +8 -0
  240. package/build/offline/index.d.ts.map +1 -0
  241. package/build/offline/index.js +8 -0
  242. package/build/offline/index.js.map +1 -0
  243. package/build/offline/offlineContentConfig.d.ts +18 -0
  244. package/build/offline/offlineContentConfig.d.ts.map +1 -0
  245. package/build/offline/offlineContentConfig.js +2 -0
  246. package/build/offline/offlineContentConfig.js.map +1 -0
  247. package/build/offline/offlineContentManager.d.ts +90 -0
  248. package/build/offline/offlineContentManager.d.ts.map +1 -0
  249. package/build/offline/offlineContentManager.js +177 -0
  250. package/build/offline/offlineContentManager.js.map +1 -0
  251. package/build/offline/offlineContentManagerListener.d.ts +174 -0
  252. package/build/offline/offlineContentManagerListener.d.ts.map +1 -0
  253. package/build/offline/offlineContentManagerListener.js +17 -0
  254. package/build/offline/offlineContentManagerListener.js.map +1 -0
  255. package/build/offline/offlineContentOptions.d.ts +29 -0
  256. package/build/offline/offlineContentOptions.d.ts.map +1 -0
  257. package/build/offline/offlineContentOptions.js +2 -0
  258. package/build/offline/offlineContentOptions.js.map +1 -0
  259. package/build/offline/offlineDownloadRequest.d.ts +19 -0
  260. package/build/offline/offlineDownloadRequest.d.ts.map +1 -0
  261. package/build/offline/offlineDownloadRequest.js +2 -0
  262. package/build/offline/offlineDownloadRequest.js.map +1 -0
  263. package/build/offline/offlineModule.d.ts +32 -0
  264. package/build/offline/offlineModule.d.ts.map +1 -0
  265. package/build/offline/offlineModule.js +3 -0
  266. package/build/offline/offlineModule.js.map +1 -0
  267. package/build/offline/offlineSourceOptions.d.ts +12 -0
  268. package/build/offline/offlineSourceOptions.d.ts.map +1 -0
  269. package/build/offline/offlineSourceOptions.js +2 -0
  270. package/build/offline/offlineSourceOptions.js.map +1 -0
  271. package/build/offline/offlineState.d.ts +23 -0
  272. package/build/offline/offlineState.d.ts.map +1 -0
  273. package/build/offline/offlineState.js +24 -0
  274. package/build/offline/offlineState.js.map +1 -0
  275. package/build/playbackConfig.d.ts +88 -0
  276. package/build/playbackConfig.d.ts.map +1 -0
  277. package/build/playbackConfig.js +2 -0
  278. package/build/playbackConfig.js.map +1 -0
  279. package/build/player.d.ts +308 -0
  280. package/build/player.d.ts.map +1 -0
  281. package/build/player.js +445 -0
  282. package/build/player.js.map +1 -0
  283. package/build/playerConfig.d.ts +83 -0
  284. package/build/playerConfig.d.ts.map +1 -0
  285. package/build/playerConfig.js +2 -0
  286. package/build/playerConfig.js.map +1 -0
  287. package/build/remoteControlConfig.d.ts +38 -0
  288. package/build/remoteControlConfig.d.ts.map +1 -0
  289. package/build/remoteControlConfig.js +2 -0
  290. package/build/remoteControlConfig.js.map +1 -0
  291. package/build/source.d.ts +216 -0
  292. package/build/source.d.ts.map +1 -0
  293. package/build/source.js +167 -0
  294. package/build/source.js.map +1 -0
  295. package/build/styleConfig.d.ts +120 -0
  296. package/build/styleConfig.d.ts.map +1 -0
  297. package/build/styleConfig.js +38 -0
  298. package/build/styleConfig.js.map +1 -0
  299. package/build/subtitleFormat.d.ts +27 -0
  300. package/build/subtitleFormat.d.ts.map +1 -0
  301. package/build/subtitleFormat.js +28 -0
  302. package/build/subtitleFormat.js.map +1 -0
  303. package/build/subtitleTrack.d.ts +55 -0
  304. package/build/subtitleTrack.d.ts.map +1 -0
  305. package/build/subtitleTrack.js +2 -0
  306. package/build/subtitleTrack.js.map +1 -0
  307. package/build/thumbnail.d.ts +38 -0
  308. package/build/thumbnail.d.ts.map +1 -0
  309. package/build/thumbnail.js +2 -0
  310. package/build/thumbnail.js.map +1 -0
  311. package/build/tweaksConfig.d.ts +197 -0
  312. package/build/tweaksConfig.d.ts.map +1 -0
  313. package/build/tweaksConfig.js +25 -0
  314. package/build/tweaksConfig.js.map +1 -0
  315. package/build/ui/customMessageHandlerModule.d.ts +27 -0
  316. package/build/ui/customMessageHandlerModule.d.ts.map +1 -0
  317. package/build/ui/customMessageHandlerModule.js +3 -0
  318. package/build/ui/customMessageHandlerModule.js.map +1 -0
  319. package/build/ui/custommessagehandler.d.ts +56 -0
  320. package/build/ui/custommessagehandler.d.ts.map +1 -0
  321. package/build/ui/custommessagehandler.js +54 -0
  322. package/build/ui/custommessagehandler.js.map +1 -0
  323. package/build/ui/custommessagehandlerbridge.d.ts +33 -0
  324. package/build/ui/custommessagehandlerbridge.d.ts.map +1 -0
  325. package/build/ui/custommessagehandlerbridge.js +72 -0
  326. package/build/ui/custommessagehandlerbridge.js.map +1 -0
  327. package/build/ui/custommessagesender.d.ts +5 -0
  328. package/build/ui/custommessagesender.d.ts.map +1 -0
  329. package/build/ui/custommessagesender.js +2 -0
  330. package/build/ui/custommessagesender.js.map +1 -0
  331. package/build/ui/fullscreenHandlerModule.d.ts +20 -0
  332. package/build/ui/fullscreenHandlerModule.d.ts.map +1 -0
  333. package/build/ui/fullscreenHandlerModule.js +3 -0
  334. package/build/ui/fullscreenHandlerModule.js.map +1 -0
  335. package/build/ui/fullscreenhandler.d.ts +18 -0
  336. package/build/ui/fullscreenhandler.d.ts.map +1 -0
  337. package/build/ui/fullscreenhandler.js +2 -0
  338. package/build/ui/fullscreenhandler.js.map +1 -0
  339. package/build/ui/fullscreenhandlerbridge.d.ts +26 -0
  340. package/build/ui/fullscreenhandlerbridge.d.ts.map +1 -0
  341. package/build/ui/fullscreenhandlerbridge.js +67 -0
  342. package/build/ui/fullscreenhandlerbridge.js.map +1 -0
  343. package/build/ui/index.d.ts +3 -0
  344. package/build/ui/index.d.ts.map +1 -0
  345. package/build/ui/index.js +3 -0
  346. package/build/ui/index.js.map +1 -0
  347. package/expo-module.config.json +40 -0
  348. package/ios/AppLifecycleDelegate.swift +25 -0
  349. package/ios/AudioSessionModule.swift +14 -40
  350. package/ios/BitmovinCastManagerModule.swift +30 -69
  351. package/ios/BufferModule.swift +26 -62
  352. package/ios/CustomMessageHandlerBridge.swift +11 -18
  353. package/ios/CustomMessageHandlerModule.swift +61 -63
  354. package/ios/DebugModule.swift +6 -27
  355. package/ios/DrmModule.swift +105 -379
  356. package/ios/Event+JSON.swift +1 -0
  357. package/ios/FullscreenHandlerBridge.swift +12 -5
  358. package/ios/FullscreenHandlerModule.swift +73 -57
  359. package/ios/LockedBox.swift +21 -0
  360. package/ios/ModuleRegistry+Generics.swift +11 -0
  361. package/ios/NetworkModule.swift +78 -82
  362. package/ios/OfflineContentManagerBridge.swift +11 -38
  363. package/ios/OfflineModule.swift +136 -454
  364. package/ios/PlayerAnalyticsModule.swift +24 -52
  365. package/ios/PlayerModule.swift +192 -770
  366. package/ios/RCTConvert+BitmovinPlayer.swift +38 -312
  367. package/ios/RNBitmovinPlayer.h +1 -8
  368. package/ios/RNBitmovinPlayer.podspec +47 -0
  369. package/ios/RNPlayerView.swift +600 -77
  370. package/ios/RNPlayerViewManager.swift +96 -210
  371. package/ios/Registry.swift +2 -2
  372. package/ios/ResultWaiter.swift +66 -0
  373. package/ios/SourceModule.swift +104 -223
  374. package/ios/UuidModule.swift +9 -18
  375. package/package.json +67 -71
  376. package/plugin/build/FeatureFlags.d.ts +24 -0
  377. package/plugin/build/FeatureFlags.js +2 -0
  378. package/plugin/build/index.d.ts +7 -0
  379. package/plugin/build/index.js +10 -0
  380. package/plugin/build/withAppGradleDependencies.d.ts +7 -0
  381. package/plugin/build/withAppGradleDependencies.js +49 -0
  382. package/plugin/build/withBitmovinAndroidConfig.d.ts +7 -0
  383. package/plugin/build/withBitmovinAndroidConfig.js +159 -0
  384. package/plugin/build/withBitmovinConfig.d.ts +7 -0
  385. package/plugin/build/withBitmovinConfig.js +21 -0
  386. package/plugin/build/withBitmovinIosConfig.d.ts +7 -0
  387. package/plugin/build/withBitmovinIosConfig.js +53 -0
  388. package/plugin/src/FeatureFlags.ts +21 -0
  389. package/plugin/src/index.ts +9 -0
  390. package/plugin/src/withAppGradleDependencies.ts +80 -0
  391. package/plugin/src/withBitmovinAndroidConfig.ts +224 -0
  392. package/plugin/src/withBitmovinConfig.ts +24 -0
  393. package/plugin/src/withBitmovinIosConfig.ts +71 -0
  394. package/plugin/tsconfig.json +9 -0
  395. package/plugin/tsconfig.tsbuildinfo +1 -0
  396. package/prettier.config.js +7 -0
  397. package/scripts/format-android.sh +2 -0
  398. package/scripts/format-swift.sh +3 -0
  399. package/scripts/lint-android.sh +2 -0
  400. package/scripts/lint-swift.sh +3 -0
  401. package/scripts/pre-commit.sh +14 -0
  402. package/scripts/setup-hooks.sh +58 -0
  403. package/src/BitmovinPlayerReactNative.types.ts +19 -0
  404. package/src/adaptationConfig.ts +1 -1
  405. package/src/advertising.ts +1 -1
  406. package/src/analytics/config.ts +4 -4
  407. package/src/analytics/player.ts +4 -6
  408. package/src/analytics/playerAnalyticsModule.ts +19 -0
  409. package/src/audioSession.ts +4 -6
  410. package/src/audioTrack.ts +1 -1
  411. package/src/bitmovinCastManager.ts +14 -10
  412. package/src/bufferApi.ts +1 -3
  413. package/src/bufferConfig.ts +2 -2
  414. package/src/components/PlayerView/events.ts +92 -94
  415. package/src/components/PlayerView/index.tsx +109 -159
  416. package/src/components/PlayerView/native.ts +24 -11
  417. package/src/components/PlayerView/nativeEvents.ts +113 -94
  418. package/src/components/PlayerView/pictureInPictureConfig.ts +1 -1
  419. package/src/components/PlayerView/playerViewConfig.ts +4 -8
  420. package/src/components/PlayerView/properties.ts +23 -22
  421. package/src/debug.ts +1 -3
  422. package/src/decoder/decoderConfig.ts +3 -3
  423. package/src/decoder/decoderConfigModule.ts +62 -0
  424. package/src/decoder/index.ts +32 -16
  425. package/src/drm/drmModule.ts +84 -0
  426. package/src/drm/fairplayConfig.ts +1 -1
  427. package/src/drm/index.ts +130 -40
  428. package/src/drm/widevineConfig.ts +5 -5
  429. package/src/events.ts +47 -41
  430. package/src/hooks/useProxy.ts +13 -20
  431. package/src/mediaControlConfig.ts +1 -1
  432. package/src/modules/AudioSessionModule.ts +13 -0
  433. package/src/modules/BitmovinCastManagerModule.ts +14 -0
  434. package/src/modules/BufferModule.ts +18 -0
  435. package/src/modules/DebugModule.ts +9 -0
  436. package/src/modules/PlayerModule.ts +251 -0
  437. package/src/modules/SourceModule.ts +74 -0
  438. package/src/modules/UuidModule.ts +9 -0
  439. package/src/nativeInstance.ts +3 -3
  440. package/src/network/index.ts +42 -15
  441. package/src/network/networkConfig.ts +3 -3
  442. package/src/network/networkModule.ts +51 -0
  443. package/src/offline/offlineContentConfig.ts +1 -1
  444. package/src/offline/offlineContentManager.ts +15 -50
  445. package/src/offline/offlineContentManagerListener.ts +20 -23
  446. package/src/offline/offlineContentOptions.ts +2 -2
  447. package/src/offline/offlineDownloadRequest.ts +1 -1
  448. package/src/offline/offlineModule.ts +46 -0
  449. package/src/offline/offlineSourceOptions.ts +2 -2
  450. package/src/offline/offlineState.ts +1 -1
  451. package/src/playbackConfig.ts +5 -6
  452. package/src/player.ts +53 -48
  453. package/src/source.ts +15 -14
  454. package/src/styleConfig.ts +5 -5
  455. package/src/subtitleFormat.ts +5 -5
  456. package/src/subtitleTrack.ts +1 -1
  457. package/src/tweaksConfig.ts +16 -16
  458. package/src/ui/customMessageHandlerModule.ts +46 -0
  459. package/src/ui/custommessagehandlerbridge.ts +45 -18
  460. package/src/ui/fullscreenHandlerModule.ts +35 -0
  461. package/src/ui/fullscreenhandlerbridge.ts +35 -15
  462. package/tsconfig.json +9 -0
  463. package/typedoc.json +23 -0
  464. package/RNBitmovinPlayer.podspec +0 -26
  465. package/android/src/main/java/com/bitmovin/player/reactnative/BitmovinBaseModule.kt +0 -114
  466. package/android/src/main/java/com/bitmovin/player/reactnative/EventRelay.kt +0 -47
  467. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +0 -48
  468. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt +0 -24
  469. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableArray.kt +0 -20
  470. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableMap.kt +0 -15
  471. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableMapExtension.kt +0 -57
  472. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/WritableMap.kt +0 -27
  473. package/android/src/main/java/com/bitmovin/player/reactnative/ui/CustomMessageHandlerModule.kt +0 -86
  474. package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerModule.kt +0 -78
  475. package/ios/AudioSessionModule.m +0 -10
  476. package/ios/BitmovinCastManagerModule.m +0 -14
  477. package/ios/BufferModule.m +0 -8
  478. package/ios/CustomMessageHandlerModule.m +0 -10
  479. package/ios/DebugModule.m +0 -7
  480. package/ios/DrmModule.m +0 -16
  481. package/ios/FullscreenHandlerModule.m +0 -10
  482. package/ios/NetworkModule.m +0 -10
  483. package/ios/OfflineModule.m +0 -19
  484. package/ios/PlayerAnalyticsModule.m +0 -8
  485. package/ios/PlayerModule.m +0 -130
  486. package/ios/PreprocessHttpRequestDelegateBridge.swift +0 -30
  487. package/ios/RCTBridge+Generics.swift +0 -6
  488. package/ios/RNBitmovinPlayer.xcodeproj/project.pbxproj +0 -303
  489. package/ios/RNPlayerView+PlayerListener.swift +0 -229
  490. package/ios/RNPlayerView+UserInterfaceListener.swift +0 -35
  491. package/ios/RNPlayerViewManager.m +0 -79
  492. package/ios/SourceModule.m +0 -42
  493. package/ios/UuidModule.m +0 -9
  494. package/lib/index.d.mts +0 -4303
  495. package/lib/index.d.ts +0 -4303
  496. package/lib/index.js +0 -1895
  497. package/lib/index.mjs +0 -1836
@@ -1,11 +1,14 @@
1
1
  package com.bitmovin.player.reactnative
2
2
 
3
3
  import android.annotation.SuppressLint
4
+ import android.content.Context
4
5
  import android.content.res.Configuration
5
6
  import android.os.Build
6
7
  import android.view.ViewGroup
8
+ import android.view.WindowManager
7
9
  import android.widget.FrameLayout
8
10
  import androidx.lifecycle.DefaultLifecycleObserver
11
+ import androidx.lifecycle.Lifecycle
9
12
  import androidx.lifecycle.LifecycleOwner
10
13
  import com.bitmovin.player.PlayerView
11
14
  import com.bitmovin.player.SubtitleView
@@ -14,106 +17,95 @@ import com.bitmovin.player.api.event.Event
14
17
  import com.bitmovin.player.api.event.PlayerEvent
15
18
  import com.bitmovin.player.api.event.SourceEvent
16
19
  import com.bitmovin.player.api.ui.PlayerViewConfig
17
- import com.bitmovin.player.api.ui.StyleConfig
20
+ import com.bitmovin.player.api.ui.ScalingMode
21
+ import com.bitmovin.player.api.ui.UiConfig
18
22
  import com.bitmovin.player.reactnative.converter.toJson
19
- import com.bitmovin.player.reactnative.extensions.playerModule
20
- import com.facebook.react.ReactActivity
21
- import com.facebook.react.bridge.*
22
- import com.facebook.react.uimanager.events.RCTEventEmitter
23
- import kotlin.reflect.KClass
24
-
25
- private val EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING = mapOf(
26
- PlayerEvent.Error::class to "playerError",
27
- PlayerEvent.Warning::class to "playerWarning",
28
- PlayerEvent.Destroy::class to "destroy",
29
- PlayerEvent.Muted::class to "muted",
30
- PlayerEvent.Unmuted::class to "unmuted",
31
- PlayerEvent.Ready::class to "ready",
32
- PlayerEvent.Paused::class to "paused",
33
- PlayerEvent.Play::class to "play",
34
- PlayerEvent.Playing::class to "playing",
35
- PlayerEvent.PlaybackFinished::class to "playbackFinished",
36
- PlayerEvent.Seek::class to "seek",
37
- PlayerEvent.Seeked::class to "seeked",
38
- PlayerEvent.TimeShift::class to "timeShift",
39
- PlayerEvent.TimeShifted::class to "timeShifted",
40
- PlayerEvent.StallStarted::class to "stallStarted",
41
- PlayerEvent.StallEnded::class to "stallEnded",
42
- PlayerEvent.TimeChanged::class to "timeChanged",
43
- SourceEvent.Load::class to "sourceLoad",
44
- SourceEvent.Loaded::class to "sourceLoaded",
45
- SourceEvent.Unloaded::class to "sourceUnloaded",
46
- SourceEvent.Error::class to "sourceError",
47
- SourceEvent.Warning::class to "sourceWarning",
48
- SourceEvent.SubtitleTrackAdded::class to "subtitleAdded",
49
- SourceEvent.SubtitleTrackChanged::class to "subtitleChanged",
50
- SourceEvent.SubtitleTrackRemoved::class to "subtitleRemoved",
51
- SourceEvent.AudioTrackAdded::class to "audioAdded",
52
- SourceEvent.AudioTrackChanged::class to "audioChanged",
53
- SourceEvent.AudioTrackRemoved::class to "audioRemoved",
54
- SourceEvent.DownloadFinished::class to "downloadFinished",
55
- SourceEvent.VideoDownloadQualityChanged::class to "videoDownloadQualityChanged",
56
- PlayerEvent.AdBreakFinished::class to "adBreakFinished",
57
- PlayerEvent.AdBreakStarted::class to "adBreakStarted",
58
- PlayerEvent.AdClicked::class to "adClicked",
59
- PlayerEvent.AdError::class to "adError",
60
- PlayerEvent.AdFinished::class to "adFinished",
61
- PlayerEvent.AdManifestLoad::class to "adManifestLoad",
62
- PlayerEvent.AdManifestLoaded::class to "adManifestLoaded",
63
- PlayerEvent.AdQuartile::class to "adQuartile",
64
- PlayerEvent.AdScheduled::class to "adScheduled",
65
- PlayerEvent.AdSkipped::class to "adSkipped",
66
- PlayerEvent.AdStarted::class to "adStarted",
67
- PlayerEvent.VideoPlaybackQualityChanged::class to "videoPlaybackQualityChanged",
68
- PlayerEvent.CastStart::class to "castStart",
69
- @Suppress("DEPRECATION")
70
- PlayerEvent.CastPlaybackFinished::class to "castPlaybackFinished",
71
- @Suppress("DEPRECATION")
72
- PlayerEvent.CastPaused::class to "castPaused",
73
- @Suppress("DEPRECATION")
74
- PlayerEvent.CastPlaying::class to "castPlaying",
75
- PlayerEvent.CastStarted::class to "castStarted",
76
- PlayerEvent.CastAvailable::class to "castAvailable",
77
- PlayerEvent.CastStopped::class to "castStopped",
78
- PlayerEvent.CastWaitingForDevice::class to "castWaitingForDevice",
79
- PlayerEvent.CastTimeUpdated::class to "castTimeUpdated",
80
- PlayerEvent.CueEnter::class to "cueEnter",
81
- PlayerEvent.CueExit::class to "cueExit",
82
- )
83
-
84
- private val EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING_UI = mapOf<KClass<out Event>, String>(
85
- PlayerEvent.PictureInPictureAvailabilityChanged::class to "pictureInPictureAvailabilityChanged",
86
- PlayerEvent.PictureInPictureEnter::class to "pictureInPictureEnter",
87
- PlayerEvent.PictureInPictureExit::class to "pictureInPictureExit",
88
- PlayerEvent.FullscreenEnabled::class to "fullscreenEnabled",
89
- PlayerEvent.FullscreenDisabled::class to "fullscreenDisabled",
90
- PlayerEvent.FullscreenEnter::class to "fullscreenEnter",
91
- PlayerEvent.FullscreenExit::class to "fullscreenExit",
92
- )
93
-
94
- /**
95
- * Native view wrapper for component instances. It both serves as the main view
96
- * handled by RN (the actual player view is handled by the RNPlayerViewManager) and
97
- * exposes player events as bubbling events.
98
- */
99
- @SuppressLint("ViewConstructor")
100
- class RNPlayerView(
101
- private val context: ReactApplicationContext,
102
- ) : FrameLayout(context) {
103
- private val activityLifecycle = (context.currentActivity as? ReactActivity)?.lifecycle
104
- ?: error("Trying to create an instance of ${this::class.simpleName} while not attached to a ReactActivity")
105
-
106
- /**
107
- * Relays the provided set of events, emitted by the player, together with the associated name
108
- * to the `eventOutput` callback.
109
- */
110
- private var playerEventRelay: EventRelay<Player, Event> = EventRelay<Player, Event>(
111
- EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING,
112
- ::emitEventFromPlayer,
113
- )
23
+ import com.bitmovin.player.reactnative.converter.toUserInterfaceType
24
+ import com.bitmovin.player.reactnative.ui.RNPictureInPictureHandler
25
+ import expo.modules.kotlin.AppContext
26
+ import expo.modules.kotlin.viewevent.EventDispatcher
27
+ import expo.modules.kotlin.viewevent.ViewEventCallback
28
+ import expo.modules.kotlin.views.ExpoView
114
29
 
115
- internal var enableBackgroundPlayback: Boolean = false
116
- var playerInMediaSessionService: Player? = null
30
+ @SuppressLint("ViewConstructor")
31
+ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
32
+ var playerView: PlayerView? = null
33
+ private set
34
+ private var subtitleView: SubtitleView? = null
35
+ private var playerContainer: FrameLayout? = null
36
+ var enableBackgroundPlayback: Boolean = false
37
+ private var scalingMode: ScalingMode? = null
38
+ private var requestedFullscreenValue: Boolean? = null
39
+ private var requestedPictureInPictureValue: Boolean? = null
40
+ private var fullscreenBridgeId: NativeId? = null
41
+
42
+ private val onBmpEvent by EventDispatcher()
43
+ private val onBmpPlayerActive by EventDispatcher()
44
+ private val onBmpPlayerInactive by EventDispatcher()
45
+ private val onBmpPlayerError by EventDispatcher()
46
+ private val onBmpPlayerWarning by EventDispatcher()
47
+ private val onBmpDestroy by EventDispatcher()
48
+ private val onBmpMuted by EventDispatcher()
49
+ private val onBmpUnmuted by EventDispatcher()
50
+ private val onBmpReady by EventDispatcher()
51
+ private val onBmpPaused by EventDispatcher()
52
+ private val onBmpPlay by EventDispatcher()
53
+ private val onBmpPlaying by EventDispatcher()
54
+ private val onBmpPlaybackFinished by EventDispatcher()
55
+ private val onBmpSeek by EventDispatcher()
56
+ private val onBmpSeeked by EventDispatcher()
57
+ private val onBmpTimeShift by EventDispatcher()
58
+ private val onBmpTimeShifted by EventDispatcher()
59
+ private val onBmpStallStarted by EventDispatcher()
60
+ private val onBmpStallEnded by EventDispatcher()
61
+ private val onBmpTimeChanged by EventDispatcher()
62
+ private val onBmpSourceLoad by EventDispatcher()
63
+ private val onBmpSourceLoaded by EventDispatcher()
64
+ private val onBmpSourceUnloaded by EventDispatcher()
65
+ private val onBmpSourceError by EventDispatcher()
66
+ private val onBmpSourceWarning by EventDispatcher()
67
+ private val onBmpAudioAdded by EventDispatcher()
68
+ private val onBmpAudioRemoved by EventDispatcher()
69
+ private val onBmpAudioChanged by EventDispatcher()
70
+ private val onBmpSubtitleAdded by EventDispatcher()
71
+ private val onBmpSubtitleRemoved by EventDispatcher()
72
+ private val onBmpSubtitleChanged by EventDispatcher()
73
+ private val onBmpDownloadFinished by EventDispatcher()
74
+ private val onBmpAdBreakFinished by EventDispatcher()
75
+ private val onBmpAdBreakStarted by EventDispatcher()
76
+ private val onBmpAdClicked by EventDispatcher()
77
+ private val onBmpAdError by EventDispatcher()
78
+ private val onBmpAdFinished by EventDispatcher()
79
+ private val onBmpAdManifestLoad by EventDispatcher()
80
+ private val onBmpAdManifestLoaded by EventDispatcher()
81
+ private val onBmpAdQuartile by EventDispatcher()
82
+ private val onBmpAdScheduled by EventDispatcher()
83
+ private val onBmpAdSkipped by EventDispatcher()
84
+ private val onBmpAdStarted by EventDispatcher()
85
+ private val onBmpVideoDownloadQualityChanged by EventDispatcher()
86
+ private val onBmpVideoPlaybackQualityChanged by EventDispatcher()
87
+ private val onBmpCastAvailable by EventDispatcher()
88
+ private val onBmpCastPaused by EventDispatcher()
89
+ private val onBmpCastPlaybackFinished by EventDispatcher()
90
+ private val onBmpCastPlaying by EventDispatcher()
91
+ private val onBmpCastStarted by EventDispatcher()
92
+ private val onBmpCastStart by EventDispatcher()
93
+ private val onBmpCastStopped by EventDispatcher()
94
+ private val onBmpCastTimeUpdated by EventDispatcher()
95
+ private val onBmpCastWaitingForDevice by EventDispatcher()
96
+ private val onBmpPlaybackSpeedChanged by EventDispatcher()
97
+ private val onBmpCueEnter by EventDispatcher()
98
+ private val onBmpCueExit by EventDispatcher()
99
+
100
+ private val onBmpFullscreenEnabled by EventDispatcher()
101
+ private val onBmpFullscreenDisabled by EventDispatcher()
102
+ private val onBmpFullscreenEnter by EventDispatcher()
103
+ private val onBmpFullscreenExit by EventDispatcher()
104
+ private val onBmpPictureInPictureAvailabilityChanged by EventDispatcher()
105
+ private val onBmpPictureInPictureEnter by EventDispatcher()
106
+ private val onBmpPictureInPictureExit by EventDispatcher()
107
+
108
+ private var playerInMediaSessionService: Player? = null
117
109
 
118
110
  private val activityLifecycleObserver = object : DefaultLifecycleObserver {
119
111
  override fun onStart(owner: LifecycleOwner) {
@@ -147,7 +139,7 @@ class RNPlayerView(
147
139
  if (!enableBackgroundPlayback) {
148
140
  return
149
141
  }
150
- if (context.playerModule?.mediaSessionPlaybackManager?.player != player) {
142
+ if (appContext.registry.getModule<PlayerModule>()?.mediaSessionPlaybackManager?.player != player) {
151
143
  return
152
144
  }
153
145
 
@@ -156,95 +148,175 @@ class RNPlayerView(
156
148
  }
157
149
  }
158
150
 
151
+ private val activityLifecycle: Lifecycle? =
152
+ (appContext.activityProvider?.currentActivity as? LifecycleOwner)?.lifecycle
153
+
159
154
  init {
160
155
  // React Native has a bug that dynamically added views sometimes aren't laid out again properly.
161
156
  // Since we dynamically add and remove SurfaceView under the hood this caused the player
162
157
  // to suddenly not show the video anymore because SurfaceView was not laid out properly.
163
158
  // Bitmovin player issue: https://github.com/bitmovin/bitmovin-player-react-native/issues/180
164
159
  // React Native layout issue: https://github.com/facebook/react-native/issues/17968
165
- getViewTreeObserver().addOnGlobalLayoutListener { requestLayout() }
160
+ viewTreeObserver.addOnGlobalLayoutListener { requestLayout() }
166
161
 
167
- activityLifecycle.addObserver(activityLifecycleObserver)
162
+ activityLifecycle?.addObserver(activityLifecycleObserver)
168
163
  }
169
164
 
170
- /**
171
- * Relays the provided set of events, emitted by the player view, together with the associated name
172
- * to the `eventOutput` callback.
173
- */
174
- private val viewEventRelay = EventRelay<PlayerView, Event>(EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING_UI, ::emitEvent)
165
+ fun dispose() {
166
+ activityLifecycle?.removeObserver(activityLifecycleObserver)
167
+ playerView?.onDestroy()
168
+ playerView = null
169
+ playerContainer?.let { container ->
170
+ (container.parent as? ViewGroup)?.removeView(container)
171
+ }
172
+ playerContainer = null
173
+ }
175
174
 
176
- private var _playerView: PlayerView? = null
177
- set(value) {
178
- field = value
179
- viewEventRelay.eventEmitter = field
180
- playerEventRelay.eventEmitter = field?.player
175
+ private fun setPlayerView(playerView: PlayerView) {
176
+ // Remove existing playerView if it exists
177
+ this.playerView?.let { oldPlayerView ->
178
+ oldPlayerView.player?.let {
179
+ detachPlayerListeners(it)
180
+ }
181
+ (oldPlayerView.parent as? ViewGroup)?.removeView(oldPlayerView)
182
+ oldPlayerView.player = null
181
183
  }
182
184
 
183
- /**
184
- * Associated Bitmovin's `PlayerView`.
185
- */
186
- val playerView: PlayerView? get() = _playerView
185
+ // Remove existing container if it exists
186
+ playerContainer?.let { oldContainer ->
187
+ (oldContainer.parent as? ViewGroup)?.removeView(oldContainer)
188
+ }
187
189
 
188
- private var subtitleView: SubtitleView? = null
190
+ // Create new container for the PlayerView
191
+ val newContainer = FrameLayout(context).apply {
192
+ layoutParams = FrameLayout.LayoutParams(
193
+ FrameLayout.LayoutParams.MATCH_PARENT,
194
+ FrameLayout.LayoutParams.MATCH_PARENT,
195
+ )
196
+ }
189
197
 
190
- /**
191
- * Handy property accessor for `playerView`'s player instance.
192
- */
193
- var player: Player?
194
- get() = playerView?.player
195
- set(value) {
196
- playerView?.player = value
197
- playerEventRelay.eventEmitter = value
198
+ // Add PlayerView to the container
199
+ (playerView.parent as ViewGroup?)?.removeView(playerView)
200
+ newContainer.addView(
201
+ playerView,
202
+ FrameLayout.LayoutParams(
203
+ FrameLayout.LayoutParams.MATCH_PARENT,
204
+ FrameLayout.LayoutParams.MATCH_PARENT,
205
+ ),
206
+ )
207
+
208
+ // Add container to the ExpoView with correct layout parameters
209
+ val containerLayoutParams = generateDefaultLayoutParams()
210
+ containerLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
211
+ containerLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
212
+ addView(newContainer, 0, containerLayoutParams)
213
+
214
+ this.playerView = playerView
215
+ this.playerContainer = newContainer
216
+
217
+ scalingMode?.let {
218
+ playerView.scalingMode = it
219
+ }
220
+ fullscreenBridgeId?.let {
221
+ attachFullscreenBridge(it)
222
+ }
223
+ requestedFullscreenValue?.let {
224
+ setFullscreen(it)
198
225
  }
226
+ requestedPictureInPictureValue?.let {
227
+ setPictureInPicture(it)
228
+ }
229
+ }
199
230
 
200
- /**
201
- * Configures the visual presentation and behaviour of the [playerView].
202
- */
203
- var config: RNPlayerViewConfigWrapper? = null
231
+ fun attachPlayer(
232
+ playerId: NativeId,
233
+ playerViewConfigWrapper: RNPlayerViewConfigWrapper?,
234
+ customMessageHandlerBridgeId: NativeId?,
235
+ enableBackgroundPlayback: Boolean,
236
+ isPictureInPictureEnabledOnPlayer: Boolean,
237
+ userInterfaceTypeName: String?,
238
+ ) {
239
+ val playerModule = appContext.registry.getModule<PlayerModule>()
240
+ // Player might not be initialized yet, this is a timing issue
241
+ // Return early without throwing to avoid crash
242
+ val player = playerModule?.getPlayerOrNull(playerId) ?: return
243
+
244
+ if (playerView?.player == player) {
245
+ // Player is already attached to the PlayerView
246
+ return
247
+ }
204
248
 
205
- /**
206
- * Cleans up the resources and listeners produced by this view.
207
- */
208
- fun dispose() {
209
- activityLifecycle.removeObserver(activityLifecycleObserver)
210
-
211
- val playerView = _playerView ?: return
212
- _playerView = null
213
- // The `RNPlayerView` should not take care of the player lifecycle.
214
- // As a different component is creating the player instance, the other component
215
- // is responsible for destroying the player in the end.
216
- playerView.player = null
217
- playerView.onDestroy()
218
- }
249
+ playerView?.player?.let {
250
+ detachPlayerListeners(it)
251
+ }
252
+ attachPlayerListeners(player)
253
+ if (playerView != null) {
254
+ playerView?.player = player
255
+ } else {
256
+ this.enableBackgroundPlayback = enableBackgroundPlayback
257
+ val userInterfaceType = userInterfaceTypeName?.toUserInterfaceType() ?: UserInterfaceType.Bitmovin
258
+ val configuredPlayerViewConfig = playerViewConfigWrapper?.playerViewConfig ?: PlayerViewConfig()
259
+
260
+ val currentActivity = appContext.activityProvider?.currentActivity
261
+ ?: throw IllegalStateException("Cannot create a PlayerView, because no activity is attached.")
262
+ val playerViewConfig: PlayerViewConfig = if (userInterfaceType != UserInterfaceType.Bitmovin) {
263
+ configuredPlayerViewConfig.copy(uiConfig = UiConfig.Disabled)
264
+ } else {
265
+ configuredPlayerViewConfig
266
+ }
219
267
 
220
- /**
221
- * Set the given `playerView` as child and start bubbling events.
222
- * @param playerView Shared player view instance.
223
- */
224
- fun setPlayerView(playerView: PlayerView) {
225
- this.playerView?.let { currentPlayerView ->
226
- (currentPlayerView.parent as? ViewGroup)?.removeView(currentPlayerView)
268
+ val newPlayerView = PlayerView(currentActivity, player, playerViewConfig)
269
+
270
+ newPlayerView.layoutParams = LayoutParams(
271
+ LayoutParams.MATCH_PARENT,
272
+ LayoutParams.MATCH_PARENT,
273
+ )
274
+
275
+ val isPictureInPictureEnabled = isPictureInPictureEnabledOnPlayer ||
276
+ playerViewConfigWrapper?.pictureInPictureConfig?.isEnabled == true
277
+ if (isPictureInPictureEnabled) {
278
+ newPlayerView.setPictureInPictureHandler(RNPictureInPictureHandler(currentActivity, player))
279
+ }
280
+ setPlayerView(newPlayerView)
281
+ attachPlayerViewListeners(newPlayerView)
282
+
283
+ val playerConfig = player.config
284
+ if (playerConfig.styleConfig.isUiEnabled && userInterfaceType == UserInterfaceType.Subtitle) {
285
+ appContext.activityProvider?.currentActivity?.let { activity ->
286
+ val subtitleView = SubtitleView(activity)
287
+ subtitleView.setPlayer(player)
288
+ setSubtitleView(subtitleView)
289
+ }
290
+ }
227
291
  }
228
- this._playerView = playerView
229
- if (playerView.parent != this) {
230
- (playerView.parent as ViewGroup?)?.removeView(playerView)
231
- addView(playerView, 0)
292
+ customMessageHandlerBridgeId?.let {
293
+ appContext.registry.getModule<CustomMessageHandlerModule>()?.getInstance(it)
294
+ ?.let { customMessageHandlerBridge ->
295
+ playerView?.setCustomMessageHandler(customMessageHandlerBridge.customMessageHandler)
296
+ }
232
297
  }
233
298
  }
234
299
 
235
- /**
236
- * Set the given `subtitleView` as a child
237
- */
238
- fun setSubtitleView(subtitleView: SubtitleView) {
300
+ private fun setSubtitleView(subtitleView: SubtitleView) {
239
301
  this.subtitleView?.let { currentSubtitleView ->
240
302
  (currentSubtitleView.parent as? ViewGroup)?.removeView(currentSubtitleView)
241
303
  }
242
304
  this.subtitleView = subtitleView
243
- addView(subtitleView)
305
+
306
+ // Add SubtitleView to the playerContainer instead of the ExpoView
307
+ // This ensures it's on top of the PlayerView
308
+ playerContainer?.let { container ->
309
+ val layoutParams = FrameLayout.LayoutParams(
310
+ FrameLayout.LayoutParams.MATCH_PARENT,
311
+ FrameLayout.LayoutParams.MATCH_PARENT,
312
+ )
313
+ container.addView(subtitleView, layoutParams)
314
+ subtitleView.bringToFront() // Ensure proper z-ordering
315
+ }
244
316
  }
245
317
 
246
318
  private fun isInPictureInPictureMode(): Boolean {
247
- val activity = context.currentActivity ?: return false
319
+ val activity = appContext.activityProvider?.currentActivity ?: return false
248
320
  return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
249
321
  activity.isInPictureInPictureMode
250
322
  } else {
@@ -259,9 +331,13 @@ class RNPlayerView(
259
331
  */
260
332
  override fun onConfigurationChanged(newConfig: Configuration) {
261
333
  super.onConfigurationChanged(newConfig)
262
- if (isCurrentActivityInPictureInPictureMode != isInPictureInPictureMode()) {
263
- isCurrentActivityInPictureInPictureMode = isInPictureInPictureMode()
264
- onPictureInPictureModeChanged(isCurrentActivityInPictureInPictureMode, newConfig)
334
+
335
+ val wasInPiP = isCurrentActivityInPictureInPictureMode
336
+ val nowInPiP = isInPictureInPictureMode()
337
+
338
+ if (wasInPiP != nowInPiP) {
339
+ isCurrentActivityInPictureInPictureMode = nowInPiP
340
+ onPictureInPictureModeChanged(nowInPiP, newConfig)
265
341
  }
266
342
  }
267
343
 
@@ -270,11 +346,325 @@ class RNPlayerView(
270
346
  newConfig: Configuration,
271
347
  ) {
272
348
  val playerView = playerView ?: return
349
+
273
350
  playerView.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
351
+
274
352
  if (isInPictureInPictureMode) {
275
- playerView.enterPictureInPicture()
353
+ if (!playerView.isPictureInPicture) {
354
+ playerView.enterPictureInPicture()
355
+ }
356
+
357
+ // Force layout update for PiP mode and ensure proper sizing
358
+ playerView.requestLayout()
359
+ requestLayout()
360
+
361
+ // Additional PiP-specific layout handling
362
+ post {
363
+ val activity = appContext.activityProvider?.currentActivity
364
+ if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
365
+ activity.isInPictureInPictureMode
366
+ ) {
367
+ // Get the actual PiP window dimensions from WindowManager
368
+ val windowManager = activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager
369
+ val pipWidth: Int
370
+ val pipHeight: Int
371
+
372
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
373
+ // Use WindowMetrics for API 30+
374
+ val windowMetrics = windowManager.currentWindowMetrics
375
+ val windowBounds = windowMetrics.bounds
376
+ pipWidth = windowBounds.width()
377
+ pipHeight = windowBounds.height()
378
+ } else {
379
+ // Use deprecated Display.getSize() for older APIs
380
+ val displayMetrics = android.util.DisplayMetrics()
381
+ @Suppress("DEPRECATION")
382
+ windowManager.defaultDisplay.getMetrics(displayMetrics)
383
+ pipWidth = displayMetrics.widthPixels
384
+ pipHeight = displayMetrics.heightPixels
385
+ }
386
+
387
+ // Force the ExpoView to be resized to PiP dimensions
388
+ // Preserve the original layout params type to avoid ClassCastException
389
+ layoutParams?.let { currentParams ->
390
+ currentParams.width = pipWidth
391
+ currentParams.height = pipHeight
392
+ // Re-assign to trigger layout update
393
+ layoutParams = currentParams
394
+ }
395
+
396
+ // Ensure the ExpoView container is properly sized for PiP
397
+ measure(
398
+ MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
399
+ MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
400
+ )
401
+ layout(left, top, left + pipWidth, top + pipHeight)
402
+
403
+ // Ensure the intermediate container is properly sized for PiP
404
+ playerContainer?.let { container ->
405
+ // Preserve the original layout params type for the container
406
+ container.layoutParams?.let { containerParams ->
407
+ containerParams.width = pipWidth
408
+ containerParams.height = pipHeight
409
+ container.layoutParams = containerParams
410
+ }
411
+ container.measure(
412
+ MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
413
+ MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
414
+ )
415
+ container.layout(0, 0, pipWidth, pipHeight)
416
+ }
417
+
418
+ // Ensure the PlayerView is properly sized for PiP
419
+ playerView.layoutParams = FrameLayout.LayoutParams(pipWidth, pipHeight)
420
+ playerView.measure(
421
+ MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
422
+ MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
423
+ )
424
+ playerView.layout(0, 0, pipWidth, pipHeight)
425
+
426
+ // Ensure the SubtitleView is properly sized for PiP
427
+ subtitleView?.let { subtitleView ->
428
+ subtitleView.layoutParams = FrameLayout.LayoutParams(pipWidth, pipHeight)
429
+ subtitleView.measure(
430
+ MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
431
+ MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
432
+ )
433
+ subtitleView.layout(0, 0, pipWidth, pipHeight)
434
+ subtitleView.invalidate()
435
+ }
436
+
437
+ // Try to force a redraw
438
+ playerView.invalidate()
439
+ playerContainer?.invalidate()
440
+ invalidate()
441
+ }
442
+ }
276
443
  } else {
277
- playerView.exitPictureInPicture()
444
+ if (playerView.isPictureInPicture) {
445
+ playerView.exitPictureInPicture()
446
+ }
447
+
448
+ // Restore full size layout when exiting PiP
449
+ post {
450
+ // Reset ExpoView to full size
451
+ layoutParams?.let { currentParams ->
452
+ currentParams.width = ViewGroup.LayoutParams.MATCH_PARENT
453
+ currentParams.height = ViewGroup.LayoutParams.MATCH_PARENT
454
+ layoutParams = currentParams
455
+ }
456
+
457
+ // Reset intermediate container to full size
458
+ playerContainer?.let { container ->
459
+ container.layoutParams?.let { containerParams ->
460
+ containerParams.width = ViewGroup.LayoutParams.MATCH_PARENT
461
+ containerParams.height = ViewGroup.LayoutParams.MATCH_PARENT
462
+ container.layoutParams = containerParams
463
+ }
464
+ }
465
+
466
+ // Reset PlayerView to full size
467
+ playerView.layoutParams = FrameLayout.LayoutParams(
468
+ FrameLayout.LayoutParams.MATCH_PARENT,
469
+ FrameLayout.LayoutParams.MATCH_PARENT,
470
+ )
471
+
472
+ // Reset SubtitleView to full size
473
+ subtitleView?.let { subtitleView ->
474
+ subtitleView.layoutParams = FrameLayout.LayoutParams(
475
+ FrameLayout.LayoutParams.MATCH_PARENT,
476
+ FrameLayout.LayoutParams.MATCH_PARENT,
477
+ )
478
+ }
479
+
480
+ // Force layout updates
481
+ measure(
482
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
483
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
484
+ )
485
+ layout(left, top, right, bottom)
486
+
487
+ playerContainer?.let { container ->
488
+ container.measure(
489
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
490
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
491
+ )
492
+ container.layout(0, 0, width, height)
493
+ }
494
+
495
+ playerView.measure(
496
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
497
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
498
+ )
499
+ playerView.layout(0, 0, width, height)
500
+
501
+ // Ensure SubtitleView is properly measured and laid out when exiting PiP
502
+ subtitleView?.let { subtitleView ->
503
+ subtitleView.measure(
504
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
505
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
506
+ )
507
+ subtitleView.layout(0, 0, width, height)
508
+ subtitleView.invalidate()
509
+ }
510
+ }
511
+ }
512
+ }
513
+
514
+ private fun attachPlayerViewListeners(playerView: PlayerView) {
515
+ playerView.on(PlayerEvent.FullscreenEnabled::class) {
516
+ onBmpFullscreenEnabled(it.toJson())
517
+ }
518
+ playerView.on(PlayerEvent.FullscreenDisabled::class) {
519
+ onBmpFullscreenDisabled(it.toJson())
520
+ }
521
+ playerView.on(PlayerEvent.FullscreenEnter::class) {
522
+ onBmpFullscreenEnter(it.toJson())
523
+ }
524
+ playerView.on(PlayerEvent.FullscreenExit::class) {
525
+ onBmpFullscreenExit(it.toJson())
526
+ }
527
+ playerView.on(PlayerEvent.PictureInPictureAvailabilityChanged::class) {
528
+ onBmpPictureInPictureAvailabilityChanged(it.toJson())
529
+ }
530
+ playerView.on(PlayerEvent.PictureInPictureEnter::class) {
531
+ onBmpPictureInPictureEnter(it.toJson())
532
+ }
533
+ playerView.on(PlayerEvent.PictureInPictureExit::class) {
534
+ onBmpPictureInPictureExit(it.toJson())
535
+ }
536
+ }
537
+
538
+ private var playerEventSubscriptions = mutableListOf<EventSubscription<*>>()
539
+
540
+ private fun detachPlayerListeners(player: Player) {
541
+ playerEventSubscriptions.forEach { listener ->
542
+ player.off(listener)
543
+ }
544
+ playerEventSubscriptions.clear()
545
+ }
546
+
547
+ private fun attachPlayerListeners(player: Player) {
548
+ playerEventSubscriptions = mutableListOf(
549
+ player.on<PlayerEvent.Active> { onEvent(onBmpPlayerActive, it.toJson()) },
550
+ player.on<PlayerEvent.Inactive> { onEvent(onBmpPlayerInactive, it.toJson()) },
551
+ player.on<PlayerEvent.Error> { onEvent(onBmpPlayerError, it.toJson()) },
552
+ player.on<PlayerEvent.Warning> { onEvent(onBmpPlayerWarning, it.toJson()) },
553
+ player.on<PlayerEvent.Destroy> { onEvent(onBmpDestroy, it.toJson()) },
554
+ player.on<PlayerEvent.Muted> { onEvent(onBmpMuted, it.toJson()) },
555
+ player.on<PlayerEvent.Unmuted> { onEvent(onBmpUnmuted, it.toJson()) },
556
+ player.on<PlayerEvent.Ready> { onEvent(onBmpReady, it.toJson()) },
557
+ player.on<PlayerEvent.Paused> { onEvent(onBmpPaused, it.toJson()) },
558
+ player.on<PlayerEvent.Play> { onEvent(onBmpPlay, it.toJson()) },
559
+ player.on<PlayerEvent.Playing> { onEvent(onBmpPlaying, it.toJson()) },
560
+ player.on<PlayerEvent.PlaybackFinished> { onEvent(onBmpPlaybackFinished, it.toJson()) },
561
+ player.on<PlayerEvent.Seek> { onEvent(onBmpSeek, it.toJson()) },
562
+ player.on<PlayerEvent.Seeked> { onEvent(onBmpSeeked, it.toJson()) },
563
+ player.on<PlayerEvent.TimeShift> { onEvent(onBmpTimeShift, it.toJson()) },
564
+ player.on<PlayerEvent.TimeShifted> { onEvent(onBmpTimeShifted, it.toJson()) },
565
+ player.on<PlayerEvent.StallStarted> { onEvent(onBmpStallStarted, it.toJson()) },
566
+ player.on<PlayerEvent.StallEnded> { onEvent(onBmpStallEnded, it.toJson()) },
567
+ player.on<PlayerEvent.TimeChanged> { onEvent(onBmpTimeChanged, it.toJson()) },
568
+ player.on<SourceEvent.Load> { onEvent(onBmpSourceLoad, it.toJson()) },
569
+ player.on<SourceEvent.Loaded> { onEvent(onBmpSourceLoaded, it.toJson()) },
570
+ player.on<SourceEvent.Unloaded> { onEvent(onBmpSourceUnloaded, it.toJson()) },
571
+ player.on<SourceEvent.Error> { onEvent(onBmpSourceError, it.toJson()) },
572
+ player.on<SourceEvent.Warning> { onEvent(onBmpSourceWarning, it.toJson()) },
573
+ player.on<SourceEvent.AudioTrackAdded> { onEvent(onBmpAudioAdded, it.toJson()) },
574
+ player.on<SourceEvent.AudioTrackChanged> { onEvent(onBmpAudioChanged, it.toJson()) },
575
+ player.on<SourceEvent.AudioTrackRemoved> { onEvent(onBmpAudioRemoved, it.toJson()) },
576
+ player.on<SourceEvent.SubtitleTrackAdded> { onEvent(onBmpSubtitleAdded, it.toJson()) },
577
+ player.on<SourceEvent.SubtitleTrackChanged> { onEvent(onBmpSubtitleChanged, it.toJson()) },
578
+ player.on<SourceEvent.SubtitleTrackRemoved> { onEvent(onBmpSubtitleRemoved, it.toJson()) },
579
+ player.on<SourceEvent.DownloadFinished> { onEvent(onBmpDownloadFinished, it.toJson()) },
580
+ player.on<PlayerEvent.AdBreakFinished> { onEvent(onBmpAdBreakFinished, it.toJson()) },
581
+ player.on<PlayerEvent.AdBreakStarted> { onEvent(onBmpAdBreakStarted, it.toJson()) },
582
+ player.on<PlayerEvent.AdClicked> { onEvent(onBmpAdClicked, it.toJson()) },
583
+ player.on<PlayerEvent.AdError> { onEvent(onBmpAdError, it.toJson()) },
584
+ player.on<PlayerEvent.AdFinished> { onEvent(onBmpAdFinished, it.toJson()) },
585
+ player.on<PlayerEvent.AdManifestLoad> { onEvent(onBmpAdManifestLoad, it.toJson()) },
586
+ player.on<PlayerEvent.AdManifestLoaded> { onEvent(onBmpAdManifestLoaded, it.toJson()) },
587
+ player.on<PlayerEvent.AdQuartile> { onEvent(onBmpAdQuartile, it.toJson()) },
588
+ player.on<PlayerEvent.AdScheduled> { onEvent(onBmpAdScheduled, it.toJson()) },
589
+ player.on<PlayerEvent.AdSkipped> { onEvent(onBmpAdSkipped, it.toJson()) },
590
+ player.on<PlayerEvent.AdStarted> { onEvent(onBmpAdStarted, it.toJson()) },
591
+ player.on<SourceEvent.VideoDownloadQualityChanged> {
592
+ onEvent(
593
+ onBmpVideoDownloadQualityChanged,
594
+ it.toJson(),
595
+ )
596
+ },
597
+ player.on<PlayerEvent.VideoPlaybackQualityChanged> {
598
+ onEvent(
599
+ onBmpVideoPlaybackQualityChanged,
600
+ it.toJson(),
601
+ )
602
+ },
603
+ player.on<PlayerEvent.CastAvailable> { onEvent(onBmpCastAvailable, it.toJson()) },
604
+ player.on<PlayerEvent.CastPaused> { onEvent(onBmpCastPaused, it.toJson()) },
605
+ player.on<PlayerEvent.CastPlaybackFinished> { onEvent(onBmpCastPlaybackFinished, it.toJson()) },
606
+ player.on<PlayerEvent.CastPlaying> { onEvent(onBmpCastPlaying, it.toJson()) },
607
+ player.on<PlayerEvent.CastStarted> { onEvent(onBmpCastStarted, it.toJson()) },
608
+ player.on<PlayerEvent.CastStart> { onEvent(onBmpCastStart, it.toJson()) },
609
+ player.on<PlayerEvent.CastStopped> { onEvent(onBmpCastStopped, it.toJson()) },
610
+ player.on<PlayerEvent.CastTimeUpdated> { onEvent(onBmpCastTimeUpdated, it.toJson()) },
611
+ player.on<PlayerEvent.CastWaitingForDevice> { onEvent(onBmpCastWaitingForDevice, it.toJson()) },
612
+ player.on<PlayerEvent.CueEnter> { onEvent(onBmpCueEnter, it.toJson()) },
613
+ player.on<PlayerEvent.CueExit> { onEvent(onBmpCueExit, it.toJson()) },
614
+ )
615
+ }
616
+
617
+ private fun onEvent(dispatcher: ViewEventCallback<Map<String, Any>>, eventData: Map<String, Any>) {
618
+ dispatcher(eventData)
619
+ onBmpEvent(eventData)
620
+ }
621
+
622
+ fun setFullscreen(isFullscreen: Boolean) {
623
+ requestedFullscreenValue = isFullscreen
624
+ playerView?.let {
625
+ if (it.isFullscreen == isFullscreen) return
626
+ if (isFullscreen) {
627
+ it.enterFullscreen()
628
+ } else {
629
+ it.exitFullscreen()
630
+ }
631
+ }
632
+ }
633
+
634
+ fun setPictureInPicture(isPictureInPicture: Boolean) {
635
+ requestedPictureInPictureValue = isPictureInPicture
636
+ playerView?.let {
637
+ if (it.isPictureInPicture == isPictureInPicture) {
638
+ return
639
+ }
640
+ if (isPictureInPicture) {
641
+ it.enterPictureInPicture()
642
+ } else {
643
+ it.exitPictureInPicture()
644
+ }
645
+ }
646
+ }
647
+
648
+ fun setScalingMode(scalingMode: String?) {
649
+ this.scalingMode = scalingMode?.let { ScalingMode.valueOf(it) } ?: ScalingMode.Fit
650
+ playerView?.scalingMode = this.scalingMode ?: ScalingMode.Fit
651
+ }
652
+
653
+ fun attachFullscreenBridge(fullscreenBridgeId: NativeId) {
654
+ this.fullscreenBridgeId = fullscreenBridgeId
655
+ val playerView = playerView ?: return
656
+ appContext.registry.getModule<FullscreenHandlerModule>()?.getInstance(fullscreenBridgeId)
657
+ ?.let { fullscreenBridge ->
658
+ playerView.setFullscreenHandler(fullscreenBridge)
659
+ } ?: throw IllegalArgumentException("Fullscreen bridge with ID $fullscreenBridgeId not found")
660
+ requestedFullscreenValue?.let { isFullscreen ->
661
+ playerView.let {
662
+ if (isFullscreen) {
663
+ it.enterFullscreen()
664
+ } else {
665
+ it.exitFullscreen()
666
+ }
667
+ }
278
668
  }
279
669
  }
280
670
 
@@ -293,55 +683,10 @@ class RNPlayerView(
293
683
  layout(left, top, right, bottom)
294
684
  }
295
685
  }
296
-
297
- /**
298
- * Emits a bubbling event with payload to js.
299
- * @param name Native event name.
300
- * @param event Optional js object to be sent as payload.
301
- */
302
- private fun <E : Event> emitEvent(name: String, event: E) {
303
- val payload = when (event) {
304
- is PlayerEvent -> event.toJson()
305
- is SourceEvent -> event.toJson()
306
- else -> throw IllegalArgumentException()
307
- }
308
- val reactContext = context as ReactContext
309
- reactContext
310
- .getJSModule(RCTEventEmitter::class.java)
311
- .receiveEvent(id, name, payload)
312
- }
313
-
314
- /**
315
- * Emits a bubbling event from the player with payload to js
316
- * and emits it for "event" to support `onEvent` prop.
317
- * @param name Native event name.
318
- * @param event Optional js object to be sent as payload.
319
- */
320
- private fun <E : Event> emitEventFromPlayer(name: String, event: E) {
321
- emitEvent(name, event)
322
- emitEvent("event", event)
323
- }
324
686
  }
325
687
 
326
- /**
327
- * Representation of the React Native API `PlayerViewConfig` object.
328
- * This is necessary as not all of its values can be directly mapped to the native `PlayerViewConfig`.
329
- */
330
- data class RNPlayerViewConfigWrapper(
331
- val playerViewConfig: PlayerViewConfig?,
332
- val pictureInPictureConfig: PictureInPictureConfig?,
333
- )
334
-
335
- data class RNStyleConfigWrapper(
336
- val styleConfig: StyleConfig?,
337
- val userInterfaceType: UserInterfaceType,
338
- )
339
-
340
- enum class UserInterfaceType {
341
- Bitmovin, Subtitle
688
+ private inline fun <reified E : Event> Player.on(noinline onEvent: (event: E) -> Unit): EventSubscription<E> {
689
+ val eventSubscription = EventSubscription(E::class, onEvent)
690
+ this.on(eventSubscription.eventClass, eventSubscription.action)
691
+ return eventSubscription
342
692
  }
343
-
344
- /**
345
- * Configuration type for picture in picture behaviors.
346
- */
347
- data class PictureInPictureConfig(val isEnabled: Boolean)