react-native-theoplayer 1.7.2 → 1.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 (236) hide show
  1. package/README.md +2 -0
  2. package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +115 -0
  3. package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +648 -0
  4. package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.kt +23 -0
  5. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +446 -0
  6. package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.kt +117 -0
  7. package/android/src/main/java/com/theoplayer/{TimeUpdateRate.java → TimeUpdateRate.kt} +2 -2
  8. package/android/src/main/java/com/theoplayer/ads/AdAdapter.kt +161 -0
  9. package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.kt +90 -0
  10. package/android/src/main/java/com/theoplayer/ads/AdsModule.kt +140 -0
  11. package/android/src/main/java/com/theoplayer/cast/CastEventAdapter.kt +81 -0
  12. package/android/src/main/java/com/theoplayer/cast/CastModule.kt +75 -0
  13. package/android/src/main/java/com/theoplayer/drm/ContentProtectionAdapter.kt +2 -2
  14. package/android/src/main/java/com/theoplayer/drm/ContentProtectionModule.kt +1 -2
  15. package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegration.kt +1 -2
  16. package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegrationFactory.kt +3 -5
  17. package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +402 -0
  18. package/android/src/main/java/com/theoplayer/track/MediaTrackEventType.kt +6 -0
  19. package/android/src/main/java/com/theoplayer/track/MediaTrackType.kt +6 -0
  20. package/android/src/main/java/com/theoplayer/track/QualityListAdapter.kt +43 -0
  21. package/android/src/main/java/com/theoplayer/track/QualityListFilter.kt +28 -0
  22. package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.kt +10 -0
  23. package/android/src/main/java/com/theoplayer/track/TrackEventType.kt +7 -0
  24. package/android/src/main/java/com/theoplayer/track/TrackListAdapter.kt +219 -0
  25. package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +19 -0
  26. package/ios/THEOplayerRCTAdAggregator.swift +12 -6
  27. package/ios/THEOplayerRCTAdsAPI.swift +39 -40
  28. package/ios/THEOplayerRCTBridge.m +52 -1
  29. package/ios/THEOplayerRCTCastAPI.swift +275 -0
  30. package/ios/THEOplayerRCTDebug.swift +3 -0
  31. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +91 -19
  32. package/ios/{THEOplayerRCTMetadataAggregator.swift → THEOplayerRCTTrackMetadataAggregator.swift} +12 -12
  33. package/ios/THEOplayerRCTView.swift +104 -24
  34. package/ios/THEOplayerRCTViewAdEventHandler.swift +2 -2
  35. package/ios/THEOplayerRCTViewCastEventHandler.swift +124 -0
  36. package/ios/THEOplayerRCTViewMainEventHandler.swift +1 -1
  37. package/ios/THEOplayerRCTViewMediaTrackEventHandler.swift +6 -6
  38. package/ios/THEOplayerRCTViewTextTrackEventHandler.swift +5 -5
  39. package/ios/custom/Frameworks/ios/put_custom_ios_xcframework_here.txt +1 -1
  40. package/ios/custom/Frameworks/tvos/put_custom_tvos_xcframework_here.txt +2 -0
  41. package/ios/custom/react-native-theoplayer_custom.podspec +46 -0
  42. package/lib/commonjs/api/THEOplayerView.js.map +1 -1
  43. package/lib/commonjs/api/barrel.js +21 -8
  44. package/lib/commonjs/api/barrel.js.map +1 -1
  45. package/lib/commonjs/api/cast/Airplay.js +6 -0
  46. package/lib/commonjs/api/cast/Airplay.js.map +1 -0
  47. package/lib/commonjs/api/cast/CastAPI.js +6 -0
  48. package/lib/commonjs/api/cast/CastAPI.js.map +1 -0
  49. package/lib/commonjs/api/cast/CastConfiguration.js +2 -0
  50. package/lib/commonjs/api/cast/CastConfiguration.js.map +1 -0
  51. package/lib/commonjs/api/cast/CastState.js +2 -0
  52. package/lib/commonjs/api/cast/CastState.js.map +1 -0
  53. package/lib/commonjs/api/cast/Chromecast.js +6 -0
  54. package/lib/commonjs/api/cast/Chromecast.js.map +1 -0
  55. package/lib/commonjs/api/cast/barrel.js +71 -0
  56. package/lib/commonjs/api/cast/barrel.js.map +1 -0
  57. package/lib/commonjs/api/config/PlayerConfiguration.js.map +1 -1
  58. package/lib/commonjs/api/error/ChromecastError.js +2 -0
  59. package/lib/commonjs/api/error/ChromecastError.js.map +1 -0
  60. package/lib/commonjs/api/error/barrel.js +13 -0
  61. package/lib/commonjs/api/error/barrel.js.map +1 -1
  62. package/lib/commonjs/api/event/CastEvent.js +21 -0
  63. package/lib/commonjs/api/event/CastEvent.js.map +1 -0
  64. package/lib/commonjs/api/event/barrel.js +25 -12
  65. package/lib/commonjs/api/event/barrel.js.map +1 -1
  66. package/lib/commonjs/api/source/SourceDescription.js.map +1 -1
  67. package/lib/commonjs/api/source/barrel.js +13 -0
  68. package/lib/commonjs/api/source/barrel.js.map +1 -1
  69. package/lib/commonjs/api/source/metadata/MetadataDescription.js +2 -0
  70. package/lib/commonjs/api/source/metadata/MetadataDescription.js.map +1 -0
  71. package/lib/commonjs/api/source/metadata/barrel.js +19 -0
  72. package/lib/commonjs/api/source/metadata/barrel.js.map +1 -0
  73. package/lib/commonjs/internal/THEOplayerView.js +16 -0
  74. package/lib/commonjs/internal/THEOplayerView.js.map +1 -1
  75. package/lib/commonjs/internal/THEOplayerView.web.js +9 -0
  76. package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
  77. package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js +34 -0
  78. package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
  79. package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js +46 -0
  80. package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
  81. package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js +42 -0
  82. package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
  83. package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js +31 -0
  84. package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js.map +1 -0
  85. package/lib/commonjs/internal/web/stub/CastButtonStub.js +16 -0
  86. package/lib/commonjs/internal/web/stub/CastButtonStub.js.map +1 -0
  87. package/lib/module/api/THEOplayerView.js.map +1 -1
  88. package/lib/module/api/barrel.js +1 -0
  89. package/lib/module/api/barrel.js.map +1 -1
  90. package/lib/module/api/cast/Airplay.js +2 -0
  91. package/lib/module/api/cast/Airplay.js.map +1 -0
  92. package/lib/module/api/cast/CastAPI.js +2 -0
  93. package/lib/module/api/cast/CastAPI.js.map +1 -0
  94. package/lib/module/api/cast/CastConfiguration.js +2 -0
  95. package/lib/module/api/cast/CastConfiguration.js.map +1 -0
  96. package/lib/module/api/cast/CastState.js +2 -0
  97. package/lib/module/api/cast/CastState.js.map +1 -0
  98. package/lib/module/api/cast/Chromecast.js +2 -0
  99. package/lib/module/api/cast/Chromecast.js.map +1 -0
  100. package/lib/module/api/cast/barrel.js +6 -0
  101. package/lib/module/api/cast/barrel.js.map +1 -0
  102. package/lib/module/api/config/PlayerConfiguration.js.map +1 -1
  103. package/lib/module/api/error/ChromecastError.js +2 -0
  104. package/lib/module/api/error/ChromecastError.js.map +1 -0
  105. package/lib/module/api/error/barrel.js +1 -0
  106. package/lib/module/api/error/barrel.js.map +1 -1
  107. package/lib/module/api/event/CastEvent.js +14 -0
  108. package/lib/module/api/event/CastEvent.js.map +1 -0
  109. package/lib/module/api/event/barrel.js +2 -1
  110. package/lib/module/api/event/barrel.js.map +1 -1
  111. package/lib/module/api/source/SourceDescription.js.map +1 -1
  112. package/lib/module/api/source/barrel.js +1 -0
  113. package/lib/module/api/source/barrel.js.map +1 -1
  114. package/lib/module/api/source/metadata/MetadataDescription.js +2 -0
  115. package/lib/module/api/source/metadata/MetadataDescription.js.map +1 -0
  116. package/lib/module/api/source/metadata/barrel.js +2 -0
  117. package/lib/module/api/source/metadata/barrel.js.map +1 -0
  118. package/lib/module/internal/THEOplayerView.js +15 -0
  119. package/lib/module/internal/THEOplayerView.js.map +1 -1
  120. package/lib/module/internal/THEOplayerView.web.js +8 -0
  121. package/lib/module/internal/THEOplayerView.web.js.map +1 -1
  122. package/lib/module/internal/cast/THEOplayerNativeAirplay.js +24 -0
  123. package/lib/module/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
  124. package/lib/module/internal/cast/THEOplayerNativeCastApi.js +34 -0
  125. package/lib/module/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
  126. package/lib/module/internal/cast/THEOplayerNativeChromecast.js +32 -0
  127. package/lib/module/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
  128. package/lib/module/internal/cast/THEOplayerWebCastApi.js +22 -0
  129. package/lib/module/internal/cast/THEOplayerWebCastApi.js.map +1 -0
  130. package/lib/module/internal/web/stub/CastButtonStub.js +6 -0
  131. package/lib/module/internal/web/stub/CastButtonStub.js.map +1 -0
  132. package/lib/typescript/lib/commonjs/api/cast/Airplay.d.ts +1 -0
  133. package/lib/typescript/lib/commonjs/api/cast/CastAPI.d.ts +1 -0
  134. package/lib/typescript/lib/commonjs/api/cast/CastConfiguration.d.ts +0 -0
  135. package/lib/typescript/lib/commonjs/api/cast/CastState.d.ts +0 -0
  136. package/lib/typescript/lib/commonjs/api/cast/Chromecast.d.ts +1 -0
  137. package/lib/typescript/lib/commonjs/api/cast/barrel.d.ts +1 -0
  138. package/lib/typescript/lib/commonjs/api/error/ChromecastError.d.ts +0 -0
  139. package/lib/typescript/lib/commonjs/api/event/CastEvent.d.ts +2 -0
  140. package/lib/typescript/lib/commonjs/api/source/metadata/MetadataDescription.d.ts +0 -0
  141. package/lib/typescript/lib/commonjs/api/source/metadata/barrel.d.ts +1 -0
  142. package/lib/typescript/lib/commonjs/internal/THEOplayerView.d.ts +3 -0
  143. package/lib/typescript/lib/commonjs/internal/THEOplayerView.web.d.ts +3 -0
  144. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
  145. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeCastApi.d.ts +12 -0
  146. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
  147. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerWebCastApi.d.ts +8 -0
  148. package/lib/typescript/lib/commonjs/internal/web/stub/CastButtonStub.d.ts +2 -0
  149. package/lib/typescript/lib/module/api/barrel.d.ts +1 -0
  150. package/lib/typescript/lib/module/api/cast/Airplay.d.ts +1 -0
  151. package/lib/typescript/lib/module/api/cast/CastAPI.d.ts +1 -0
  152. package/lib/typescript/lib/module/api/cast/CastConfiguration.d.ts +0 -0
  153. package/lib/typescript/lib/module/api/cast/CastState.d.ts +0 -0
  154. package/lib/typescript/lib/module/api/cast/Chromecast.d.ts +1 -0
  155. package/lib/typescript/lib/module/api/cast/barrel.d.ts +3 -0
  156. package/lib/typescript/lib/module/api/error/ChromecastError.d.ts +0 -0
  157. package/lib/typescript/lib/module/api/event/CastEvent.d.ts +1 -0
  158. package/lib/typescript/lib/module/api/event/barrel.d.ts +2 -1
  159. package/lib/typescript/lib/module/api/source/barrel.d.ts +1 -0
  160. package/lib/typescript/lib/module/api/source/metadata/MetadataDescription.d.ts +0 -0
  161. package/lib/typescript/lib/module/api/source/metadata/barrel.d.ts +1 -0
  162. package/lib/typescript/lib/module/internal/THEOplayerView.d.ts +3 -0
  163. package/lib/typescript/lib/module/internal/THEOplayerView.web.d.ts +3 -0
  164. package/lib/typescript/lib/module/internal/cast/THEOplayerNativeAirplay.d.ts +8 -0
  165. package/lib/typescript/lib/module/internal/cast/THEOplayerNativeCastApi.d.ts +11 -0
  166. package/lib/typescript/lib/module/internal/cast/THEOplayerNativeChromecast.d.ts +10 -0
  167. package/lib/typescript/lib/module/internal/cast/THEOplayerWebCastApi.d.ts +7 -0
  168. package/lib/typescript/lib/module/internal/web/stub/CastButtonStub.d.ts +2 -0
  169. package/lib/typescript/src/api/THEOplayerView.d.ts +10 -0
  170. package/lib/typescript/src/api/barrel.d.ts +1 -0
  171. package/lib/typescript/src/api/cast/Airplay.d.ts +27 -0
  172. package/lib/typescript/src/api/cast/CastAPI.d.ts +25 -0
  173. package/lib/typescript/src/api/cast/CastConfiguration.d.ts +41 -0
  174. package/lib/typescript/src/api/cast/CastState.d.ts +10 -0
  175. package/lib/typescript/src/api/cast/Chromecast.d.ts +39 -0
  176. package/lib/typescript/src/api/cast/barrel.d.ts +5 -0
  177. package/lib/typescript/src/api/config/PlayerConfiguration.d.ts +6 -1
  178. package/lib/typescript/src/api/error/ChromecastError.d.ts +34 -0
  179. package/lib/typescript/src/api/error/barrel.d.ts +1 -0
  180. package/lib/typescript/src/api/event/CastEvent.d.ts +21 -0
  181. package/lib/typescript/src/api/event/barrel.d.ts +2 -1
  182. package/lib/typescript/src/api/source/SourceDescription.d.ts +7 -0
  183. package/lib/typescript/src/api/source/barrel.d.ts +1 -0
  184. package/lib/typescript/src/api/source/metadata/MetadataDescription.d.ts +12 -0
  185. package/lib/typescript/src/api/source/metadata/barrel.d.ts +1 -0
  186. package/lib/typescript/src/internal/THEOplayerView.d.ts +5 -1
  187. package/lib/typescript/src/internal/THEOplayerView.web.d.ts +3 -1
  188. package/lib/typescript/src/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
  189. package/lib/typescript/src/internal/cast/THEOplayerNativeCastApi.d.ts +10 -0
  190. package/lib/typescript/src/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
  191. package/lib/typescript/src/internal/cast/THEOplayerWebCastApi.d.ts +9 -0
  192. package/lib/typescript/src/internal/web/stub/CastButtonStub.d.ts +3 -0
  193. package/package.json +2 -2
  194. package/react-native-theoplayer.podspec +2 -2
  195. package/src/api/THEOplayerView.ts +12 -0
  196. package/src/api/barrel.ts +1 -0
  197. package/src/api/cast/Airplay.ts +31 -0
  198. package/src/api/cast/CastAPI.ts +30 -0
  199. package/src/api/cast/CastConfiguration.ts +44 -0
  200. package/src/api/cast/CastState.ts +10 -0
  201. package/src/api/cast/Chromecast.ts +45 -0
  202. package/src/api/cast/barrel.ts +5 -0
  203. package/src/api/config/PlayerConfiguration.ts +7 -1
  204. package/src/api/error/ChromecastError.ts +46 -0
  205. package/src/api/error/barrel.ts +1 -0
  206. package/src/api/event/CastEvent.ts +45 -0
  207. package/src/api/event/barrel.ts +2 -1
  208. package/src/api/source/SourceDescription.ts +8 -0
  209. package/src/api/source/barrel.ts +1 -0
  210. package/src/api/source/metadata/MetadataDescription.ts +13 -0
  211. package/src/api/source/metadata/barrel.ts +1 -0
  212. package/src/internal/THEOplayerView.tsx +17 -0
  213. package/src/internal/THEOplayerView.web.tsx +8 -1
  214. package/src/internal/cast/THEOplayerNativeAirplay.ts +22 -0
  215. package/src/internal/cast/THEOplayerNativeCastApi.ts +28 -0
  216. package/src/internal/cast/THEOplayerNativeChromecast.ts +30 -0
  217. package/src/internal/cast/THEOplayerWebCastApi.ts +21 -0
  218. package/src/internal/web/stub/CastButtonStub.tsx +7 -0
  219. package/android/src/main/java/com/theoplayer/PlayerConfigHelper.java +0 -70
  220. package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.java +0 -32
  221. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.java +0 -525
  222. package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.java +0 -127
  223. package/android/src/main/java/com/theoplayer/SourceHelper.java +0 -362
  224. package/android/src/main/java/com/theoplayer/VideoEventEmitter.java +0 -578
  225. package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.java +0 -92
  226. package/android/src/main/java/com/theoplayer/ads/AdInfo.java +0 -168
  227. package/android/src/main/java/com/theoplayer/ads/AdsModule.java +0 -152
  228. package/android/src/main/java/com/theoplayer/track/MediaTrackEventType.java +0 -11
  229. package/android/src/main/java/com/theoplayer/track/MediaTrackType.java +0 -11
  230. package/android/src/main/java/com/theoplayer/track/QualityListAdapter.java +0 -54
  231. package/android/src/main/java/com/theoplayer/track/QualityListFilter.java +0 -40
  232. package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.java +0 -11
  233. package/android/src/main/java/com/theoplayer/track/TrackEventType.java +0 -12
  234. package/android/src/main/java/com/theoplayer/track/TrackListInfo.java +0 -234
  235. package/android/src/main/java/com/theoplayer/util/ViewResolver.java +0 -42
  236. package/ios/custom/react-native-theoplayer_custom_ios.podspec +0 -36
