spactureai-mobile-player 1.0.30

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 (492) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +474 -0
  3. package/UnifiedPlayer.podspec +51 -0
  4. package/android/CMakeLists.txt +29 -0
  5. package/android/build.gradle +249 -0
  6. package/android/fix-prefab.gradle +51 -0
  7. package/android/gradle.properties +15 -0
  8. package/android/src/main/AndroidManifest.xml +10 -0
  9. package/android/src/main/AndroidManifestNew.xml +9 -0
  10. package/android/src/main/cpp/cpp-adapter.cpp +9 -0
  11. package/android/src/main/java/com/unifiedplayer/core/AudioFocusManager.kt +233 -0
  12. package/android/src/main/java/com/unifiedplayer/core/VideoError.kt +105 -0
  13. package/android/src/main/java/com/unifiedplayer/core/VideoManager.kt +292 -0
  14. package/android/src/main/java/com/unifiedplayer/core/extensions/ResizeMode+AspectRatioFrameLayout.kt +20 -0
  15. package/android/src/main/java/com/unifiedplayer/core/extensions/SubtitleType+toString.kt +14 -0
  16. package/android/src/main/java/com/unifiedplayer/core/extensions/VideoPlaybackService+ServiceManagment.kt +59 -0
  17. package/android/src/main/java/com/unifiedplayer/core/fragments/FullscreenVideoFragment.kt +346 -0
  18. package/android/src/main/java/com/unifiedplayer/core/fragments/PictureInPictureHelperFragment.kt +85 -0
  19. package/android/src/main/java/com/unifiedplayer/core/player/DRMManagerSpec.kt +23 -0
  20. package/android/src/main/java/com/unifiedplayer/core/player/DataSourceFactoryUtils.kt +93 -0
  21. package/android/src/main/java/com/unifiedplayer/core/player/MediaItemUtils.kt +141 -0
  22. package/android/src/main/java/com/unifiedplayer/core/player/MediaSourceUtils.kt +134 -0
  23. package/android/src/main/java/com/unifiedplayer/core/player/OnAudioFocusChangedListener.kt +25 -0
  24. package/android/src/main/java/com/unifiedplayer/core/plugins/PluginsRegistry.kt +223 -0
  25. package/android/src/main/java/com/unifiedplayer/core/plugins/ReactNativeVideoPlugin.kt +173 -0
  26. package/android/src/main/java/com/unifiedplayer/core/recivers/AudioBecomingNoisyReceiver.kt +38 -0
  27. package/android/src/main/java/com/unifiedplayer/core/services/playback/CustomMediaNotificationProvider.kt +151 -0
  28. package/android/src/main/java/com/unifiedplayer/core/services/playback/VideoPlaybackCallback.kt +96 -0
  29. package/android/src/main/java/com/unifiedplayer/core/services/playback/VideoPlaybackService.kt +219 -0
  30. package/android/src/main/java/com/unifiedplayer/core/services/playback/VideoPlaybackServiceConnection.kt +59 -0
  31. package/android/src/main/java/com/unifiedplayer/core/utils/PictureInPictureUtils.kt +153 -0
  32. package/android/src/main/java/com/unifiedplayer/core/utils/SmallVideoPlayerOptimizer.kt +157 -0
  33. package/android/src/main/java/com/unifiedplayer/core/utils/SourceLoader.kt +48 -0
  34. package/android/src/main/java/com/unifiedplayer/core/utils/TextTrackUtils.kt +175 -0
  35. package/android/src/main/java/com/unifiedplayer/core/utils/Threading.kt +75 -0
  36. package/android/src/main/java/com/unifiedplayer/core/utils/VideoFileHelper.kt +51 -0
  37. package/android/src/main/java/com/unifiedplayer/core/utils/VideoInformationUtils.kt +67 -0
  38. package/android/src/main/java/com/unifiedplayer/core/utils/VideoOrientationUtils.kt +30 -0
  39. package/android/src/main/java/com/unifiedplayer/hybrids/videoplayer/HybridVideoPlayer.kt +732 -0
  40. package/android/src/main/java/com/unifiedplayer/hybrids/videoplayer/HybridVideoPlayerFactory.kt +16 -0
  41. package/android/src/main/java/com/unifiedplayer/hybrids/videoplayereventemitter/HybridVideoPlayerEventEmitter.kt +180 -0
  42. package/android/src/main/java/com/unifiedplayer/hybrids/videoplayersource/HybridVideoPlayerSource.kt +67 -0
  43. package/android/src/main/java/com/unifiedplayer/hybrids/videoplayersource/HybridVideoPlayerSourceFactory.kt +58 -0
  44. package/android/src/main/java/com/unifiedplayer/hybrids/videoviewviewmanager/HybridVideoViewViewManager.kt +187 -0
  45. package/android/src/main/java/com/unifiedplayer/hybrids/videoviewviewmanager/HybridVideoViewViewManagerFactory.kt +13 -0
  46. package/android/src/main/java/com/unifiedplayer/react/VideoPackage.kt +25 -0
  47. package/android/src/main/java/com/unifiedplayer/react/VideoViewViewManager.kt +78 -0
  48. package/android/src/main/java/com/unifiedplayer/view/VideoView.kt +565 -0
  49. package/android/src/main/res/layout/custom_player_control_view.xml +82 -0
  50. package/android/src/main/res/layout/player_view_surface.xml +13 -0
  51. package/android/src/main/res/layout/player_view_texture.xml +13 -0
  52. package/android/src/paper/java/com/facebook/react/viewmanagers/RNCVideoViewManagerDelegate.java +32 -0
  53. package/android/src/paper/java/com/facebook/react/viewmanagers/RNCVideoViewManagerInterface.java +16 -0
  54. package/android/src/stubs/dash/androidx/media3/exoplayer/dash/DashMediaSource.kt +35 -0
  55. package/android/src/stubs/dash/androidx/media3/exoplayer/dash/DashUtil.kt +11 -0
  56. package/android/src/stubs/dash/androidx/media3/exoplayer/dash/manifest/AdaptationSet.kt +9 -0
  57. package/android/src/stubs/dash/androidx/media3/exoplayer/dash/manifest/DashManifest.kt +10 -0
  58. package/android/src/stubs/dash/androidx/media3/exoplayer/dash/manifest/Period.kt +7 -0
  59. package/android/src/stubs/dash/androidx/media3/exoplayer/dash/manifest/Representation.kt +8 -0
  60. package/android/src/stubs/hls/androidx/media3/exoplayer/hls/HlsMediaSource.kt +33 -0
  61. package/ios/RNCVideoViewManager.mm +39 -0
  62. package/ios/Video-Bridging-Header.h +2 -0
  63. package/ios/core/HLSAuthProxy.swift +428 -0
  64. package/ios/core/VideoError.swift +164 -0
  65. package/ios/core/VideoManager.swift +219 -0
  66. package/ios/hybrids/VideoPlayer/HybridVideoPlayer.swift +697 -0
  67. package/ios/hybrids/VideoPlayer/HybridVideoPlayerFactory.swift +15 -0
  68. package/ios/hybrids/VideoPlayer/VLCPlaybackDelegates.swift +58 -0
  69. package/ios/hybrids/VideoPlayerEmitter/HybridVideoPlayerEventEmitter.swift +203 -0
  70. package/ios/hybrids/VideoPlayerSource/HybridVideoPlayerSource.swift +55 -0
  71. package/ios/hybrids/VideoPlayerSource/HybridVideoPlayerSourceFactory.swift +29 -0
  72. package/ios/hybrids/VideoViewViewManager/HybridVideoViewViewManager.swift +266 -0
  73. package/ios/hybrids/VideoViewViewManager/HybridVideoViewViewManagerFactory.swift +14 -0
  74. package/ios/view/VideoComponentView.swift +196 -0
  75. package/ios/view/VideoComponentViewObserver.swift +48 -0
  76. package/lib/module/core/VideoPlayer.js +287 -0
  77. package/lib/module/core/VideoPlayer.js.map +1 -0
  78. package/lib/module/core/VideoPlayerEvents.js +84 -0
  79. package/lib/module/core/VideoPlayerEvents.js.map +1 -0
  80. package/lib/module/core/hooks/useEvent.js +19 -0
  81. package/lib/module/core/hooks/useEvent.js.map +1 -0
  82. package/lib/module/core/hooks/useManagedInstance.js +75 -0
  83. package/lib/module/core/hooks/useManagedInstance.js.map +1 -0
  84. package/lib/module/core/hooks/useVideoPlayer.js +57 -0
  85. package/lib/module/core/hooks/useVideoPlayer.js.map +1 -0
  86. package/lib/module/core/types/BufferConfig.js +2 -0
  87. package/lib/module/core/types/BufferConfig.js.map +1 -0
  88. package/lib/module/core/types/DrmParams.js +2 -0
  89. package/lib/module/core/types/DrmParams.js.map +1 -0
  90. package/lib/module/core/types/Events.js +10 -0
  91. package/lib/module/core/types/Events.js.map +1 -0
  92. package/lib/module/core/types/IgnoreSilentSwitchMode.js +2 -0
  93. package/lib/module/core/types/IgnoreSilentSwitchMode.js.map +1 -0
  94. package/lib/module/core/types/MixAudioMode.js +2 -0
  95. package/lib/module/core/types/MixAudioMode.js.map +1 -0
  96. package/lib/module/core/types/ResizeMode.js +2 -0
  97. package/lib/module/core/types/ResizeMode.js.map +1 -0
  98. package/lib/module/core/types/TextTrack.js +2 -0
  99. package/lib/module/core/types/TextTrack.js.map +1 -0
  100. package/lib/module/core/types/Utils.js +2 -0
  101. package/lib/module/core/types/Utils.js.map +1 -0
  102. package/lib/module/core/types/VideoConfig.js +4 -0
  103. package/lib/module/core/types/VideoConfig.js.map +1 -0
  104. package/lib/module/core/types/VideoError.js +100 -0
  105. package/lib/module/core/types/VideoError.js.map +1 -0
  106. package/lib/module/core/types/VideoInformation.js +4 -0
  107. package/lib/module/core/types/VideoInformation.js.map +1 -0
  108. package/lib/module/core/types/VideoOrientation.js +2 -0
  109. package/lib/module/core/types/VideoOrientation.js.map +1 -0
  110. package/lib/module/core/types/VideoPlayerBase.js +4 -0
  111. package/lib/module/core/types/VideoPlayerBase.js.map +1 -0
  112. package/lib/module/core/types/VideoPlayerSourceBase.js +4 -0
  113. package/lib/module/core/types/VideoPlayerSourceBase.js.map +1 -0
  114. package/lib/module/core/types/VideoPlayerStatus.js +2 -0
  115. package/lib/module/core/types/VideoPlayerStatus.js.map +1 -0
  116. package/lib/module/core/utils/playerFactory.js +25 -0
  117. package/lib/module/core/utils/playerFactory.js.map +1 -0
  118. package/lib/module/core/utils/sourceFactory.js +138 -0
  119. package/lib/module/core/utils/sourceFactory.js.map +1 -0
  120. package/lib/module/core/video-view/NativeVideoView.tsx +18 -0
  121. package/lib/module/core/video-view/VideoView.js +261 -0
  122. package/lib/module/core/video-view/VideoView.js.map +1 -0
  123. package/lib/module/expo-plugins/@types.js +2 -0
  124. package/lib/module/expo-plugins/@types.js.map +1 -0
  125. package/lib/module/expo-plugins/getPackageInfo.js +23 -0
  126. package/lib/module/expo-plugins/getPackageInfo.js.map +1 -0
  127. package/lib/module/expo-plugins/withAndroidExtensions.js +35 -0
  128. package/lib/module/expo-plugins/withAndroidExtensions.js.map +1 -0
  129. package/lib/module/expo-plugins/withAndroidNotificationControls.js +29 -0
  130. package/lib/module/expo-plugins/withAndroidNotificationControls.js.map +1 -0
  131. package/lib/module/expo-plugins/withAndroidPictureInPicture.js +18 -0
  132. package/lib/module/expo-plugins/withAndroidPictureInPicture.js.map +1 -0
  133. package/lib/module/expo-plugins/withBackgroundAudio.js +22 -0
  134. package/lib/module/expo-plugins/withBackgroundAudio.js.map +1 -0
  135. package/lib/module/expo-plugins/withReactNativeVideo.js +27 -0
  136. package/lib/module/expo-plugins/withReactNativeVideo.js.map +1 -0
  137. package/lib/module/expo-plugins/writeToPodfile.js +53 -0
  138. package/lib/module/expo-plugins/writeToPodfile.js.map +1 -0
  139. package/lib/module/index.js +8 -0
  140. package/lib/module/index.js.map +1 -0
  141. package/lib/module/package.json +1 -0
  142. package/lib/module/spec/fabric/VideoViewNativeComponent.ts +17 -0
  143. package/lib/module/spec/nitro/VideoPlayer.nitro.js +4 -0
  144. package/lib/module/spec/nitro/VideoPlayer.nitro.js.map +1 -0
  145. package/lib/module/spec/nitro/VideoPlayerEventEmitter.nitro.js +4 -0
  146. package/lib/module/spec/nitro/VideoPlayerEventEmitter.nitro.js.map +1 -0
  147. package/lib/module/spec/nitro/VideoPlayerSource.nitro.js +4 -0
  148. package/lib/module/spec/nitro/VideoPlayerSource.nitro.js.map +1 -0
  149. package/lib/module/spec/nitro/VideoViewViewManager.nitro.js +4 -0
  150. package/lib/module/spec/nitro/VideoViewViewManager.nitro.js.map +1 -0
  151. package/lib/typescript/drm-plugin/src/PluginManager.nitro.d.ts +10 -0
  152. package/lib/typescript/drm-plugin/src/PluginManager.nitro.d.ts.map +1 -0
  153. package/lib/typescript/drm-plugin/src/index.d.ts +4 -0
  154. package/lib/typescript/drm-plugin/src/index.d.ts.map +1 -0
  155. package/lib/typescript/package.json +1 -0
  156. package/lib/typescript/src/core/VideoPlayer.d.ts +88 -0
  157. package/lib/typescript/src/core/VideoPlayer.d.ts.map +1 -0
  158. package/lib/typescript/src/core/VideoPlayerEvents.d.ts +22 -0
  159. package/lib/typescript/src/core/VideoPlayerEvents.d.ts.map +1 -0
  160. package/lib/typescript/src/core/hooks/useEvent.d.ts +11 -0
  161. package/lib/typescript/src/core/hooks/useEvent.d.ts.map +1 -0
  162. package/lib/typescript/src/core/hooks/useManagedInstance.d.ts +19 -0
  163. package/lib/typescript/src/core/hooks/useManagedInstance.d.ts.map +1 -0
  164. package/lib/typescript/src/core/hooks/useVideoPlayer.d.ts +16 -0
  165. package/lib/typescript/src/core/hooks/useVideoPlayer.d.ts.map +1 -0
  166. package/lib/typescript/src/core/types/BufferConfig.d.ts +97 -0
  167. package/lib/typescript/src/core/types/BufferConfig.d.ts.map +1 -0
  168. package/lib/typescript/src/core/types/DrmParams.d.ts +64 -0
  169. package/lib/typescript/src/core/types/DrmParams.d.ts.map +1 -0
  170. package/lib/typescript/src/core/types/Events.d.ts +224 -0
  171. package/lib/typescript/src/core/types/Events.d.ts.map +1 -0
  172. package/lib/typescript/src/core/types/IgnoreSilentSwitchMode.d.ts +2 -0
  173. package/lib/typescript/src/core/types/IgnoreSilentSwitchMode.d.ts.map +1 -0
  174. package/lib/typescript/src/core/types/MixAudioMode.d.ts +2 -0
  175. package/lib/typescript/src/core/types/MixAudioMode.d.ts.map +1 -0
  176. package/lib/typescript/src/core/types/ResizeMode.d.ts +10 -0
  177. package/lib/typescript/src/core/types/ResizeMode.d.ts.map +1 -0
  178. package/lib/typescript/src/core/types/TextTrack.d.ts +20 -0
  179. package/lib/typescript/src/core/types/TextTrack.d.ts.map +1 -0
  180. package/lib/typescript/src/core/types/Utils.d.ts +2 -0
  181. package/lib/typescript/src/core/types/Utils.d.ts.map +1 -0
  182. package/lib/typescript/src/core/types/VideoConfig.d.ts +138 -0
  183. package/lib/typescript/src/core/types/VideoConfig.d.ts.map +1 -0
  184. package/lib/typescript/src/core/types/VideoError.d.ts +31 -0
  185. package/lib/typescript/src/core/types/VideoError.d.ts.map +1 -0
  186. package/lib/typescript/src/core/types/VideoInformation.d.ts +38 -0
  187. package/lib/typescript/src/core/types/VideoInformation.d.ts.map +1 -0
  188. package/lib/typescript/src/core/types/VideoOrientation.d.ts +2 -0
  189. package/lib/typescript/src/core/types/VideoOrientation.d.ts.map +1 -0
  190. package/lib/typescript/src/core/types/VideoPlayerBase.d.ts +155 -0
  191. package/lib/typescript/src/core/types/VideoPlayerBase.d.ts.map +1 -0
  192. package/lib/typescript/src/core/types/VideoPlayerSourceBase.d.ts +17 -0
  193. package/lib/typescript/src/core/types/VideoPlayerSourceBase.d.ts.map +1 -0
  194. package/lib/typescript/src/core/types/VideoPlayerStatus.d.ts +9 -0
  195. package/lib/typescript/src/core/types/VideoPlayerStatus.d.ts.map +1 -0
  196. package/lib/typescript/src/core/utils/playerFactory.d.ts +12 -0
  197. package/lib/typescript/src/core/utils/playerFactory.d.ts.map +1 -0
  198. package/lib/typescript/src/core/utils/sourceFactory.d.ts +29 -0
  199. package/lib/typescript/src/core/utils/sourceFactory.d.ts.map +1 -0
  200. package/lib/typescript/src/core/video-view/NativeVideoView.d.ts +2 -0
  201. package/lib/typescript/src/core/video-view/NativeVideoView.d.ts.map +1 -0
  202. package/lib/typescript/src/core/video-view/VideoView.d.ts +104 -0
  203. package/lib/typescript/src/core/video-view/VideoView.d.ts.map +1 -0
  204. package/lib/typescript/src/index.d.ts +13 -0
  205. package/lib/typescript/src/index.d.ts.map +1 -0
  206. package/lib/typescript/src/spec/fabric/VideoViewNativeComponent.d.ts +13 -0
  207. package/lib/typescript/src/spec/fabric/VideoViewNativeComponent.d.ts.map +1 -0
  208. package/lib/typescript/src/spec/nitro/VideoPlayer.nitro.d.ts +55 -0
  209. package/lib/typescript/src/spec/nitro/VideoPlayer.nitro.d.ts.map +1 -0
  210. package/lib/typescript/src/spec/nitro/VideoPlayerEventEmitter.nitro.d.ts +150 -0
  211. package/lib/typescript/src/spec/nitro/VideoPlayerEventEmitter.nitro.d.ts.map +1 -0
  212. package/lib/typescript/src/spec/nitro/VideoPlayerSource.nitro.d.ts +21 -0
  213. package/lib/typescript/src/spec/nitro/VideoPlayerSource.nitro.d.ts.map +1 -0
  214. package/lib/typescript/src/spec/nitro/VideoViewViewManager.nitro.d.ts +75 -0
  215. package/lib/typescript/src/spec/nitro/VideoViewViewManager.nitro.d.ts.map +1 -0
  216. package/nitro.json +47 -0
  217. package/nitrogen/generated/android/UnifiedPlayer+autolinking.cmake +95 -0
  218. package/nitrogen/generated/android/UnifiedPlayer+autolinking.gradle +27 -0
  219. package/nitrogen/generated/android/UnifiedPlayerOnLoad.cpp +122 -0
  220. package/nitrogen/generated/android/UnifiedPlayerOnLoad.hpp +34 -0
  221. package/nitrogen/generated/android/c++/JBandwidthData.hpp +65 -0
  222. package/nitrogen/generated/android/c++/JBufferConfig.hpp +101 -0
  223. package/nitrogen/generated/android/c++/JCustomVideoMetadata.hpp +74 -0
  224. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__string_____OnGetLicensePayload.hpp +126 -0
  225. package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
  226. package/nitrogen/generated/android/c++/JFunc_void_BandwidthData.hpp +78 -0
  227. package/nitrogen/generated/android/c++/JFunc_void_TimedMetadata.hpp +81 -0
  228. package/nitrogen/generated/android/c++/JFunc_void_VideoPlayerStatus.hpp +77 -0
  229. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
  230. package/nitrogen/generated/android/c++/JFunc_void_double.hpp +75 -0
  231. package/nitrogen/generated/android/c++/JFunc_void_onLoadData.hpp +79 -0
  232. package/nitrogen/generated/android/c++/JFunc_void_onLoadStartData.hpp +82 -0
  233. package/nitrogen/generated/android/c++/JFunc_void_onPlaybackStateChangeData.hpp +77 -0
  234. package/nitrogen/generated/android/c++/JFunc_void_onProgressData.hpp +77 -0
  235. package/nitrogen/generated/android/c++/JFunc_void_onVolumeChangeData.hpp +77 -0
  236. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__TextTrack__.hpp +83 -0
  237. package/nitrogen/generated/android/c++/JFunc_void_std__vector_std__string_.hpp +95 -0
  238. package/nitrogen/generated/android/c++/JHybridVideoPlayerEventEmitterSpec.cpp +224 -0
  239. package/nitrogen/generated/android/c++/JHybridVideoPlayerEventEmitterSpec.hpp +82 -0
  240. package/nitrogen/generated/android/c++/JHybridVideoPlayerFactorySpec.cpp +60 -0
  241. package/nitrogen/generated/android/c++/JHybridVideoPlayerFactorySpec.hpp +63 -0
  242. package/nitrogen/generated/android/c++/JHybridVideoPlayerSourceFactorySpec.cpp +106 -0
  243. package/nitrogen/generated/android/c++/JHybridVideoPlayerSourceFactorySpec.hpp +64 -0
  244. package/nitrogen/generated/android/c++/JHybridVideoPlayerSourceSpec.cpp +124 -0
  245. package/nitrogen/generated/android/c++/JHybridVideoPlayerSourceSpec.hpp +64 -0
  246. package/nitrogen/generated/android/c++/JHybridVideoPlayerSpec.cpp +300 -0
  247. package/nitrogen/generated/android/c++/JHybridVideoPlayerSpec.hpp +98 -0
  248. package/nitrogen/generated/android/c++/JHybridVideoViewViewManagerFactorySpec.cpp +56 -0
  249. package/nitrogen/generated/android/c++/JHybridVideoViewViewManagerFactorySpec.hpp +63 -0
  250. package/nitrogen/generated/android/c++/JHybridVideoViewViewManagerSpec.cpp +185 -0
  251. package/nitrogen/generated/android/c++/JHybridVideoViewViewManagerSpec.hpp +87 -0
  252. package/nitrogen/generated/android/c++/JIgnoreSilentSwitchMode.hpp +61 -0
  253. package/nitrogen/generated/android/c++/JListenerSubscription.hpp +67 -0
  254. package/nitrogen/generated/android/c++/JLivePlaybackParams.hpp +73 -0
  255. package/nitrogen/generated/android/c++/JMixAudioMode.hpp +64 -0
  256. package/nitrogen/generated/android/c++/JNativeDrmParams.hpp +111 -0
  257. package/nitrogen/generated/android/c++/JNativeExternalSubtitle.hpp +71 -0
  258. package/nitrogen/generated/android/c++/JNativeVideoConfig.hpp +136 -0
  259. package/nitrogen/generated/android/c++/JOnGetLicensePayload.hpp +69 -0
  260. package/nitrogen/generated/android/c++/JResizeMode.hpp +64 -0
  261. package/nitrogen/generated/android/c++/JResolution.hpp +61 -0
  262. package/nitrogen/generated/android/c++/JSourceType.hpp +58 -0
  263. package/nitrogen/generated/android/c++/JSubtitleType.hpp +67 -0
  264. package/nitrogen/generated/android/c++/JSurfaceType.hpp +58 -0
  265. package/nitrogen/generated/android/c++/JTextTrack.hpp +70 -0
  266. package/nitrogen/generated/android/c++/JTimedMetadata.hpp +78 -0
  267. package/nitrogen/generated/android/c++/JTimedMetadataObject.hpp +61 -0
  268. package/nitrogen/generated/android/c++/JVariant_NullType_HybridVideoPlayerSourceSpec.cpp +26 -0
  269. package/nitrogen/generated/android/c++/JVariant_NullType_HybridVideoPlayerSourceSpec.hpp +72 -0
  270. package/nitrogen/generated/android/c++/JVariant_NullType_TextTrack.cpp +26 -0
  271. package/nitrogen/generated/android/c++/JVariant_NullType_TextTrack.hpp +73 -0
  272. package/nitrogen/generated/android/c++/JVideoInformation.hpp +86 -0
  273. package/nitrogen/generated/android/c++/JVideoOrientation.hpp +73 -0
  274. package/nitrogen/generated/android/c++/JVideoPlayerStatus.hpp +64 -0
  275. package/nitrogen/generated/android/c++/JonLoadData.hpp +74 -0
  276. package/nitrogen/generated/android/c++/JonLoadStartData.hpp +65 -0
  277. package/nitrogen/generated/android/c++/JonPlaybackStateChangeData.hpp +61 -0
  278. package/nitrogen/generated/android/c++/JonProgressData.hpp +65 -0
  279. package/nitrogen/generated/android/c++/JonVolumeChangeData.hpp +61 -0
  280. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/BandwidthData.kt +61 -0
  281. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/BufferConfig.kt +101 -0
  282. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/CustomVideoMetadata.kt +71 -0
  283. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__string_____OnGetLicensePayload.kt +80 -0
  284. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void.kt +80 -0
  285. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_BandwidthData.kt +80 -0
  286. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_TimedMetadata.kt +80 -0
  287. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_VideoPlayerStatus.kt +80 -0
  288. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_bool.kt +80 -0
  289. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_double.kt +80 -0
  290. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_onLoadData.kt +80 -0
  291. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_onLoadStartData.kt +80 -0
  292. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_onPlaybackStateChangeData.kt +80 -0
  293. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_onProgressData.kt +80 -0
  294. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_onVolumeChangeData.kt +80 -0
  295. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_std__optional_std__variant_nitro__NullType__TextTrack__.kt +80 -0
  296. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Func_void_std__vector_std__string_.kt +80 -0
  297. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/HybridVideoPlayerEventEmitterSpec.kt +226 -0
  298. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/HybridVideoPlayerFactorySpec.kt +54 -0
  299. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/HybridVideoPlayerSourceFactorySpec.kt +58 -0
  300. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/HybridVideoPlayerSourceSpec.kt +61 -0
  301. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/HybridVideoPlayerSpec.kt +178 -0
  302. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/HybridVideoViewViewManagerFactorySpec.kt +54 -0
  303. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/HybridVideoViewViewManagerSpec.kt +168 -0
  304. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/IgnoreSilentSwitchMode.kt +24 -0
  305. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/ListenerSubscription.kt +55 -0
  306. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/LivePlaybackParams.kt +71 -0
  307. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/MixAudioMode.kt +25 -0
  308. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/NativeDrmParams.kt +85 -0
  309. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/NativeExternalSubtitle.kt +66 -0
  310. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/NativeVideoConfig.kt +81 -0
  311. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/OnGetLicensePayload.kt +66 -0
  312. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/ResizeMode.kt +25 -0
  313. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Resolution.kt +56 -0
  314. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/SourceType.kt +23 -0
  315. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/SubtitleType.kt +26 -0
  316. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/SurfaceType.kt +23 -0
  317. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/TextTrack.kt +66 -0
  318. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/TimedMetadata.kt +51 -0
  319. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/TimedMetadataObject.kt +56 -0
  320. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/UnifiedPlayerOnLoad.kt +35 -0
  321. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Variant_NullType_HybridVideoPlayerSourceSpec.kt +62 -0
  322. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/Variant_NullType_TextTrack.kt +62 -0
  323. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/VideoInformation.kt +86 -0
  324. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/VideoOrientation.kt +28 -0
  325. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/VideoPlayerStatus.kt +25 -0
  326. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/onLoadData.kt +71 -0
  327. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/onLoadStartData.kt +56 -0
  328. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/onPlaybackStateChangeData.kt +56 -0
  329. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/onProgressData.kt +61 -0
  330. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unifiedplayer/onVolumeChangeData.kt +56 -0
  331. package/nitrogen/generated/ios/UnifiedPlayer+autolinking.rb +62 -0
  332. package/nitrogen/generated/ios/UnifiedPlayer-Swift-Cxx-Bridge.cpp +280 -0
  333. package/nitrogen/generated/ios/UnifiedPlayer-Swift-Cxx-Bridge.hpp +1106 -0
  334. package/nitrogen/generated/ios/UnifiedPlayer-Swift-Cxx-Umbrella.hpp +162 -0
  335. package/nitrogen/generated/ios/UnifiedPlayerAutolinking.mm +49 -0
  336. package/nitrogen/generated/ios/UnifiedPlayerAutolinking.swift +50 -0
  337. package/nitrogen/generated/ios/c++/HybridVideoPlayerEventEmitterSpecSwift.cpp +11 -0
  338. package/nitrogen/generated/ios/c++/HybridVideoPlayerEventEmitterSpecSwift.hpp +279 -0
  339. package/nitrogen/generated/ios/c++/HybridVideoPlayerFactorySpecSwift.cpp +11 -0
  340. package/nitrogen/generated/ios/c++/HybridVideoPlayerFactorySpecSwift.hpp +87 -0
  341. package/nitrogen/generated/ios/c++/HybridVideoPlayerSourceFactorySpecSwift.cpp +11 -0
  342. package/nitrogen/generated/ios/c++/HybridVideoPlayerSourceFactorySpecSwift.hpp +125 -0
  343. package/nitrogen/generated/ios/c++/HybridVideoPlayerSourceSpecSwift.cpp +11 -0
  344. package/nitrogen/generated/ios/c++/HybridVideoPlayerSourceSpecSwift.hpp +125 -0
  345. package/nitrogen/generated/ios/c++/HybridVideoPlayerSpecSwift.cpp +11 -0
  346. package/nitrogen/generated/ios/c++/HybridVideoPlayerSpecSwift.hpp +256 -0
  347. package/nitrogen/generated/ios/c++/HybridVideoViewViewManagerFactorySpecSwift.cpp +11 -0
  348. package/nitrogen/generated/ios/c++/HybridVideoViewViewManagerFactorySpecSwift.hpp +84 -0
  349. package/nitrogen/generated/ios/c++/HybridVideoViewViewManagerSpecSwift.cpp +11 -0
  350. package/nitrogen/generated/ios/c++/HybridVideoViewViewManagerSpecSwift.hpp +217 -0
  351. package/nitrogen/generated/ios/swift/BandwidthData.swift +65 -0
  352. package/nitrogen/generated/ios/swift/BufferConfig.swift +201 -0
  353. package/nitrogen/generated/ios/swift/CustomVideoMetadata.swift +114 -0
  354. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__string_____OnGetLicensePayload.swift +61 -0
  355. package/nitrogen/generated/ios/swift/Func_void.swift +46 -0
  356. package/nitrogen/generated/ios/swift/Func_void_BandwidthData.swift +46 -0
  357. package/nitrogen/generated/ios/swift/Func_void_TimedMetadata.swift +46 -0
  358. package/nitrogen/generated/ios/swift/Func_void_VideoInformation.swift +46 -0
  359. package/nitrogen/generated/ios/swift/Func_void_VideoPlayerStatus.swift +46 -0
  360. package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  361. package/nitrogen/generated/ios/swift/Func_void_double.swift +46 -0
  362. package/nitrogen/generated/ios/swift/Func_void_onLoadData.swift +46 -0
  363. package/nitrogen/generated/ios/swift/Func_void_onLoadStartData.swift +46 -0
  364. package/nitrogen/generated/ios/swift/Func_void_onPlaybackStateChangeData.swift +46 -0
  365. package/nitrogen/generated/ios/swift/Func_void_onProgressData.swift +46 -0
  366. package/nitrogen/generated/ios/swift/Func_void_onVolumeChangeData.swift +46 -0
  367. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
  368. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__variant_nitro__NullType__TextTrack__.swift +65 -0
  369. package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_std__string__.swift +66 -0
  370. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
  371. package/nitrogen/generated/ios/swift/Func_void_std__vector_std__string_.swift +46 -0
  372. package/nitrogen/generated/ios/swift/HybridVideoPlayerEventEmitterSpec.swift +74 -0
  373. package/nitrogen/generated/ios/swift/HybridVideoPlayerEventEmitterSpec_cxx.swift +479 -0
  374. package/nitrogen/generated/ios/swift/HybridVideoPlayerFactorySpec.swift +55 -0
  375. package/nitrogen/generated/ios/swift/HybridVideoPlayerFactorySpec_cxx.swift +145 -0
  376. package/nitrogen/generated/ios/swift/HybridVideoPlayerSourceFactorySpec.swift +56 -0
  377. package/nitrogen/generated/ios/swift/HybridVideoPlayerSourceFactorySpec_cxx.swift +156 -0
  378. package/nitrogen/generated/ios/swift/HybridVideoPlayerSourceSpec.swift +56 -0
  379. package/nitrogen/generated/ios/swift/HybridVideoPlayerSourceSpec_cxx.swift +157 -0
  380. package/nitrogen/generated/ios/swift/HybridVideoPlayerSpec.swift +80 -0
  381. package/nitrogen/generated/ios/swift/HybridVideoPlayerSpec_cxx.swift +490 -0
  382. package/nitrogen/generated/ios/swift/HybridVideoViewViewManagerFactorySpec.swift +55 -0
  383. package/nitrogen/generated/ios/swift/HybridVideoViewViewManagerFactorySpec_cxx.swift +141 -0
  384. package/nitrogen/generated/ios/swift/HybridVideoViewViewManagerSpec.swift +72 -0
  385. package/nitrogen/generated/ios/swift/HybridVideoViewViewManagerSpec_cxx.swift +390 -0
  386. package/nitrogen/generated/ios/swift/IgnoreSilentSwitchMode.swift +44 -0
  387. package/nitrogen/generated/ios/swift/ListenerSubscription.swift +37 -0
  388. package/nitrogen/generated/ios/swift/LivePlaybackParams.swift +114 -0
  389. package/nitrogen/generated/ios/swift/MixAudioMode.swift +48 -0
  390. package/nitrogen/generated/ios/swift/NativeDrmParams.swift +193 -0
  391. package/nitrogen/generated/ios/swift/NativeExternalSubtitle.swift +44 -0
  392. package/nitrogen/generated/ios/swift/NativeVideoConfig.swift +136 -0
  393. package/nitrogen/generated/ios/swift/OnGetLicensePayload.swift +44 -0
  394. package/nitrogen/generated/ios/swift/ResizeMode.swift +48 -0
  395. package/nitrogen/generated/ios/swift/Resolution.swift +34 -0
  396. package/nitrogen/generated/ios/swift/SourceType.swift +40 -0
  397. package/nitrogen/generated/ios/swift/SubtitleType.swift +52 -0
  398. package/nitrogen/generated/ios/swift/SurfaceType.swift +40 -0
  399. package/nitrogen/generated/ios/swift/TextTrack.swift +57 -0
  400. package/nitrogen/generated/ios/swift/TimedMetadata.swift +35 -0
  401. package/nitrogen/generated/ios/swift/TimedMetadataObject.swift +34 -0
  402. package/nitrogen/generated/ios/swift/Variant_NullType_TextTrack.swift +30 -0
  403. package/nitrogen/generated/ios/swift/Variant_NullType__any_HybridVideoPlayerSourceSpec_.swift +30 -0
  404. package/nitrogen/generated/ios/swift/VideoInformation.swift +64 -0
  405. package/nitrogen/generated/ios/swift/VideoOrientation.swift +60 -0
  406. package/nitrogen/generated/ios/swift/VideoPlayerStatus.swift +48 -0
  407. package/nitrogen/generated/ios/swift/onLoadData.swift +49 -0
  408. package/nitrogen/generated/ios/swift/onLoadStartData.swift +41 -0
  409. package/nitrogen/generated/ios/swift/onPlaybackStateChangeData.swift +34 -0
  410. package/nitrogen/generated/ios/swift/onProgressData.swift +39 -0
  411. package/nitrogen/generated/ios/swift/onVolumeChangeData.swift +34 -0
  412. package/nitrogen/generated/shared/c++/BandwidthData.hpp +91 -0
  413. package/nitrogen/generated/shared/c++/BufferConfig.hpp +128 -0
  414. package/nitrogen/generated/shared/c++/CustomVideoMetadata.hpp +100 -0
  415. package/nitrogen/generated/shared/c++/HybridVideoPlayerEventEmitterSpec.cpp +40 -0
  416. package/nitrogen/generated/shared/c++/HybridVideoPlayerEventEmitterSpec.hpp +115 -0
  417. package/nitrogen/generated/shared/c++/HybridVideoPlayerFactorySpec.cpp +21 -0
  418. package/nitrogen/generated/shared/c++/HybridVideoPlayerFactorySpec.hpp +67 -0
  419. package/nitrogen/generated/shared/c++/HybridVideoPlayerSourceFactorySpec.cpp +22 -0
  420. package/nitrogen/generated/shared/c++/HybridVideoPlayerSourceFactorySpec.hpp +69 -0
  421. package/nitrogen/generated/shared/c++/HybridVideoPlayerSourceSpec.cpp +23 -0
  422. package/nitrogen/generated/shared/c++/HybridVideoPlayerSourceSpec.hpp +69 -0
  423. package/nitrogen/generated/shared/c++/HybridVideoPlayerSpec.cpp +57 -0
  424. package/nitrogen/generated/shared/c++/HybridVideoPlayerSpec.hpp +120 -0
  425. package/nitrogen/generated/shared/c++/HybridVideoViewViewManagerFactorySpec.cpp +21 -0
  426. package/nitrogen/generated/shared/c++/HybridVideoViewViewManagerFactorySpec.hpp +64 -0
  427. package/nitrogen/generated/shared/c++/HybridVideoViewViewManagerSpec.cpp +46 -0
  428. package/nitrogen/generated/shared/c++/HybridVideoViewViewManagerSpec.hpp +99 -0
  429. package/nitrogen/generated/shared/c++/IgnoreSilentSwitchMode.hpp +80 -0
  430. package/nitrogen/generated/shared/c++/ListenerSubscription.hpp +83 -0
  431. package/nitrogen/generated/shared/c++/LivePlaybackParams.hpp +99 -0
  432. package/nitrogen/generated/shared/c++/MixAudioMode.hpp +84 -0
  433. package/nitrogen/generated/shared/c++/NativeDrmParams.hpp +113 -0
  434. package/nitrogen/generated/shared/c++/NativeExternalSubtitle.hpp +97 -0
  435. package/nitrogen/generated/shared/c++/NativeVideoConfig.hpp +121 -0
  436. package/nitrogen/generated/shared/c++/OnGetLicensePayload.hpp +95 -0
  437. package/nitrogen/generated/shared/c++/ResizeMode.hpp +84 -0
  438. package/nitrogen/generated/shared/c++/Resolution.hpp +87 -0
  439. package/nitrogen/generated/shared/c++/SourceType.hpp +76 -0
  440. package/nitrogen/generated/shared/c++/SubtitleType.hpp +88 -0
  441. package/nitrogen/generated/shared/c++/SurfaceType.hpp +76 -0
  442. package/nitrogen/generated/shared/c++/TextTrack.hpp +96 -0
  443. package/nitrogen/generated/shared/c++/TimedMetadata.hpp +85 -0
  444. package/nitrogen/generated/shared/c++/TimedMetadataObject.hpp +87 -0
  445. package/nitrogen/generated/shared/c++/VideoInformation.hpp +112 -0
  446. package/nitrogen/generated/shared/c++/VideoOrientation.hpp +96 -0
  447. package/nitrogen/generated/shared/c++/VideoPlayerStatus.hpp +84 -0
  448. package/nitrogen/generated/shared/c++/onLoadData.hpp +100 -0
  449. package/nitrogen/generated/shared/c++/onLoadStartData.hpp +92 -0
  450. package/nitrogen/generated/shared/c++/onPlaybackStateChangeData.hpp +87 -0
  451. package/nitrogen/generated/shared/c++/onProgressData.hpp +91 -0
  452. package/nitrogen/generated/shared/c++/onVolumeChangeData.hpp +87 -0
  453. package/package.json +180 -0
  454. package/react-native.config.js +10 -0
  455. package/src/core/VideoPlayer.ts +357 -0
  456. package/src/core/VideoPlayerEvents.ts +146 -0
  457. package/src/core/hooks/useEvent.ts +24 -0
  458. package/src/core/hooks/useManagedInstance.ts +96 -0
  459. package/src/core/hooks/useVideoPlayer.ts +73 -0
  460. package/src/core/types/BufferConfig.ts +103 -0
  461. package/src/core/types/DrmParams.ts +65 -0
  462. package/src/core/types/Events.ts +283 -0
  463. package/src/core/types/IgnoreSilentSwitchMode.ts +1 -0
  464. package/src/core/types/MixAudioMode.ts +1 -0
  465. package/src/core/types/ResizeMode.ts +9 -0
  466. package/src/core/types/TextTrack.ts +22 -0
  467. package/src/core/types/Utils.ts +1 -0
  468. package/src/core/types/VideoConfig.ts +150 -0
  469. package/src/core/types/VideoError.ts +174 -0
  470. package/src/core/types/VideoInformation.ts +45 -0
  471. package/src/core/types/VideoOrientation.ts +8 -0
  472. package/src/core/types/VideoPlayerBase.ts +181 -0
  473. package/src/core/types/VideoPlayerSourceBase.ts +19 -0
  474. package/src/core/types/VideoPlayerStatus.ts +8 -0
  475. package/src/core/utils/playerFactory.ts +33 -0
  476. package/src/core/utils/sourceFactory.ts +171 -0
  477. package/src/core/video-view/NativeVideoView.tsx +18 -0
  478. package/src/core/video-view/VideoView.tsx +492 -0
  479. package/src/expo-plugins/@types.ts +37 -0
  480. package/src/expo-plugins/getPackageInfo.ts +23 -0
  481. package/src/expo-plugins/withAndroidExtensions.ts +46 -0
  482. package/src/expo-plugins/withAndroidNotificationControls.ts +43 -0
  483. package/src/expo-plugins/withAndroidPictureInPicture.ts +31 -0
  484. package/src/expo-plugins/withBackgroundAudio.ts +26 -0
  485. package/src/expo-plugins/withReactNativeVideo.ts +32 -0
  486. package/src/expo-plugins/writeToPodfile.ts +74 -0
  487. package/src/index.tsx +29 -0
  488. package/src/spec/fabric/VideoViewNativeComponent.ts +17 -0
  489. package/src/spec/nitro/VideoPlayer.nitro.ts +62 -0
  490. package/src/spec/nitro/VideoPlayerEventEmitter.nitro.ts +207 -0
  491. package/src/spec/nitro/VideoPlayerSource.nitro.ts +18 -0
  492. package/src/spec/nitro/VideoViewViewManager.nitro.ts +92 -0