@@ -0,0 +1,648 @@
1
+ package com.theoplayer
2
+
3
+ import android.util.Log
4
+ import android.view.View
5
+ import androidx.annotation.StringDef
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.ReactApplicationContext
8
+ import com.facebook.react.bridge.WritableMap
9
+ import com.facebook.react.uimanager.events.ReactEventEmitter
10
+ import com.theoplayer.ads.AdEventAdapter
11
+ import com.theoplayer.ads.AdEventAdapter.AdEventEmitter
12
+ import com.theoplayer.android.api.error.THEOplayerException
13
+ import com.theoplayer.android.api.event.EventListener
14
+ import com.theoplayer.android.api.event.EventType
15
+ import com.theoplayer.android.api.event.player.*
16
+ import com.theoplayer.android.api.event.track.mediatrack.audio.ActiveQualityChangedEvent
17
+ import com.theoplayer.android.api.event.track.mediatrack.audio.AudioTrackEventTypes
18
+ import com.theoplayer.android.api.event.track.mediatrack.audio.QualityChangedEvent
19
+ import com.theoplayer.android.api.event.track.mediatrack.audio.list.AudioTrackListEventTypes
20
+ import com.theoplayer.android.api.event.track.mediatrack.video.VideoTrackEventTypes
21
+ import com.theoplayer.android.api.event.track.mediatrack.video.list.VideoTrackListEventTypes
22
+ import com.theoplayer.android.api.event.track.texttrack.AddCueEvent
23
+ import com.theoplayer.android.api.event.track.texttrack.RemoveCueEvent
24
+ import com.theoplayer.android.api.event.track.texttrack.TextTrackEventTypes
25
+ import com.theoplayer.android.api.event.track.texttrack.list.AddTrackEvent
26
+ import com.theoplayer.android.api.event.track.texttrack.list.RemoveTrackEvent
27
+ import com.theoplayer.android.api.event.track.texttrack.list.TextTrackListEventTypes
28
+ import com.theoplayer.android.api.event.track.texttrack.list.TrackListChangeEvent
29
+ import com.theoplayer.android.api.event.track.tracklist.TrackListEvent
30
+ import com.theoplayer.android.api.player.Player
31
+ import com.theoplayer.android.api.player.track.mediatrack.MediaTrack
32
+ import com.theoplayer.android.api.player.track.mediatrack.MediaTrackList
33
+ import com.theoplayer.android.api.player.track.mediatrack.quality.AudioQuality
34
+ import com.theoplayer.android.api.player.track.mediatrack.quality.Quality
35
+ import com.theoplayer.android.api.player.track.mediatrack.quality.VideoQuality
36
+ import com.theoplayer.android.api.player.track.texttrack.TextTrack
37
+ import com.theoplayer.cast.CastEventAdapter
38
+ import com.theoplayer.track.*
39
+ import com.theoplayer.util.TypeUtils.encodeInfNan
40
+ import kotlin.math.floor
41
+
42
+ private val TAG = PlayerEventEmitter::class.java.name
43
+
44
+ private const val EVENT_SOURCECHANGE = "onNativeSourceChange"
45
+ private const val EVENT_LOADSTART = "onNativeLoadStart"
46
+ private const val EVENT_LOADEDMETADATA = "onNativeLoadedMetadata"
47
+ private const val EVENT_LOADEDDATA = "onNativeLoadedData"
48
+ private const val EVENT_PLAY = "onNativePlay"
49
+ private const val EVENT_PLAYING = "onNativePlaying"
50
+ private const val EVENT_PAUSE = "onNativePause"
51
+ private const val EVENT_ERROR = "onNativeError"
52
+ private const val EVENT_PROGRESS = "onNativeProgress"
53
+ private const val EVENT_SEEKING = "onNativeSeeking"
54
+ private const val EVENT_SEEKED = "onNativeSeeked"
55
+ private const val EVENT_ENDED = "onNativeEnded"
56
+ private const val EVENT_READYSTATECHANGE = "onNativeReadyStateChange"
57
+ private const val EVENT_TIMEUPDATE = "onNativeTimeUpdate"
58
+ private const val EVENT_DURATIONCHANGE = "onNativeDurationChange"
59
+ private const val EVENT_SEGMENTNOTFOUND = "onNativeSegmentNotFound"
60
+ private const val EVENT_TEXTTRACK_LIST_EVENT = "onNativeTextTrackListEvent"
61
+ private const val EVENT_TEXTTRACK_EVENT = "onNativeTextTrackEvent"
62
+ private const val EVENT_MEDIATRACK_LIST_EVENT = "onNativeMediaTrackListEvent"
63
+ private const val EVENT_MEDIATRACK_EVENT = "onNativeMediaTrackEvent"
64
+ private const val EVENT_AD_EVENT = "onNativeAdEvent"
65
+ private const val EVENT_FULLSCREEN_WILL_PRESENT = "onNativeFullscreenPlayerWillPresent"
66
+ private const val EVENT_FULLSCREEN_DID_PRESENT = "onNativeFullscreenPlayerDidPresent"
67
+ private const val EVENT_FULLSCREEN_WILL_DISMISS = "onNativeFullscreenPlayerWillDismiss"
68
+ private const val EVENT_FULLSCREEN_DID_DISMISS = "onNativeFullscreenPlayerDidDismiss"
69
+ private const val EVENT_CAST_EVENT = "onNativeCastEvent"
70
+
71
+ private const val EVENT_PROP_CURRENT_TIME = "currentTime"
72
+ private const val EVENT_PROP_CURRENT_PROGRAM_DATE_TIME = "currentProgramDateTime"
73
+ private const val EVENT_PROP_DURATION = "duration"
74
+ private const val EVENT_PROP_READYSTATE = "readyState"
75
+ private const val EVENT_PROP_ERROR = "error"
76
+ private const val EVENT_PROP_ERROR_CODE = "errorCode"
77
+ private const val EVENT_PROP_ERROR_MESSAGE = "errorMessage"
78
+ private const val EVENT_PROP_TEXT_TRACKS = "textTracks"
79
+ private const val EVENT_PROP_AUDIO_TRACKS = "audioTracks"
80
+ private const val EVENT_PROP_VIDEO_TRACKS = "videoTracks"
81
+ private const val EVENT_PROP_SELECTED_TEXT_TRACK = "selectedTextTrack"
82
+ private const val EVENT_PROP_SELECTED_AUDIO_TRACK = "selectedAudioTrack"
83
+ private const val EVENT_PROP_SELECTED_VIDEO_TRACK = "selectedVideoTrack"
84
+ private const val EVENT_PROP_SEEKABLE = "seekable"
85
+ private const val EVENT_PROP_START = "start"
86
+ private const val EVENT_PROP_END = "end"
87
+ private const val EVENT_PROP_RETRYCOUNT = "retryCount"
88
+ private const val EVENT_PROP_SEGMENTSTARTTIME = "segmentStartTime"
89
+ private const val EVENT_PROP_TRACK = "track"
90
+ private const val EVENT_PROP_TRACK_UID = "trackUid"
91
+ private const val EVENT_PROP_TRACK_TYPE = "trackType"
92
+ private const val EVENT_PROP_CUE = "cue"
93
+ private const val EVENT_PROP_TYPE = "type"
94
+ private const val EVENT_PROP_QUALITIES = "qualities"
95
+
96
+ @Suppress("UNCHECKED_CAST")
97
+ class PlayerEventEmitter internal constructor(
98
+ reactContext: ReactApplicationContext,
99
+ playerView: ReactTHEOplayerView
100
+ ) {
101
+ @Retention(AnnotationRetention.SOURCE)
102
+ @StringDef(
103
+ EVENT_SOURCECHANGE,
104
+ EVENT_LOADSTART,
105
+ EVENT_LOADEDMETADATA,
106
+ EVENT_LOADEDDATA,
107
+ EVENT_PLAY,
108
+ EVENT_PLAYING,
109
+ EVENT_PAUSE,
110
+ EVENT_ERROR,
111
+ EVENT_PROGRESS,
112
+ EVENT_SEEKING,
113
+ EVENT_SEEKED,
114
+ EVENT_ENDED,
115
+ EVENT_READYSTATECHANGE,
116
+ EVENT_TIMEUPDATE,
117
+ EVENT_DURATIONCHANGE,
118
+ EVENT_SEGMENTNOTFOUND,
119
+ EVENT_TEXTTRACK_LIST_EVENT,
120
+ EVENT_TEXTTRACK_EVENT,
121
+ EVENT_MEDIATRACK_LIST_EVENT,
122
+ EVENT_MEDIATRACK_EVENT,
123
+ EVENT_AD_EVENT,
124
+ EVENT_FULLSCREEN_WILL_PRESENT,
125
+ EVENT_FULLSCREEN_DID_PRESENT,
126
+ EVENT_FULLSCREEN_WILL_DISMISS,
127
+ EVENT_FULLSCREEN_DID_DISMISS,
128
+ EVENT_CAST_EVENT
129
+ )
130
+ annotation class VideoEvents
131
+
132
+ companion object {
133
+
134
+ @JvmField
135
+ val Events = arrayOf(
136
+ EVENT_SOURCECHANGE,
137
+ EVENT_LOADSTART,
138
+ EVENT_LOADEDMETADATA,
139
+ EVENT_LOADEDDATA,
140
+ EVENT_PLAY,
141
+ EVENT_PLAYING,
142
+ EVENT_PAUSE,
143
+ EVENT_ERROR,
144
+ EVENT_PROGRESS,
145
+ EVENT_SEEKING,
146
+ EVENT_SEEKED,
147
+ EVENT_ENDED,
148
+ EVENT_READYSTATECHANGE,
149
+ EVENT_TIMEUPDATE,
150
+ EVENT_DURATIONCHANGE,
151
+ EVENT_SEGMENTNOTFOUND,
152
+ EVENT_TEXTTRACK_LIST_EVENT,
153
+ EVENT_TEXTTRACK_EVENT,
154
+ EVENT_MEDIATRACK_LIST_EVENT,
155
+ EVENT_MEDIATRACK_EVENT,
156
+ EVENT_AD_EVENT,
157
+ EVENT_FULLSCREEN_WILL_PRESENT,
158
+ EVENT_FULLSCREEN_DID_PRESENT,
159
+ EVENT_FULLSCREEN_WILL_DISMISS,
160
+ EVENT_FULLSCREEN_DID_DISMISS,
161
+ EVENT_CAST_EVENT
162
+ )
163
+ }
164
+
165
+ private val eventEmitter: ReactEventEmitter
166
+ private var viewId = View.NO_ID
167
+ private val playerListeners = HashMap<EventType<*>, EventListener<*>>()
168
+ private val textTrackListeners = HashMap<EventType<*>, EventListener<*>>()
169
+ private val audioTrackListeners = HashMap<EventType<*>, EventListener<*>>()
170
+ private val videoTrackListeners = HashMap<EventType<*>, EventListener<*>>()
171
+ private val playerView: ReactTHEOplayerView
172
+ private val trackListAdapter = TrackListAdapter()
173
+ private var adEventAdapter: AdEventAdapter? = null
174
+ private var castEventAdapter: CastEventAdapter? = null
175
+ private var lastTimeUpdate: Long = 0
176
+ private var lastCurrentTime = 0.0
177
+
178
+ init {
179
+ eventEmitter = ReactEventEmitter(reactContext)
180
+ this.playerView = playerView
181
+
182
+ // Create listeners
183
+ playerListeners[PlayerEventTypes.SOURCECHANGE] = EventListener<PlayerEvent<*>> {
184
+ receiveEvent(EVENT_SOURCECHANGE, null)
185
+ }
186
+ playerListeners[PlayerEventTypes.LOADSTART] = EventListener<PlayerEvent<*>> {
187
+ receiveEvent(EVENT_LOADSTART, null)
188
+ }
189
+ playerListeners[PlayerEventTypes.LOADEDMETADATA] =
190
+ EventListener<PlayerEvent<*>> { onLoadedMetadata() }
191
+ playerListeners[PlayerEventTypes.LOADEDDATA] = EventListener<PlayerEvent<*>> {
192
+ receiveEvent(EVENT_LOADEDDATA, null)
193
+ }
194
+ playerListeners[PlayerEventTypes.PLAY] = EventListener<PlayerEvent<*>> {
195
+ receiveEvent(EVENT_PLAY, null)
196
+ }
197
+ playerListeners[PlayerEventTypes.PLAYING] = EventListener<PlayerEvent<*>> {
198
+ receiveEvent(EVENT_PLAYING, null)
199
+ }
200
+ playerListeners[PlayerEventTypes.READYSTATECHANGE] =
201
+ EventListener { event: ReadyStateChangeEvent -> onReadyState(event) }
202
+ playerListeners[PlayerEventTypes.SEEKING] =
203
+ EventListener { event: SeekingEvent -> onSeeking(event) }
204
+ playerListeners[PlayerEventTypes.SEEKED] =
205
+ EventListener { event: SeekedEvent -> onSeeked(event) }
206
+ playerListeners[PlayerEventTypes.ERROR] =
207
+ EventListener { event: ErrorEvent -> onError(event) }
208
+ playerListeners[PlayerEventTypes.ENDED] =
209
+ EventListener<PlayerEvent<*>> { receiveEvent(EVENT_ENDED, null) }
210
+ playerListeners[PlayerEventTypes.PROGRESS] = EventListener<PlayerEvent<*>> { onProgress() }
211
+ playerListeners[PlayerEventTypes.TIMEUPDATE] =
212
+ EventListener { event: TimeUpdateEvent -> onTimeUpdate(event) }
213
+ playerListeners[PlayerEventTypes.DURATIONCHANGE] =
214
+ EventListener { event: DurationChangeEvent -> onDurationChange(event) }
215
+ playerListeners[PlayerEventTypes.PAUSE] = EventListener<PlayerEvent<*>> { onPause() }
216
+ playerListeners[PlayerEventTypes.SEGMENTNOTFOUND] =
217
+ EventListener { event: SegmentNotFoundEvent -> onSegmentNotFound(event) }
218
+ textTrackListeners[TextTrackListEventTypes.ADDTRACK] =
219
+ EventListener { event: AddTrackEvent -> onTextTrackAdd(event) }
220
+ textTrackListeners[TextTrackListEventTypes.REMOVETRACK] =
221
+ EventListener { event: RemoveTrackEvent -> onTextTrackRemove(event) }
222
+ textTrackListeners[TextTrackListEventTypes.TRACKLISTCHANGE] =
223
+ EventListener { event: TrackListChangeEvent -> onTextTrackChange(event) }
224
+ audioTrackListeners[AudioTrackListEventTypes.ADDTRACK] =
225
+ EventListener { event: com.theoplayer.android.api.event.track.mediatrack.audio.list.AddTrackEvent ->
226
+ onAudioTrackAdd(event)
227
+ }
228
+ audioTrackListeners[AudioTrackListEventTypes.REMOVETRACK] =
229
+ EventListener { event: com.theoplayer.android.api.event.track.mediatrack.audio.list.RemoveTrackEvent ->
230
+ onAudioTrackRemove(event)
231
+ }
232
+ audioTrackListeners[AudioTrackListEventTypes.TRACKLISTCHANGE] =
233
+ EventListener { event: com.theoplayer.android.api.event.track.mediatrack.audio.list.TrackListChangeEvent ->
234
+ onAudioTrackChange(event)
235
+ }
236
+ videoTrackListeners[VideoTrackListEventTypes.ADDTRACK] =
237
+ EventListener { event: com.theoplayer.android.api.event.track.mediatrack.video.list.AddTrackEvent ->
238
+ onVideoTrackAdd(event)
239
+ }
240
+ videoTrackListeners[VideoTrackListEventTypes.REMOVETRACK] =
241
+ EventListener { event: com.theoplayer.android.api.event.track.mediatrack.video.list.RemoveTrackEvent ->
242
+ onVideoTrackRemove(event)
243
+ }
244
+ videoTrackListeners[VideoTrackListEventTypes.TRACKLISTCHANGE] =
245
+ EventListener { event: com.theoplayer.android.api.event.track.mediatrack.video.list.TrackListChangeEvent ->
246
+ onVideoTrackChange(event)
247
+ }
248
+ }
249
+
250
+ fun setViewId(viewId: Int) {
251
+ this.viewId = viewId
252
+ }
253
+
254
+ fun emitError(exception: THEOplayerException) {
255
+ emitError(exception.code.name, exception.message)
256
+ }
257
+
258
+ private fun emitError(code: String, message: String?) {
259
+ val error = Arguments.createMap()
260
+ error.putString(EVENT_PROP_ERROR_CODE, code)
261
+ error.putString(EVENT_PROP_ERROR_MESSAGE, message ?: "")
262
+ val payload = Arguments.createMap()
263
+ payload.putMap(EVENT_PROP_ERROR, error)
264
+ receiveEvent(EVENT_ERROR, payload)
265
+ }
266
+
267
+ private fun onLoadedMetadata() {
268
+ val payload = Arguments.createMap()
269
+ payload.putArray(EVENT_PROP_TEXT_TRACKS, playerView.textTrackInfo)
270
+ payload.putArray(EVENT_PROP_AUDIO_TRACKS, playerView.audioTrackInfo)
271
+ payload.putArray(EVENT_PROP_VIDEO_TRACKS, playerView.videoTrackInfo)
272
+ val selectedTextTrack = playerView.selectedTextTrack
273
+ if (selectedTextTrack != null) {
274
+ payload.putInt(EVENT_PROP_SELECTED_TEXT_TRACK, selectedTextTrack.uid)
275
+ }
276
+ val selectedAudioTrack = playerView.selectedAudioTrack
277
+ if (selectedAudioTrack != null) {
278
+ payload.putInt(EVENT_PROP_SELECTED_AUDIO_TRACK, selectedAudioTrack.uid)
279
+ }
280
+ val selectedVideoTrack = playerView.selectedVideoTrack
281
+ if (selectedVideoTrack != null) {
282
+ payload.putInt(EVENT_PROP_SELECTED_VIDEO_TRACK, selectedVideoTrack.uid)
283
+ }
284
+ payload.putDouble(EVENT_PROP_DURATION, playerView.duration)
285
+ receiveEvent(EVENT_LOADEDMETADATA, payload)
286
+ }
287
+
288
+ private fun onSeeking(event: SeekingEvent) {
289
+ val payload = Arguments.createMap()
290
+ payload.putDouble(EVENT_PROP_CURRENT_TIME, (1e03 * event.currentTime).toLong().toDouble())
291
+ receiveEvent(EVENT_SEEKING, payload)
292
+ }
293
+
294
+ private fun onSeeked(event: SeekedEvent) {
295
+ val payload = Arguments.createMap()
296
+ payload.putDouble(EVENT_PROP_CURRENT_TIME, (1e03 * event.currentTime).toLong().toDouble())
297
+ receiveEvent(EVENT_SEEKED, payload)
298
+ }
299
+
300
+ private fun shouldSkipTimeUpdate(now: Long, currentTime: Double): Boolean {
301
+ val timeUpdateRate = BuildConfig.TIMEUPDATE_RATE
302
+
303
+ // No limited update rate.
304
+ if (timeUpdateRate == TimeUpdateRate.UNLIMITED) {
305
+ return false
306
+ }
307
+
308
+ // Try to align updates on second boundary.
309
+ if (floor(lastCurrentTime) != floor(currentTime)) {
310
+ return false
311
+ }
312
+
313
+ // Limit update rate.
314
+ val dt = now - lastTimeUpdate
315
+ return timeUpdateRate == TimeUpdateRate.LIMITED_ONE_HZ && dt < 1e03 ||
316
+ timeUpdateRate == TimeUpdateRate.LIMITED_TWO_HZ && dt < 500 ||
317
+ timeUpdateRate == TimeUpdateRate.LIMITED_THREE_HZ && dt < 333
318
+ }
319
+
320
+ private fun onPause() {
321
+ val player = playerView.player
322
+ // Do not forward the pause event in case the content player is paused because the ad player starts.
323
+ if (player != null && !playerView.adsApi.isPlaying) {
324
+ receiveEvent(EVENT_PAUSE, null)
325
+ }
326
+ }
327
+
328
+ private fun onTimeUpdate(event: TimeUpdateEvent) {
329
+ val now = System.currentTimeMillis()
330
+ val currentTime = event.currentTime
331
+
332
+ // Check for limited timeUpdates
333
+ if (shouldSkipTimeUpdate(now, currentTime)) {
334
+ return
335
+ }
336
+ lastTimeUpdate = now
337
+ lastCurrentTime = currentTime
338
+ val payload = Arguments.createMap()
339
+ payload.putDouble(EVENT_PROP_CURRENT_TIME, (1e03 * currentTime).toLong().toDouble())
340
+ val currentProgramDateTime = event.currentProgramDateTime
341
+ if (currentProgramDateTime != null) {
342
+ payload.putDouble(
343
+ EVENT_PROP_CURRENT_PROGRAM_DATE_TIME,
344
+ (1e03 * currentProgramDateTime.time).toLong().toDouble()
345
+ )
346
+ }
347
+ receiveEvent(EVENT_TIMEUPDATE, payload)
348
+ }
349
+
350
+ private fun onReadyState(event: ReadyStateChangeEvent) {
351
+ val payload = Arguments.createMap()
352
+ payload.putInt(EVENT_PROP_READYSTATE, event.readyState.ordinal)
353
+ receiveEvent(EVENT_READYSTATECHANGE, payload)
354
+ }
355
+
356
+ private fun onDurationChange(event: DurationChangeEvent) {
357
+ val payload = Arguments.createMap()
358
+ payload.putDouble(EVENT_PROP_DURATION, encodeInfNan(1e03 * event.duration))
359
+ receiveEvent(EVENT_DURATIONCHANGE, payload)
360
+ }
361
+
362
+ private fun onError(event: ErrorEvent) {
363
+ emitError(event.errorObject)
364
+ }
365
+
366
+ private fun onProgress() {
367
+ val timeRanges = playerView.getSeekableRange()
368
+ val payload = Arguments.createMap()
369
+ if (timeRanges != null) {
370
+ val seekable = Arguments.createArray()
371
+ for (i in 0 until timeRanges.length()) {
372
+ val range = Arguments.createMap()
373
+ range.putDouble(EVENT_PROP_START, 1e03 * timeRanges.getStart(i))
374
+ range.putDouble(EVENT_PROP_END, 1e03 * timeRanges.getEnd(i))
375
+ seekable.pushMap(range)
376
+ }
377
+ payload.putArray(EVENT_PROP_SEEKABLE, seekable)
378
+ }
379
+ receiveEvent(EVENT_PROGRESS, payload)
380
+ }
381
+
382
+ private fun onSegmentNotFound(event: SegmentNotFoundEvent) {
383
+ val payload = Arguments.createMap()
384
+ payload.putDouble(EVENT_PROP_SEGMENTSTARTTIME, 1e03 * event.segmentStartTime)
385
+ payload.putString(EVENT_PROP_ERROR, event.error)
386
+ payload.putInt(EVENT_PROP_RETRYCOUNT, event.retryCount)
387
+ receiveEvent(EVENT_SEGMENTNOTFOUND, payload)
388
+ }
389
+
390
+ private fun dispatchTextTrackEvent(eventType: TrackEventType, textTrack: TextTrack) {
391
+ val payload = Arguments.createMap()
392
+ payload.putMap(EVENT_PROP_TRACK, playerView.getTextTrackInfo(textTrack))
393
+ payload.putInt(EVENT_PROP_TYPE, eventType.type)
394
+ when (eventType) {
395
+ TrackEventType.ADD_TRACK -> {
396
+ textTrack.addEventListener(TextTrackEventTypes.ADDCUE) { event: AddCueEvent ->
397
+ onTextTrackAddCue(event)
398
+ }
399
+ textTrack.addEventListener(TextTrackEventTypes.REMOVECUE) { event: RemoveCueEvent ->
400
+ onTextTrackRemoveCue(event)
401
+ }
402
+ }
403
+ TrackEventType.REMOVE_TRACK -> {
404
+ textTrack.removeEventListener(TextTrackEventTypes.ADDCUE) { event: AddCueEvent ->
405
+ onTextTrackAddCue(event)
406
+ }
407
+ textTrack.removeEventListener(TextTrackEventTypes.REMOVECUE) { event: RemoveCueEvent ->
408
+ onTextTrackRemoveCue(event)
409
+ }
410
+ }
411
+ else -> {
412
+ // Ignore
413
+ }
414
+ }
415
+ receiveEvent(EVENT_TEXTTRACK_LIST_EVENT, payload)
416
+ }
417
+
418
+ private fun onTextTrackAdd(event: AddTrackEvent) {
419
+ dispatchTextTrackEvent(TrackEventType.ADD_TRACK, event.track)
420
+ }
421
+
422
+ private fun onTextTrackRemove(event: RemoveTrackEvent) {
423
+ dispatchTextTrackEvent(TrackEventType.REMOVE_TRACK, event.track)
424
+ }
425
+
426
+ private fun onTextTrackChange(event: TrackListChangeEvent) {
427
+ dispatchTextTrackEvent(TrackEventType.CHANGE_TRACK, event.track)
428
+ }
429
+
430
+ private fun onTextTrackAddCue(event: AddCueEvent) {
431
+ val payload = Arguments.createMap()
432
+ payload.putInt(EVENT_PROP_TRACK_UID, event.track.uid)
433
+ payload.putInt(EVENT_PROP_TYPE, TextTrackCueEventType.ADD_CUE.type)
434
+ payload.putMap(EVENT_PROP_CUE, playerView.getTextTrackCueInfo(event.cue))
435
+ receiveEvent(EVENT_TEXTTRACK_EVENT, payload)
436
+ }
437
+
438
+ private fun onTextTrackRemoveCue(event: RemoveCueEvent) {
439
+ val payload = Arguments.createMap()
440
+ payload.putInt(EVENT_PROP_TRACK_UID, event.track.uid)
441
+ payload.putInt(EVENT_PROP_TYPE, TextTrackCueEventType.REMOVE_CUE.type)
442
+ payload.putMap(EVENT_PROP_CUE, playerView.getTextTrackCueInfo(event.cue))
443
+ receiveEvent(EVENT_TEXTTRACK_EVENT, payload)
444
+ }
445
+
446
+ private fun activeAudioTrack(): MediaTrack<AudioQuality>? {
447
+ return if (playerView.player != null) activeTrack(
448
+ playerView.player!!.audioTracks
449
+ ) else null
450
+ }
451
+
452
+ private fun activeVideoTrack(): MediaTrack<VideoQuality>? {
453
+ return if (playerView.player != null) activeTrack(
454
+ playerView.player!!.videoTracks
455
+ ) else null
456
+ }
457
+
458
+ private fun <T : Quality?> activeTrack(tracks: MediaTrackList<T>): MediaTrack<T>? {
459
+ for (i in 0 until tracks.length()) {
460
+ val track = tracks.getItem(i)
461
+ if (track.isEnabled) {
462
+ return track
463
+ }
464
+ }
465
+ return null
466
+ }
467
+
468
+ private fun onActiveQualityChanged(event: QualityChangedEvent<*, *>) {
469
+ val quality = event.quality
470
+ val trackType = if (quality is AudioQuality) MediaTrackType.AUDIO else MediaTrackType.VIDEO
471
+ val payload = Arguments.createMap()
472
+ payload.putInt(EVENT_PROP_TYPE, MediaTrackEventType.ACTIVE_QUALITY_CHANGED.type)
473
+ payload.putInt(EVENT_PROP_TRACK_TYPE, trackType.type)
474
+ val activeTrack =
475
+ if (trackType === MediaTrackType.AUDIO) activeAudioTrack() else activeVideoTrack()
476
+ if (activeTrack != null) {
477
+ payload.putInt(EVENT_PROP_TRACK_UID, activeTrack.uid)
478
+ }
479
+ val qualities = Arguments.createArray()
480
+ qualities.pushMap(trackListAdapter.fromQuality(quality))
481
+ payload.putArray(EVENT_PROP_QUALITIES, qualities)
482
+ receiveEvent(EVENT_MEDIATRACK_EVENT, payload)
483
+ }
484
+
485
+ private fun <Q : Quality?> dispatchMediaTrackEvent(
486
+ eventType: TrackEventType,
487
+ trackType: MediaTrackType,
488
+ track: MediaTrack<Q>
489
+ ) {
490
+ val payload = Arguments.createMap()
491
+ payload.putInt(EVENT_PROP_TYPE, eventType.type)
492
+ payload.putInt(EVENT_PROP_TRACK_TYPE, trackType.type)
493
+ payload.putMap(EVENT_PROP_TRACK, trackListAdapter.fromMediaTrack(track, trackType))
494
+ val qualityChangedEventType =
495
+ (if (trackType === MediaTrackType.AUDIO)
496
+ AudioTrackEventTypes.ACTIVEQUALITYCHANGEDEVENT
497
+ else VideoTrackEventTypes.ACTIVEQUALITYCHANGEDEVENT) as EventType<QualityChangedEvent<Q, ActiveQualityChangedEvent>>
498
+ when (eventType) {
499
+ TrackEventType.ADD_TRACK -> track.addEventListener(qualityChangedEventType) { event: QualityChangedEvent<Q, ActiveQualityChangedEvent> ->
500
+ onActiveQualityChanged(event)
501
+ }
502
+ TrackEventType.REMOVE_TRACK -> track.removeEventListener(qualityChangedEventType) { event: QualityChangedEvent<Q, ActiveQualityChangedEvent> ->
503
+ onActiveQualityChanged(event)
504
+ }
505
+ else -> { /* ignore */
506
+ }
507
+ }
508
+ receiveEvent(EVENT_MEDIATRACK_LIST_EVENT, payload)
509
+ }
510
+
511
+ private fun onAudioTrackAdd(event: com.theoplayer.android.api.event.track.mediatrack.audio.list.AddTrackEvent) {
512
+ dispatchMediaTrackEvent(TrackEventType.ADD_TRACK, MediaTrackType.AUDIO, event.track)
513
+ }
514
+
515
+ private fun onVideoTrackAdd(event: com.theoplayer.android.api.event.track.mediatrack.video.list.AddTrackEvent) {
516
+ dispatchMediaTrackEvent(TrackEventType.ADD_TRACK, MediaTrackType.VIDEO, event.track)
517
+ }
518
+
519
+ private fun onAudioTrackRemove(event: com.theoplayer.android.api.event.track.mediatrack.audio.list.RemoveTrackEvent) {
520
+ dispatchMediaTrackEvent(TrackEventType.REMOVE_TRACK, MediaTrackType.AUDIO, event.track)
521
+ }
522
+
523
+ private fun onVideoTrackRemove(event: com.theoplayer.android.api.event.track.mediatrack.video.list.RemoveTrackEvent) {
524
+ dispatchMediaTrackEvent(TrackEventType.REMOVE_TRACK, MediaTrackType.VIDEO, event.track)
525
+ }
526
+
527
+ private fun onAudioTrackChange(event: com.theoplayer.android.api.event.track.mediatrack.audio.list.TrackListChangeEvent) {
528
+ dispatchMediaTrackEvent(TrackEventType.CHANGE_TRACK, MediaTrackType.AUDIO, event.track)
529
+ }
530
+
531
+ private fun onVideoTrackChange(event: com.theoplayer.android.api.event.track.mediatrack.video.list.TrackListChangeEvent) {
532
+ dispatchMediaTrackEvent(TrackEventType.CHANGE_TRACK, MediaTrackType.VIDEO, event.track)
533
+ }
534
+
535
+ fun onFullscreenWillPresent() {
536
+ receiveEvent(EVENT_FULLSCREEN_WILL_PRESENT, null)
537
+ }
538
+
539
+ fun onFullscreenDidPresent() {
540
+ receiveEvent(EVENT_FULLSCREEN_DID_PRESENT, null)
541
+ }
542
+
543
+ fun onFullscreenWillDismiss() {
544
+ receiveEvent(EVENT_FULLSCREEN_WILL_DISMISS, null)
545
+ }
546
+
547
+ fun onFullscreenDidDismiss() {
548
+ receiveEvent(EVENT_FULLSCREEN_DID_DISMISS, null)
549
+ }
550
+
551
+ private fun receiveEvent(@VideoEvents type: String, event: WritableMap?) {
552
+ if (BuildConfig.LOG_PLAYER_EVENTS) {
553
+ try {
554
+ Log.d(TAG, "receiveEvent $type $event")
555
+ } catch (ignore: RuntimeException) {
556
+ }
557
+ }
558
+ eventEmitter.receiveEvent(viewId, type, event)
559
+ }
560
+
561
+ fun attachListeners(player: Player) {
562
+ // Attach player listeners
563
+ for ((key, value) in playerListeners) {
564
+ player.addEventListener(
565
+ key as EventType<PlayerEvent<*>>,
566
+ value as EventListener<PlayerEvent<*>>
567
+ )
568
+ }
569
+
570
+ // Attach text track listeners
571
+ for ((key, value) in textTrackListeners) {
572
+ player.textTracks.addEventListener(
573
+ key as EventType<TrackListEvent<*, *>>,
574
+ value as EventListener<TrackListEvent<*, *>>
575
+ )
576
+ }
577
+
578
+ // Attach audio track listeners
579
+ for ((key, value) in audioTrackListeners) {
580
+ player.audioTracks.addEventListener(
581
+ key as EventType<TrackListEvent<*, *>>,
582
+ value as EventListener<TrackListEvent<*, *>>
583
+ )
584
+ }
585
+
586
+ // Attach video track listeners
587
+ for ((key, value) in videoTrackListeners) {
588
+ player.videoTracks.addEventListener(
589
+ key as EventType<TrackListEvent<*, *>>,
590
+ value as EventListener<TrackListEvent<*, *>>
591
+ )
592
+ }
593
+
594
+ // Attach AdStateHolder
595
+ if (BuildConfig.EXTENSION_ADS) {
596
+ adEventAdapter = AdEventAdapter(playerView.adsApi,
597
+ object : AdEventEmitter {
598
+ override fun emit(payload: WritableMap?) {
599
+ receiveEvent(EVENT_AD_EVENT, payload)
600
+ }
601
+ })
602
+ }
603
+ if (BuildConfig.EXTENSION_CAST && playerView.castApi != null) {
604
+ castEventAdapter = CastEventAdapter(playerView.castApi!!,
605
+ object : CastEventAdapter.Emitter {
606
+ override fun emit(payload: WritableMap?) {
607
+ receiveEvent(EVENT_CAST_EVENT, payload)
608
+ }
609
+ })
610
+ }
611
+ }
612
+
613
+ fun removeListeners(player: Player) {
614
+ // Remove player listeners
615
+ for ((key, value) in playerListeners) {
616
+ player.removeEventListener(
617
+ key as EventType<PlayerEvent<*>>,
618
+ value as EventListener<PlayerEvent<*>>
619
+ )
620
+ }
621
+
622
+ // Remove text track listeners
623
+ for ((key, value) in textTrackListeners) {
624
+ player.textTracks.removeEventListener(
625
+ key as EventType<TrackListEvent<*, *>>,
626
+ value as EventListener<TrackListEvent<*, *>>
627
+ )
628
+ }
629
+
630
+ // Remove audio track listeners
631
+ for ((key, value) in audioTrackListeners) {
632
+ player.audioTracks.removeEventListener(
633
+ key as EventType<TrackListEvent<*, *>>,
634
+ value as EventListener<TrackListEvent<*, *>>
635
+ )
636
+ }
637
+
638
+ // Remove video track listeners
639
+ for ((key, value) in videoTrackListeners) {
640
+ player.videoTracks.removeEventListener(
641
+ key as EventType<TrackListEvent<*, *>>,
642
+ value as EventListener<TrackListEvent<*, *>>
643
+ )
644
+ }
645
+ castEventAdapter?.destroy()
646
+ adEventAdapter?.destroy()
647
+ }
648
+ }
@@ -0,0 +1,23 @@
1
+ package com.theoplayer
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.NativeModule
6
+ import com.facebook.react.uimanager.ViewManager
7
+ import com.theoplayer.ads.AdsModule
8
+ import com.theoplayer.drm.ContentProtectionModule
9
+ import com.theoplayer.cast.CastModule
10
+
11
+ class ReactTHEOplayerPackage : ReactPackage {
12
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
13
+ return listOf(
14
+ AdsModule(reactContext),
15
+ ContentProtectionModule(reactContext),
16
+ CastModule(reactContext)
17
+ )
18
+ }
19
+
20
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
21
+ return listOf<ViewManager<*, *>>(ReactTHEOplayerViewManager())
22
+ }
23
+ }