@@ -0,0 +1,732 @@
1
+ package com.margelo.nitro.unifiedplayer
2
+
3
+ import android.graphics.Bitmap
4
+ import android.media.MediaMetadataRetriever
5
+ import android.os.Handler
6
+ import android.os.Looper
7
+ import android.util.Base64
8
+ import android.util.Log
9
+ import android.view.TextureView
10
+ import java.io.ByteArrayOutputStream
11
+ import androidx.media3.common.C
12
+ import androidx.media3.common.Metadata
13
+ import androidx.media3.common.PlaybackException
14
+ import androidx.media3.common.PlaybackParameters
15
+ import androidx.media3.common.Player
16
+ import androidx.media3.common.Tracks
17
+ import androidx.media3.common.text.CueGroup
18
+ import androidx.media3.common.util.UnstableApi
19
+ import androidx.media3.exoplayer.DefaultLoadControl
20
+ import androidx.media3.exoplayer.DefaultRenderersFactory
21
+ import androidx.media3.exoplayer.ExoPlayer
22
+ import androidx.media3.exoplayer.analytics.AnalyticsListener
23
+ import androidx.media3.exoplayer.mediacodec.MediaCodecSelector
24
+ import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
25
+ import androidx.media3.exoplayer.upstream.DefaultAllocator
26
+ import androidx.media3.extractor.metadata.emsg.EventMessage
27
+ import androidx.media3.extractor.metadata.id3.Id3Frame
28
+ import androidx.media3.extractor.metadata.id3.TextInformationFrame
29
+ import androidx.media3.ui.PlayerView
30
+ import com.facebook.proguard.annotations.DoNotStrip
31
+ import com.margelo.nitro.NitroModules
32
+ import com.margelo.nitro.core.Promise
33
+ import com.unifiedplayer.core.LibraryError
34
+ import com.unifiedplayer.core.PlayerError
35
+ import com.unifiedplayer.core.VideoManager
36
+ import com.unifiedplayer.core.extensions.startService
37
+ import com.unifiedplayer.core.extensions.stopService
38
+ import com.unifiedplayer.core.player.OnAudioFocusChangedListener
39
+ import com.unifiedplayer.core.recivers.AudioBecomingNoisyReceiver
40
+ import com.unifiedplayer.core.services.playback.VideoPlaybackService
41
+ import com.unifiedplayer.core.services.playback.VideoPlaybackServiceConnection
42
+ import com.unifiedplayer.core.utils.TextTrackUtils
43
+ import com.unifiedplayer.core.utils.Threading.mainThreadProperty
44
+ import com.unifiedplayer.core.utils.Threading.runOnMainThread
45
+ import com.unifiedplayer.core.utils.Threading.runOnMainThreadSync
46
+ import com.unifiedplayer.core.utils.VideoOrientationUtils
47
+ import com.unifiedplayer.view.VideoView
48
+ import java.lang.ref.WeakReference
49
+ import kotlin.math.max
50
+
51
+ @UnstableApi
52
+ @DoNotStrip
53
+ class HybridVideoPlayer() : HybridVideoPlayerSpec(), AutoCloseable {
54
+ override lateinit var source: HybridVideoPlayerSourceSpec
55
+ override var eventEmitter = HybridVideoPlayerEventEmitter()
56
+ set(value) {
57
+ if (field != value) {
58
+ audioFocusChangedListener.setEventEmitter(value)
59
+ audioBecomingNoisyReceiver.setEventEmitter(value)
60
+ }
61
+ field = value
62
+ }
63
+
64
+ private var allocator: DefaultAllocator? = null
65
+ private var context = NitroModules.applicationContext
66
+ ?: run {
67
+ throw LibraryError.ApplicationContextNotFound
68
+ }
69
+
70
+ var player: ExoPlayer = runOnMainThreadSync {
71
+ // Build Temporary player that will be replaced when source is loaded
72
+ return@runOnMainThreadSync ExoPlayer.Builder(context).build()
73
+ }
74
+
75
+ var loadedWithSource = false
76
+ private var currentPlayerView: WeakReference<PlayerView>? = null
77
+
78
+ var wasAutoPaused = false
79
+
80
+ // Buffer Config
81
+ private var bufferConfig: BufferConfig? = null
82
+ get() = source.config.bufferConfig
83
+
84
+ // Time updates
85
+ private val progressHandler = Handler(Looper.getMainLooper())
86
+ private var progressRunnable: Runnable? = null
87
+
88
+ // Listeners
89
+ private val audioFocusChangedListener = OnAudioFocusChangedListener()
90
+ private val audioBecomingNoisyReceiver = AudioBecomingNoisyReceiver()
91
+
92
+ // Service Connection
93
+ private val videoPlaybackServiceConnection = VideoPlaybackServiceConnection(WeakReference(this))
94
+
95
+ // Text track selection state
96
+ private var selectedExternalTrackIndex: Int? = null
97
+
98
+ private companion object {
99
+ const val PROGRESS_UPDATE_INTERVAL_MS = 250L
100
+ private const val TAG = "HybridVideoPlayer"
101
+ private const val DEFAULT_MIN_BUFFER_DURATION_MS = 5000
102
+ private const val DEFAULT_MAX_BUFFER_DURATION_MS = 10000
103
+ private const val DEFAULT_BUFFER_FOR_PLAYBACK_DURATION_MS = 1000
104
+ private const val DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_DURATION_MS = 2000
105
+ private const val DEFAULT_BACK_BUFFER_DURATION_MS = 0
106
+ }
107
+
108
+ override var status: VideoPlayerStatus = VideoPlayerStatus.IDLE
109
+ set(value) {
110
+ if (field != value) {
111
+ eventEmitter.onStatusChange(value)
112
+ }
113
+ field = value
114
+ }
115
+
116
+ override var showNotificationControls: Boolean = false
117
+ set(value) {
118
+ val wasRunning = (field || playInBackground)
119
+ val shouldRun = (value || playInBackground)
120
+
121
+ if (shouldRun && !wasRunning) {
122
+ VideoPlaybackService.startService(context, videoPlaybackServiceConnection)
123
+ }
124
+ if (!shouldRun && wasRunning) {
125
+ VideoPlaybackService.stopService(this, videoPlaybackServiceConnection)
126
+ }
127
+
128
+ field = value
129
+ // Inform service to refresh notification/session layout
130
+ try { videoPlaybackServiceConnection.serviceBinder?.service?.updatePlayerPreferences(this) } catch (_: Exception) {}
131
+ }
132
+
133
+ // Player Properties
134
+ override var currentTime: Double by mainThreadProperty(
135
+ get = { player.currentPosition.toDouble() / 1000.0 },
136
+ set = { value -> runOnMainThread { player.seekTo((value * 1000).toLong()) } }
137
+ )
138
+
139
+ // volume defined by user
140
+ var userVolume: Double = 1.0
141
+
142
+ override var volume: Double by mainThreadProperty(
143
+ get = { player.volume.toDouble() },
144
+ set = { value ->
145
+ userVolume = value
146
+ player.volume = value.toFloat()
147
+ }
148
+ )
149
+
150
+ override val duration: Double by mainThreadProperty(
151
+ get = {
152
+ val duration = player.duration
153
+ return@mainThreadProperty if (duration == C.TIME_UNSET) Double.NaN else duration.toDouble() / 1000.0
154
+ }
155
+ )
156
+
157
+ override var loop: Boolean by mainThreadProperty(
158
+ get = {
159
+ player.repeatMode == Player.REPEAT_MODE_ONE
160
+ },
161
+ set = { value ->
162
+ player.repeatMode = if (value) Player.REPEAT_MODE_ONE else Player.REPEAT_MODE_OFF
163
+ }
164
+ )
165
+
166
+ override var muted: Boolean by mainThreadProperty(
167
+ get = {
168
+ val playerVolume = player.volume.toDouble()
169
+ return@mainThreadProperty playerVolume == 0.0
170
+ },
171
+ set = { value ->
172
+ if (value) {
173
+ userVolume = volume
174
+ player.volume = 0f
175
+ } else {
176
+ player.volume = userVolume.toFloat()
177
+ }
178
+ eventEmitter.onVolumeChange(onVolumeChangeData(
179
+ volume = player.volume.toDouble(),
180
+ muted = muted
181
+ ))
182
+ }
183
+ )
184
+
185
+ override var rate: Double by mainThreadProperty(
186
+ get = { player.playbackParameters.speed.toDouble() },
187
+ set = { value ->
188
+ player.playbackParameters = player.playbackParameters.withSpeed(value.toFloat())
189
+ }
190
+ )
191
+
192
+ override var mixAudioMode: MixAudioMode = MixAudioMode.AUTO
193
+ set(value) {
194
+ VideoManager.audioFocusManager.requestAudioFocusUpdate()
195
+ field = value
196
+ }
197
+
198
+ // iOS only property
199
+ override var ignoreSilentSwitchMode: IgnoreSilentSwitchMode = IgnoreSilentSwitchMode.AUTO
200
+
201
+ override var playInBackground: Boolean = false
202
+ set(value) {
203
+ val shouldRun = (value || showNotificationControls)
204
+ val wasRunning = (field || showNotificationControls)
205
+
206
+ if (shouldRun && !wasRunning) {
207
+ VideoPlaybackService.startService(context, videoPlaybackServiceConnection)
208
+ }
209
+ if (!shouldRun && wasRunning) {
210
+ VideoPlaybackService.stopService(this, videoPlaybackServiceConnection)
211
+ }
212
+ field = value
213
+ // Update preferences to refresh notifications/registration
214
+ try { videoPlaybackServiceConnection.serviceBinder?.service?.updatePlayerPreferences(this) } catch (_: Exception) {}
215
+ }
216
+
217
+ override var playWhenInactive: Boolean = false
218
+
219
+ override var isPlaying: Boolean by mainThreadProperty(
220
+ get = { player.isPlaying == true }
221
+ )
222
+
223
+ private fun initializePlayer() {
224
+ if (NitroModules.applicationContext == null) {
225
+ throw LibraryError.ApplicationContextNotFound
226
+ }
227
+
228
+ val hybridSource = source as? HybridVideoPlayerSource ?: throw PlayerError.InvalidSource
229
+
230
+ // Initialize the allocator
231
+ allocator = DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE)
232
+
233
+ // Create a LoadControl with the allocator
234
+ val loadControl = DefaultLoadControl.Builder()
235
+ .setAllocator(allocator!!)
236
+ .setBufferDurationsMs(
237
+ bufferConfig?.minBufferMs?.toInt() ?: DEFAULT_MIN_BUFFER_DURATION_MS, // minBufferMs
238
+ bufferConfig?.maxBufferMs?.toInt() ?: DEFAULT_MAX_BUFFER_DURATION_MS, // maxBufferMs
239
+ bufferConfig?.bufferForPlaybackMs?.toInt()
240
+ ?: DEFAULT_BUFFER_FOR_PLAYBACK_DURATION_MS, // bufferForPlaybackMs
241
+ bufferConfig?.bufferForPlaybackAfterRebufferMs?.toInt()
242
+ ?: DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_DURATION_MS // bufferForPlaybackAfterRebufferMs
243
+ )
244
+ .setBackBuffer(
245
+ bufferConfig?.backBufferDurationMs?.toInt()
246
+ ?: DEFAULT_BACK_BUFFER_DURATION_MS, // backBufferDurationMs,
247
+ false // retainBackBufferFromKeyframe
248
+ )
249
+ .build()
250
+
251
+ // Renderers:
252
+ // setEnableDecoderFallback(true) — if the primary HW decoder rejects an HEVC
253
+ // sample (Main10, profile/level mismatch, vendor bug), ExoPlayer transparently
254
+ // falls back to a secondary decoder (e.g. software c2.android.hevc.decoder).
255
+ // setMediaCodecSelector(DEFAULT) — explicit so the selector enumerates *all*
256
+ // HEVC decoders the device exposes, not just the first match. Some Mediatek
257
+ // SoCs list a buggy HEVC HW decoder before the working one.
258
+ // forceEnableMediaCodecAsynchronousQueueing() — kept; improves H.264 latency
259
+ // and the decoder-fallback path will catch any device where async queueing
260
+ // interacts badly with HEVC.
261
+ val renderersFactory = DefaultRenderersFactory(context)
262
+ .forceEnableMediaCodecAsynchronousQueueing()
263
+ .setEnableDecoderFallback(true)
264
+ .setMediaCodecSelector(MediaCodecSelector.DEFAULT)
265
+
266
+ // Track selector tuned for adaptive HLS that mixes H.264 and H.265 variants.
267
+ // setAllowVideoMixedMimeTypeAdaptiveness — required to switch between H.264
268
+ // and H.265 variants in the same EXT-X-STREAM-INF group. Off-by-default
269
+ // conservatively, but server-side HEVC ladders often expose mixed MIME.
270
+ // setAllowVideoNonSeamlessAdaptiveness — lets the player rebuild the codec
271
+ // when crossing a HEVC variant boundary instead of failing track selection.
272
+ // setExceedVideoConstraintsIfNecessary — falls back to picking the lowest
273
+ // HEVC rendition rather than failing if every HEVC track exceeds the
274
+ // default 1080p/30fps viewport constraint on small surfaces.
275
+ val trackSelector = DefaultTrackSelector(context).apply {
276
+ setParameters(
277
+ buildUponParameters()
278
+ .setAllowVideoMixedMimeTypeAdaptiveness(true)
279
+ .setAllowVideoNonSeamlessAdaptiveness(true)
280
+ .setExceedVideoConstraintsIfNecessary(true)
281
+ )
282
+ }
283
+
284
+ player = ExoPlayer.Builder(context)
285
+ .setLoadControl(loadControl)
286
+ .setLooper(Looper.getMainLooper())
287
+ .setRenderersFactory(renderersFactory)
288
+ .setTrackSelector(trackSelector)
289
+ .build()
290
+
291
+ loadedWithSource = true
292
+
293
+ player.addListener(playerListener)
294
+ player.addAnalyticsListener(analyticsListener)
295
+ player.setMediaSource(hybridSource.mediaSource)
296
+
297
+ // Emit onLoadStart
298
+ val sourceType = if (hybridSource.uri.startsWith("http")) SourceType.NETWORK else SourceType.LOCAL
299
+ eventEmitter.onLoadStart(onLoadStartData(sourceType = sourceType, source = hybridSource))
300
+ status = VideoPlayerStatus.LOADING
301
+ startProgressUpdates()
302
+ }
303
+
304
+ override fun initialize(): Promise<Unit> {
305
+ return Promise.async {
306
+ return@async runOnMainThreadSync {
307
+ initializePlayer()
308
+ player.prepare()
309
+ }
310
+ }
311
+ }
312
+
313
+ constructor(source: HybridVideoPlayerSource) : this() {
314
+ this.source = source
315
+
316
+ runOnMainThread {
317
+ if (source.config.initializeOnCreation == true) {
318
+ initializePlayer()
319
+ player.prepare()
320
+ }
321
+ }
322
+
323
+ VideoManager.registerPlayer(this)
324
+ }
325
+
326
+ override fun play() {
327
+ runOnMainThread {
328
+ player.play()
329
+ }
330
+ }
331
+
332
+ override fun pause() {
333
+ runOnMainThread {
334
+ player.pause()
335
+ }
336
+ }
337
+
338
+ override fun seekBy(time: Double) {
339
+ currentTime = (currentTime + time).coerceIn(0.0, duration)
340
+ }
341
+
342
+ override fun seekTo(time: Double) {
343
+ currentTime = time.coerceIn(0.0, duration)
344
+ }
345
+
346
+ override fun replaceSourceAsync(source: Variant_NullType_HybridVideoPlayerSourceSpec?): Promise<Unit> {
347
+ return Promise.async {
348
+ val source = source?.asSecondOrNull()
349
+
350
+ if (source == null) {
351
+ release()
352
+ return@async
353
+ }
354
+
355
+ val hybridSource = source as? HybridVideoPlayerSource ?: throw PlayerError.InvalidSource
356
+
357
+ val oldSource = this.source as? HybridVideoPlayerSource
358
+ oldSource?.sourceLoader?.cancel()
359
+
360
+ runOnMainThreadSync {
361
+ // Update source
362
+ this.source = source
363
+ player.setMediaSource(hybridSource.mediaSource)
364
+
365
+ // Prepare player
366
+ player.prepare()
367
+ }
368
+ }
369
+ }
370
+
371
+ override fun preload(): Promise<Unit> {
372
+ return Promise.async {
373
+ runOnMainThreadSync {
374
+ if (!loadedWithSource) {
375
+ initializePlayer()
376
+ }
377
+
378
+ if (player.playbackState != Player.STATE_IDLE) {
379
+ return@runOnMainThreadSync
380
+ }
381
+
382
+ player.prepare()
383
+ }
384
+ }
385
+ }
386
+
387
+ override fun release() {
388
+ if (playInBackground || showNotificationControls) {
389
+ VideoPlaybackService.stopService(this, videoPlaybackServiceConnection)
390
+ }
391
+
392
+ runOnMainThread {
393
+ VideoManager.unregisterPlayer(this)
394
+ stopProgressUpdates()
395
+ loadedWithSource = false
396
+
397
+ eventEmitter.clearAllListeners()
398
+
399
+ player.removeListener(playerListener)
400
+ player.removeAnalyticsListener(analyticsListener)
401
+ player.release() // Release player
402
+
403
+ // Clean Listeners
404
+ audioFocusChangedListener.removeEventEmitter()
405
+ audioBecomingNoisyReceiver.removeEventEmitter()
406
+
407
+ // Update status
408
+ status = VideoPlayerStatus.IDLE
409
+ }
410
+ }
411
+
412
+ fun movePlayerToVideoView(videoView: VideoView) {
413
+ VideoManager.addViewToPlayer(videoView, this)
414
+
415
+ runOnMainThreadSync {
416
+ PlayerView.switchTargetView(player, currentPlayerView?.get(), videoView.playerView)
417
+ currentPlayerView = WeakReference(videoView.playerView)
418
+ }
419
+ }
420
+
421
+ override fun dispose() {
422
+ release()
423
+ }
424
+
425
+ override fun close() {
426
+ release()
427
+ }
428
+
429
+ override val memorySize: Long
430
+ // 1 MiB by default
431
+ get() = allocator?.totalBytesAllocated?.toLong() ?: (1024L * 1024L)
432
+
433
+ private fun startProgressUpdates() {
434
+ stopProgressUpdates() // Ensure no multiple runnables
435
+ progressRunnable = object : Runnable {
436
+ override fun run() {
437
+ if (player.playbackState != Player.STATE_IDLE && player.playbackState != Player.STATE_ENDED) {
438
+ val currentTimeSeconds = player.currentPosition / 1000.0
439
+ val bufferedDurationSeconds = player.bufferedPosition / 1000.0
440
+ // bufferDuration is the time from current time that is buffered.
441
+ val playableDurationFromNow = max(0.0, bufferedDurationSeconds - currentTimeSeconds)
442
+
443
+ val durationSeconds = if (player.duration == C.TIME_UNSET) Double.NaN else player.duration / 1000.0
444
+
445
+ eventEmitter.onProgress(
446
+ onProgressData(
447
+ currentTime = currentTimeSeconds,
448
+ duration = durationSeconds,
449
+ bufferDuration = playableDurationFromNow
450
+ )
451
+ )
452
+ progressHandler.postDelayed(this, PROGRESS_UPDATE_INTERVAL_MS)
453
+ }
454
+ }
455
+ }
456
+ progressHandler.post(progressRunnable ?: return)
457
+ }
458
+
459
+ private fun stopProgressUpdates() {
460
+ progressRunnable?.let { progressHandler.removeCallbacks(it) }
461
+ progressRunnable = null
462
+ }
463
+
464
+ private val analyticsListener = object: AnalyticsListener {
465
+ override fun onBandwidthEstimate(
466
+ eventTime: AnalyticsListener.EventTime,
467
+ totalLoadTimeMs: Int,
468
+ totalBytesLoaded: Long,
469
+ bitrateEstimate: Long
470
+ ) {
471
+ val videoFormat = player.videoFormat
472
+ eventEmitter.onBandwidthUpdate(
473
+ BandwidthData(
474
+ bitrate = bitrateEstimate.toDouble(),
475
+ width = if (videoFormat != null) videoFormat.width.toDouble() else null,
476
+ height = if (videoFormat != null) videoFormat.height.toDouble() else null
477
+ )
478
+ )
479
+ }
480
+ }
481
+
482
+ private val playerListener = object : Player.Listener {
483
+ override fun onPlaybackStateChanged(playbackState: Int) {
484
+ val isPlayingUpdate = player.isPlaying
485
+ val isBufferingUpdate = playbackState == Player.STATE_BUFFERING
486
+
487
+ eventEmitter.onPlaybackStateChange(
488
+ onPlaybackStateChangeData(
489
+ isPlaying = isPlayingUpdate,
490
+ isBuffering = isBufferingUpdate
491
+ )
492
+ )
493
+
494
+ when (playbackState) {
495
+ Player.STATE_IDLE -> {
496
+ status = VideoPlayerStatus.IDLE
497
+ eventEmitter.onBuffer(false)
498
+ }
499
+ Player.STATE_BUFFERING -> {
500
+ status = VideoPlayerStatus.LOADING
501
+ eventEmitter.onBuffer(true)
502
+ }
503
+ Player.STATE_READY -> {
504
+ status = VideoPlayerStatus.READYTOPLAY
505
+ eventEmitter.onBuffer(false)
506
+
507
+ val generalVideoFormat = player.videoFormat
508
+ val currentTracks = player.currentTracks
509
+
510
+ val selectedVideoTrackGroup = currentTracks.groups.find { group -> group.type == C.TRACK_TYPE_VIDEO && group.isSelected }
511
+ val selectedVideoTrackFormat = if (selectedVideoTrackGroup != null && selectedVideoTrackGroup.length > 0) {
512
+ selectedVideoTrackGroup.getTrackFormat(0)
513
+ } else {
514
+ null
515
+ }
516
+
517
+ val width = selectedVideoTrackFormat?.width ?: generalVideoFormat?.width ?: 0
518
+ val height = selectedVideoTrackFormat?.height ?: generalVideoFormat?.height ?: 0
519
+ val rotationDegrees = selectedVideoTrackFormat?.rotationDegrees ?: generalVideoFormat?.rotationDegrees
520
+
521
+ eventEmitter.onLoad(
522
+ onLoadData(
523
+ currentTime = player.currentPosition / 1000.0,
524
+ duration = if (player.duration == C.TIME_UNSET) Double.NaN else player.duration / 1000.0,
525
+ width = width.toDouble(),
526
+ height = height.toDouble(),
527
+ orientation = VideoOrientationUtils.fromWHR(width, height, rotationDegrees)
528
+ )
529
+ )
530
+ // If player becomes ready and is set to play, start progress updates
531
+ if (player.playWhenReady) {
532
+ startProgressUpdates()
533
+ }
534
+
535
+ eventEmitter.onReadyToDisplay()
536
+ }
537
+ Player.STATE_ENDED -> {
538
+ status = VideoPlayerStatus.IDLE // Or a specific 'COMPLETED' status if you add one
539
+ eventEmitter.onEnd()
540
+ eventEmitter.onBuffer(false)
541
+ stopProgressUpdates()
542
+ }
543
+ }
544
+ }
545
+
546
+ override fun onIsPlayingChanged(isPlaying: Boolean) {
547
+ super.onIsPlayingChanged(isPlaying)
548
+ eventEmitter.onPlaybackStateChange(
549
+ onPlaybackStateChangeData(
550
+ isPlaying = isPlaying,
551
+ isBuffering = player.playbackState == Player.STATE_BUFFERING
552
+ )
553
+ )
554
+ if (isPlaying) {
555
+ VideoManager.setLastPlayedPlayer(this@HybridVideoPlayer)
556
+ startProgressUpdates()
557
+ } else {
558
+ if (player.playbackState == Player.STATE_ENDED || player.playbackState == Player.STATE_IDLE) {
559
+ stopProgressUpdates()
560
+ }
561
+ }
562
+ }
563
+
564
+ override fun onPlayerError(error: PlaybackException) {
565
+ Log.e(TAG, "Player error: ${error.errorCodeName} - ${error.message}", error)
566
+ status = VideoPlayerStatus.ERROR
567
+ stopProgressUpdates()
568
+ }
569
+
570
+ override fun onPositionDiscontinuity(
571
+ oldPosition: Player.PositionInfo,
572
+ newPosition: Player.PositionInfo,
573
+ reason: Int
574
+ ) {
575
+ if (reason == Player.DISCONTINUITY_REASON_SEEK || reason == Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT) {
576
+ eventEmitter.onSeek(newPosition.positionMs / 1000.0)
577
+ }
578
+ // Update progress immediately after a discontinuity if needed by your logic
579
+ val currentTimeSeconds = newPosition.positionMs / 1000.0
580
+ val bufferedDurationSeconds = player.bufferedPosition / 1000.0
581
+ val durationSeconds = if (player.duration == C.TIME_UNSET) Double.NaN else player.duration / 1000.0
582
+ eventEmitter.onProgress(
583
+ onProgressData(
584
+ currentTime = currentTimeSeconds,
585
+ duration = durationSeconds,
586
+ bufferDuration = max(0.0, bufferedDurationSeconds - currentTimeSeconds)
587
+ )
588
+ )
589
+ }
590
+
591
+ override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters) {
592
+ eventEmitter.onPlaybackRateChange(playbackParameters.speed.toDouble())
593
+ }
594
+
595
+ override fun onVolumeChanged(volume: Float) {
596
+ // We get here device volume changes, and if
597
+ // player is not muted we will sync it
598
+ if (!muted) {
599
+ this@HybridVideoPlayer.volume = volume.toDouble()
600
+ }
601
+
602
+ VideoManager.audioFocusManager.requestAudioFocusUpdate()
603
+ eventEmitter.onVolumeChange(onVolumeChangeData(
604
+ volume = volume.toDouble(),
605
+ muted = muted
606
+ ))
607
+ }
608
+
609
+ override fun onCues(cueGroup: CueGroup) {
610
+ val texts = cueGroup.cues.mapNotNull { it.text?.toString() }
611
+ if (texts.isNotEmpty()) {
612
+ eventEmitter.onTextTrackDataChanged(texts.toTypedArray())
613
+ }
614
+ }
615
+
616
+ override fun onMetadata(metadata: Metadata) {
617
+ val timedMetadataObjects = mutableListOf<TimedMetadataObject>()
618
+ for (i in 0 until metadata.length()) {
619
+ val entry = metadata.get(i)
620
+
621
+ when (entry) {
622
+ is Id3Frame -> {
623
+ var value = ""
624
+
625
+ if (entry is TextInformationFrame) {
626
+ value = entry.values.first()
627
+ }
628
+
629
+ timedMetadataObjects.add(TimedMetadataObject(entry.id, value))
630
+ }
631
+ is EventMessage ->
632
+ timedMetadataObjects.add(TimedMetadataObject(entry.schemeIdUri, entry.value))
633
+ else -> Log.d(TAG, "Unknown metadata: $entry")
634
+ }
635
+ }
636
+ if (timedMetadataObjects.isNotEmpty()) {
637
+ eventEmitter.onTimedMetadata(TimedMetadata(metadata = timedMetadataObjects.toTypedArray()))
638
+ }
639
+ }
640
+
641
+ override fun onTracksChanged(tracks: Tracks) {
642
+ super.onTracksChanged(tracks)
643
+ }
644
+ }
645
+
646
+ // MARK: - Frame Capture
647
+
648
+ override fun captureFrame(): Promise<String> {
649
+ return Promise.async {
650
+ val hybridSource = source as? HybridVideoPlayerSource
651
+ ?: throw PlayerError.InvalidSource
652
+
653
+ // Try to capture from TextureView first (if using texture surface type)
654
+ val textureViewBitmap = runOnMainThreadSync {
655
+ try {
656
+ val playerView = currentPlayerView?.get()
657
+ if (playerView != null) {
658
+ // Find TextureView in the player view hierarchy
659
+ for (i in 0 until playerView.childCount) {
660
+ val child = playerView.getChildAt(i)
661
+ if (child is TextureView && child.isAvailable) {
662
+ return@runOnMainThreadSync child.bitmap
663
+ }
664
+ }
665
+ }
666
+ null
667
+ } catch (e: Exception) {
668
+ Log.w(TAG, "Failed to capture from TextureView", e)
669
+ null
670
+ }
671
+ }
672
+
673
+ if (textureViewBitmap != null) {
674
+ return@async bitmapToBase64(textureViewBitmap)
675
+ }
676
+
677
+ // Fallback: Use MediaMetadataRetriever for frame extraction
678
+ val retriever = MediaMetadataRetriever()
679
+ try {
680
+ val uri = hybridSource.uri
681
+ if (uri.startsWith("http://") || uri.startsWith("https://")) {
682
+ retriever.setDataSource(uri, HashMap())
683
+ } else {
684
+ retriever.setDataSource(context, android.net.Uri.parse(uri))
685
+ }
686
+
687
+ // Get frame at current position (in microseconds)
688
+ val currentPositionUs = (currentTime * 1_000_000).toLong()
689
+ val bitmap = retriever.getFrameAtTime(
690
+ currentPositionUs,
691
+ MediaMetadataRetriever.OPTION_CLOSEST_SYNC
692
+ ) ?: throw PlayerError.NotInitialized
693
+
694
+ return@async bitmapToBase64(bitmap)
695
+ } catch (e: Exception) {
696
+ Log.e(TAG, "Failed to capture frame", e)
697
+ throw PlayerError.NotInitialized
698
+ } finally {
699
+ try {
700
+ retriever.release()
701
+ } catch (e: Exception) {
702
+ Log.w(TAG, "Failed to release MediaMetadataRetriever", e)
703
+ }
704
+ }
705
+ }
706
+ }
707
+
708
+ private fun bitmapToBase64(bitmap: Bitmap): String {
709
+ val outputStream = ByteArrayOutputStream()
710
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
711
+ val byteArray = outputStream.toByteArray()
712
+ return Base64.encodeToString(byteArray, Base64.NO_WRAP)
713
+ }
714
+
715
+ // MARK: - Text Track Management
716
+
717
+ override fun getAvailableTextTracks(): Array<TextTrack> {
718
+ return TextTrackUtils.getAvailableTextTracks(player, source)
719
+ }
720
+
721
+ override fun selectTextTrack(textTrack: Variant_NullType_TextTrack?) {
722
+ selectedExternalTrackIndex = TextTrackUtils.selectTextTrack(
723
+ player = player,
724
+ textTrack = textTrack?.asSecondOrNull(),
725
+ source = source,
726
+ onTrackChange = { track -> eventEmitter.onTrackChange(track) }
727
+ )
728
+ }
729
+
730
+ override val selectedTrack: TextTrack?
731
+ get() = TextTrackUtils.getSelectedTrack(player, source)
732
+ }