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,697 @@
1
+ //
2
+ // HybridVideoPlayer.swift
3
+ // ReactNativeVideo
4
+ //
5
+ // Created by Krzysztof Moch on 09/10/2024.
6
+ // MobileVLCKit backend for HLS (MediaMTX-style manifests, relative .ts
7
+ // segments resolved by VLC against the playlist URL).
8
+ //
9
+
10
+ import Foundation
11
+ import MobileVLCKit
12
+ import NitroModules
13
+
14
+ // MARK: - HLS / network tuning (conservative defaults; override via source headers if needed)
15
+
16
+ private enum VLCHLSDefaults {
17
+ /// Milliseconds of media to prefetch before playback resumes.
18
+ /// VLC sits buffering for at least this long after every seek, so we
19
+ /// keep it small for VOD HLS (recordings) where the user expects scrub
20
+ /// to land near-instantly. Bump back up if you see frequent stutter.
21
+ static let networkCachingMs = 300
22
+ /// Same as above but only used when libvlc tags the stream as live; our
23
+ /// MediaMTX recordings are VOD, so this almost never applies. Keep it
24
+ /// low so the rare live tail doesn't add seconds of pre-roll.
25
+ static let liveCachingMs = 300
26
+ }
27
+
28
+ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
29
+
30
+ public let mediaPlayer: VLCMediaPlayer
31
+ private var media: VLCMedia?
32
+ private var vlcDelegates: VLCPlaybackDelegates?
33
+
34
+ /// Local 127.0.0.1 HTTP proxy used to inject Authorization on HLS
35
+ /// manifest + segment fetches. libvlc 3.x ignores `--http-header(s)`,
36
+ /// so we point VLC at this proxy when the JS layer passes an
37
+ /// Authorization header. nil when the source is unauthenticated.
38
+ private var authProxy: HLSAuthProxy?
39
+
40
+ private var lastReportedRate: Double = 1.0
41
+ private var hasFiredOnLoad: Bool = false
42
+ private var hasFiredOnLoadStart: Bool = false
43
+ private var lastEmittedIsPlaying: Bool = false
44
+ private var lastEmittedIsBuffering: Bool = false
45
+ private var pendingSeekSeconds: Double? = nil
46
+ private var hasEmittedEndForCurrentItem: Bool = false
47
+
48
+ /// Monotonic playback time from VLC; used by the stall watchdog.
49
+ private var lastProgressTimeSeconds: Double = 0
50
+ private var lastProgressTickMonotonic: TimeInterval = 0
51
+
52
+ private var stallCheckTimer: Timer?
53
+ private var reconnectAttempts: Int = 0
54
+ private static let maxAutoReconnects = 3
55
+ private static let stallNoProgressSeconds: TimeInterval = 4.0
56
+ private static let stallCheckIntervalSeconds: TimeInterval = 1.0
57
+
58
+ /// JS called `play()` before a `UIView` drawable existed — iOS VLC often
59
+ /// needs the drawable before demux/decode can finish; we re-issue `play()`
60
+ /// from `VideoComponentView` when the surface attaches.
61
+ private var wantsPlaybackWhenDrawableReady: Bool = false
62
+
63
+ init(source: (any HybridVideoPlayerSourceSpec)) throws {
64
+ self.source = source
65
+ self.eventEmitter = HybridVideoPlayerEventEmitter()
66
+ self.mediaPlayer = VLCMediaPlayer()
67
+
68
+ super.init()
69
+
70
+ let delegates = VLCPlaybackDelegates(owner: self)
71
+ self.vlcDelegates = delegates
72
+ self.mediaPlayer.delegate = delegates
73
+
74
+ if source.config.initializeOnCreation == true {
75
+ attachMedia()
76
+ }
77
+
78
+ VideoManager.shared.register(player: self)
79
+ startStallWatchdogIfNeeded()
80
+ }
81
+
82
+ deinit {
83
+ invalidateStallWatchdog()
84
+ release()
85
+ }
86
+
87
+ // MARK: - HybridVideoPlayerSpec
88
+
89
+ var source: any HybridVideoPlayerSourceSpec
90
+
91
+ var status: VideoPlayerStatus = .idle {
92
+ didSet {
93
+ if status != oldValue {
94
+ _eventEmitter?.onStatusChange(status)
95
+ }
96
+ }
97
+ }
98
+
99
+ var eventEmitter: HybridVideoPlayerEventEmitterSpec
100
+ var _eventEmitter: HybridVideoPlayerEventEmitter? {
101
+ return eventEmitter as? HybridVideoPlayerEventEmitter
102
+ }
103
+
104
+ var volume: Double {
105
+ set {
106
+ let clamped = max(0, min(1, newValue))
107
+ mediaPlayer.audio?.volume = Int32(clamped * 100)
108
+ _eventEmitter?.onVolumeChange(
109
+ onVolumeChangeData(volume: clamped, muted: muted)
110
+ )
111
+ }
112
+ get {
113
+ let v = Int(mediaPlayer.audio?.volume ?? 100)
114
+ return Double(v) / 100.0
115
+ }
116
+ }
117
+
118
+ private var _muted: Bool = false
119
+ var muted: Bool {
120
+ set {
121
+ _muted = newValue
122
+ mediaPlayer.audio?.setMute(newValue)
123
+ _eventEmitter?.onVolumeChange(
124
+ onVolumeChangeData(volume: volume, muted: newValue)
125
+ )
126
+ }
127
+ get { _muted }
128
+ }
129
+
130
+ var currentTime: Double {
131
+ set {
132
+ let target = max(0, newValue)
133
+ _eventEmitter?.onSeek(target)
134
+ markUserInitiatedTransport()
135
+ applySeek(seconds: target)
136
+ }
137
+ get {
138
+ let ms = mediaPlayer.time.intValue
139
+ if ms < 0 { return Double.nan }
140
+ return Double(ms) / 1000.0
141
+ }
142
+ }
143
+
144
+ var duration: Double {
145
+ let ms = mediaPlayer.media?.length.intValue ?? 0
146
+ if ms <= 0 { return Double.nan }
147
+ return Double(ms) / 1000.0
148
+ }
149
+
150
+ var rate: Double {
151
+ set {
152
+ let clamped = max(0, newValue)
153
+ mediaPlayer.rate = Float(clamped)
154
+ lastReportedRate = clamped
155
+ _eventEmitter?.onPlaybackRateChange(clamped)
156
+ }
157
+ get {
158
+ return Double(mediaPlayer.rate)
159
+ }
160
+ }
161
+
162
+ var loop: Bool = false
163
+
164
+ var mixAudioMode: MixAudioMode = .auto {
165
+ didSet { VideoManager.shared.requestAudioSessionUpdate() }
166
+ }
167
+
168
+ var ignoreSilentSwitchMode: IgnoreSilentSwitchMode = .auto {
169
+ didSet { VideoManager.shared.requestAudioSessionUpdate() }
170
+ }
171
+
172
+ var playInBackground: Bool = false {
173
+ didSet { VideoManager.shared.requestAudioSessionUpdate() }
174
+ }
175
+
176
+ var playWhenInactive: Bool = false
177
+
178
+ var wasAutoPaused: Bool = false
179
+
180
+ var isCurrentlyBuffering: Bool = false
181
+
182
+ var isPlaying: Bool {
183
+ return mediaPlayer.isPlaying
184
+ }
185
+
186
+ var showNotificationControls: Bool = false
187
+
188
+ var preventsDisplaySleepDuringVideoPlayback: Bool = true
189
+
190
+ func initialize() throws -> Promise<Void> {
191
+ let promise = Promise<Void>()
192
+ if media != nil {
193
+ promise.resolve(withResult: ())
194
+ return promise
195
+ }
196
+ attachMedia()
197
+ promise.resolve(withResult: ())
198
+ return promise
199
+ }
200
+
201
+ func release() {
202
+ invalidateStallWatchdog()
203
+ if mediaPlayer.isPlaying {
204
+ mediaPlayer.stop()
205
+ }
206
+ media?.delegate = nil
207
+ media = nil
208
+ mediaPlayer.media = nil
209
+ mediaPlayer.delegate = nil
210
+ vlcDelegates = nil
211
+
212
+ authProxy?.stop()
213
+ authProxy = nil
214
+
215
+ try? _eventEmitter?.clearAllListeners()
216
+
217
+ wantsPlaybackWhenDrawableReady = false
218
+ status = .idle
219
+ hasFiredOnLoad = false
220
+ hasFiredOnLoadStart = false
221
+ pendingSeekSeconds = nil
222
+ hasEmittedEndForCurrentItem = false
223
+ reconnectAttempts = 0
224
+ lastProgressTimeSeconds = 0
225
+ lastProgressTickMonotonic = 0
226
+
227
+ VideoManager.shared.unregister(player: self)
228
+ }
229
+
230
+ func preload() throws -> Promise<Void> {
231
+ let promise = Promise<Void>()
232
+ if media == nil {
233
+ attachMedia()
234
+ }
235
+ promise.resolve(withResult: ())
236
+ return promise
237
+ }
238
+
239
+ func play() throws {
240
+ wantsPlaybackWhenDrawableReady = true
241
+ mediaPlayer.play()
242
+ VideoManager.shared.requestAudioSessionUpdate()
243
+ }
244
+
245
+ func pause() throws {
246
+ wantsPlaybackWhenDrawableReady = false
247
+ if mediaPlayer.canPause {
248
+ mediaPlayer.pause()
249
+ } else {
250
+ mediaPlayer.stop()
251
+ }
252
+ VideoManager.shared.requestAudioSessionUpdate()
253
+ }
254
+
255
+ /// Called from `VideoComponentView` after `mediaPlayer.drawable` is set.
256
+ func notifyVideoHostViewAttached() {
257
+ if wantsPlaybackWhenDrawableReady, media != nil {
258
+ mediaPlayer.play()
259
+ }
260
+ maybeFireOnLoad()
261
+ }
262
+
263
+ func seekBy(time: Double) throws {
264
+ let cur = currentTime
265
+ let base = cur.isFinite ? cur : 0
266
+ let target = base + time
267
+ let total = duration
268
+ let bounded =
269
+ total.isFinite && total > 0
270
+ ? min(max(0, target), total)
271
+ : max(0, target)
272
+ currentTime = bounded
273
+ }
274
+
275
+ func seekTo(time: Double) {
276
+ currentTime = time
277
+ }
278
+
279
+ func replaceSourceAsync(
280
+ source: Variant_NullType__any_HybridVideoPlayerSourceSpec_?
281
+ ) throws -> Promise<Void> {
282
+ let promise = Promise<Void>()
283
+
284
+ guard let source else {
285
+ release()
286
+ promise.resolve(withResult: ())
287
+ return promise
288
+ }
289
+
290
+ switch source {
291
+ case .first(_):
292
+ release()
293
+ promise.resolve(withResult: ())
294
+ case .second(let newSource):
295
+ wantsPlaybackWhenDrawableReady = false
296
+ invalidateStallWatchdog()
297
+ if mediaPlayer.isPlaying {
298
+ mediaPlayer.stop()
299
+ }
300
+ media?.delegate = nil
301
+ media = nil
302
+ mediaPlayer.media = nil
303
+
304
+ authProxy?.stop()
305
+ authProxy = nil
306
+
307
+ self.source = newSource
308
+ hasFiredOnLoad = false
309
+ hasFiredOnLoadStart = false
310
+ pendingSeekSeconds = nil
311
+ hasEmittedEndForCurrentItem = false
312
+ reconnectAttempts = 0
313
+ attachMedia()
314
+ startStallWatchdogIfNeeded()
315
+ promise.resolve(withResult: ())
316
+ }
317
+
318
+ return promise
319
+ }
320
+
321
+ func getAvailableTextTracks() throws -> [TextTrack] { return [] }
322
+
323
+ func selectTextTrack(textTrack: Variant_NullType_TextTrack?) throws { /* no-op */ }
324
+
325
+ var selectedTrack: TextTrack? { nil }
326
+
327
+ func captureFrame() throws -> Promise<String> {
328
+ let promise = Promise<String>()
329
+ promise.reject(withError: PlayerError.notInitialized.error())
330
+ return promise
331
+ }
332
+
333
+ func dispose() { release() }
334
+
335
+ var memorySize: Int { 0 }
336
+
337
+ // MARK: - VLCPlaybackDelegateOwner
338
+
339
+ func vlcMediaPlayerStateDidChange() {
340
+ handleStateChange()
341
+ }
342
+
343
+ func vlcMediaPlayerTimeDidChange() {
344
+ handleTimeChange()
345
+ }
346
+
347
+ func vlcMediaMetaDataDidChange(_ media: VLCMedia) {
348
+ _ = media
349
+ flushPendingSeek()
350
+ maybeFireOnLoad()
351
+ }
352
+
353
+ func vlcMediaDidFinishParsing(_ media: VLCMedia) {
354
+ _ = media
355
+ flushPendingSeek()
356
+ maybeFireOnLoad()
357
+ }
358
+
359
+ // MARK: - Internal helpers
360
+
361
+ private func attachMedia() {
362
+ guard let hybridSource = source as? HybridVideoPlayerSource else {
363
+ status = .error
364
+ return
365
+ }
366
+
367
+ // Tear down any previous proxy before we (maybe) start a new one.
368
+ authProxy?.stop()
369
+ authProxy = nil
370
+
371
+ var mediaURL = hybridSource.url
372
+ var residualHeaders: [String: String] = [:]
373
+ var bearerToken: String? = nil
374
+
375
+ if let headers = hybridSource.config.headers, !headers.isEmpty {
376
+ for (key, value) in headers {
377
+ if key.lowercased() == "authorization" {
378
+ // "Bearer xyz" or raw token — strip the scheme prefix; the
379
+ // proxy re-prepends "Bearer " uniformly on forward.
380
+ let trimmed = value.trimmingCharacters(in: .whitespaces)
381
+ if trimmed.lowercased().hasPrefix("bearer ") {
382
+ bearerToken = String(trimmed.dropFirst(7)).trimmingCharacters(in: .whitespaces)
383
+ } else {
384
+ bearerToken = trimmed
385
+ }
386
+ } else {
387
+ residualHeaders[key] = value
388
+ }
389
+ }
390
+ }
391
+
392
+ // libvlc 3.x has no `--http-header(s)`, so a JS-supplied Authorization
393
+ // never reaches segment fetches. Route everything through a local
394
+ // proxy that injects the bearer on each upstream request. UA / Referer
395
+ // are still applied via the supported libvlc options below.
396
+ if let token = bearerToken,
397
+ let scheme = mediaURL.scheme?.lowercased(),
398
+ scheme == "http" || scheme == "https"
399
+ {
400
+ let proxy = HLSAuthProxy(originURL: mediaURL, bearerToken: token)
401
+ do {
402
+ try proxy.start()
403
+ if let localURL = buildLocalProxyURL(from: mediaURL, port: proxy.port) {
404
+ self.authProxy = proxy
405
+ mediaURL = localURL
406
+ } else {
407
+ proxy.stop()
408
+ }
409
+ } catch {
410
+ // Fall through with the original URL — playback will still fail
411
+ // upstream, but at least the player surfaces VLC's own error
412
+ // rather than a silent local-proxy failure.
413
+ }
414
+ }
415
+
416
+ let media = VLCMedia(url: mediaURL)
417
+
418
+ applyHlsNetworkOptions(to: media)
419
+
420
+ for (key, value) in residualHeaders {
421
+ switch key.lowercased() {
422
+ case "user-agent":
423
+ media.addOption(":http-user-agent=\(value)")
424
+ case "referer", "referrer":
425
+ media.addOption(":http-referrer=\(value)")
426
+ default:
427
+ // libvlc 3.x silently ignores arbitrary headers; skip rather than
428
+ // pretending we forwarded them.
429
+ break
430
+ }
431
+ }
432
+
433
+ media.delegate = vlcDelegates
434
+ self.media = media
435
+ mediaPlayer.media = media
436
+
437
+ if !hasFiredOnLoadStart {
438
+ hasFiredOnLoadStart = true
439
+ // Classify by the *original* source URL, not the loopback rewrite —
440
+ // a proxied https origin is still a network source.
441
+ let isNetworkSource = !hybridSource.url.isFileURL
442
+ _eventEmitter?.onLoadStart(
443
+ onLoadStartData(
444
+ sourceType: isNetworkSource ? .network : .local,
445
+ source: hybridSource
446
+ )
447
+ )
448
+ }
449
+
450
+ status = .loading
451
+ setBuffering(true)
452
+ hasEmittedEndForCurrentItem = false
453
+ }
454
+
455
+ /// Rewrite an http(s) URL to point at the local auth proxy on
456
+ /// 127.0.0.1:<port> while preserving path + query so VLC's relative
457
+ /// segment resolution keeps targeting the proxy.
458
+ private func buildLocalProxyURL(from origin: URL, port: UInt16) -> URL? {
459
+ guard
460
+ var components = URLComponents(url: origin, resolvingAgainstBaseURL: false)
461
+ else { return nil }
462
+ components.scheme = "http"
463
+ components.host = "127.0.0.1"
464
+ components.port = Int(port)
465
+ components.user = nil
466
+ components.password = nil
467
+ return components.url
468
+ }
469
+
470
+ private func applyHlsNetworkOptions(to media: VLCMedia) {
471
+ media.addOption(":network-caching=\(VLCHLSDefaults.networkCachingMs)")
472
+ media.addOption(":live-caching=\(VLCHLSDefaults.liveCachingMs)")
473
+ // HLS over HTTP benefits from reconnect; harmless for file URLs.
474
+ media.addOption(":http-reconnect=true")
475
+ }
476
+
477
+ /// Resets stall-watchdog liveness so a long seek / buffer gap is not mistaken for a dead stream.
478
+ private func markUserInitiatedTransport() {
479
+ lastProgressTickMonotonic = ProcessInfo.processInfo.systemUptime
480
+ }
481
+
482
+ private func applySeek(seconds target: Double) {
483
+ let ms = Int32(min(Double(Int32.max), max(0, target * 1000.0)))
484
+
485
+ if mediaPlayer.isSeekable {
486
+ mediaPlayer.time = VLCTime(int: ms)
487
+ pendingSeekSeconds = nil
488
+ return
489
+ }
490
+
491
+ let totalMs = Double(media?.length.intValue ?? 0)
492
+ if totalMs > 0 {
493
+ let position = Float(min(1.0, (Double(ms)) / totalMs))
494
+ mediaPlayer.position = position
495
+ pendingSeekSeconds = nil
496
+ } else {
497
+ pendingSeekSeconds = target
498
+ }
499
+ }
500
+
501
+ private func handleStateChange() {
502
+ let state = mediaPlayer.state
503
+ switch state {
504
+ case .opening:
505
+ status = .loading
506
+ setBuffering(true)
507
+
508
+ case .buffering:
509
+ markUserInitiatedTransport()
510
+ setBuffering(true)
511
+ if status != .readytoplay {
512
+ status = .loading
513
+ }
514
+
515
+ case .playing:
516
+ setBuffering(false)
517
+ status = .readytoplay
518
+ maybeFireOnLoad()
519
+ flushPendingSeek()
520
+ reconnectAttempts = 0
521
+ VideoManager.shared.requestAudioSessionUpdate()
522
+
523
+ case .paused:
524
+ setBuffering(false)
525
+ if status == .loading { status = .readytoplay }
526
+ VideoManager.shared.requestAudioSessionUpdate()
527
+
528
+ case .stopped, .ended:
529
+ setBuffering(false)
530
+ if !hasEmittedEndForCurrentItem {
531
+ hasEmittedEndForCurrentItem = true
532
+ _eventEmitter?.onEnd()
533
+ }
534
+ if loop {
535
+ hasEmittedEndForCurrentItem = false
536
+ currentTime = 0
537
+ try? play()
538
+ }
539
+
540
+ case .error:
541
+ setBuffering(false)
542
+ status = .error
543
+ // JS layer maps `error` status → `onError` (see VideoPlayer.ts).
544
+
545
+ default:
546
+ break
547
+ }
548
+
549
+ emitPlaybackState()
550
+ }
551
+
552
+ private func handleTimeChange() {
553
+ let cur = currentTime
554
+ let dur = duration
555
+ if cur.isFinite {
556
+ lastProgressTimeSeconds = cur
557
+ lastProgressTickMonotonic = ProcessInfo.processInfo.systemUptime
558
+ }
559
+
560
+ _eventEmitter?.onProgress(
561
+ onProgressData(
562
+ currentTime: cur.isFinite ? cur : 0,
563
+ duration: dur.isFinite ? dur : Double.nan,
564
+ bufferDuration: 0
565
+ )
566
+ )
567
+ flushPendingSeek()
568
+ maybeFireOnLoad()
569
+ }
570
+
571
+ private func setBuffering(_ buffering: Bool) {
572
+ isCurrentlyBuffering = buffering
573
+ }
574
+
575
+ private func emitPlaybackState() {
576
+ let playing = mediaPlayer.isPlaying && !isCurrentlyBuffering
577
+ if playing != lastEmittedIsPlaying || isCurrentlyBuffering != lastEmittedIsBuffering {
578
+ lastEmittedIsPlaying = playing
579
+ lastEmittedIsBuffering = isCurrentlyBuffering
580
+ _eventEmitter?.onPlaybackStateChange(
581
+ onPlaybackStateChangeData(isPlaying: playing, isBuffering: isCurrentlyBuffering)
582
+ )
583
+ _eventEmitter?.onBuffer(isCurrentlyBuffering)
584
+ }
585
+ }
586
+
587
+ private func maybeFireOnLoad() {
588
+ guard !hasFiredOnLoad else { return }
589
+ let dur = duration
590
+ let hasDuration = dur.isFinite && dur > 0
591
+ let size = mediaPlayer.videoSize
592
+ let hasVideo = size.width > 0 && size.height > 0
593
+ // VOD HLS from MediaMTX may keep length at 0 until the playlist is fully
594
+ // parsed; still emit onLoad once we are playing or have decoded dimensions
595
+ // so JS overlays (e.g. preroll spinner) can clear.
596
+ if !hasDuration && !mediaPlayer.isPlaying && !hasVideo {
597
+ return
598
+ }
599
+ hasFiredOnLoad = true
600
+ let width = Double(size.width)
601
+ let height = Double(size.height)
602
+ let orientation: VideoOrientation =
603
+ height > width ? .portrait : (width > height ? .landscape : .square)
604
+ let ct = currentTime
605
+ _eventEmitter?.onLoad(
606
+ onLoadData(
607
+ currentTime: ct.isFinite ? ct : 0,
608
+ duration: dur.isFinite ? dur : Double.nan,
609
+ height: height,
610
+ width: width,
611
+ orientation: orientation
612
+ )
613
+ )
614
+ _eventEmitter?.onReadyToDisplay()
615
+ }
616
+
617
+ private func flushPendingSeek() {
618
+ guard let target = pendingSeekSeconds else { return }
619
+ applySeek(seconds: target)
620
+ }
621
+
622
+ // MARK: - Stall detection + reconnect
623
+
624
+ private func startStallWatchdogIfNeeded() {
625
+ invalidateStallWatchdog()
626
+ let timer = Timer.scheduledTimer(withTimeInterval: Self.stallCheckIntervalSeconds, repeats: true) {
627
+ [weak self] _ in
628
+ self?.evaluatePlaybackStall()
629
+ }
630
+ RunLoop.main.add(timer, forMode: .common)
631
+ stallCheckTimer = timer
632
+ }
633
+
634
+ private func invalidateStallWatchdog() {
635
+ stallCheckTimer?.invalidate()
636
+ stallCheckTimer = nil
637
+ }
638
+
639
+ private func evaluatePlaybackStall() {
640
+ guard media != nil else { return }
641
+ guard mediaPlayer.isPlaying else { return }
642
+ guard !isCurrentlyBuffering else { return }
643
+ guard status == .readytoplay else { return }
644
+
645
+ let now = ProcessInfo.processInfo.systemUptime
646
+ let idle = now - lastProgressTickMonotonic
647
+ guard idle > Self.stallNoProgressSeconds else { return }
648
+
649
+ // Genuine stall: VLC still claims "playing" but time is not advancing.
650
+ trySoftRecovery()
651
+ }
652
+
653
+ private func trySoftRecovery() {
654
+ let savedTime = lastProgressTimeSeconds
655
+
656
+ mediaPlayer.pause()
657
+ mediaPlayer.play()
658
+
659
+ DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) { [weak self] in
660
+ guard let self else { return }
661
+ guard self.mediaPlayer.isPlaying else { return }
662
+ let progressed =
663
+ abs(self.lastProgressTimeSeconds - savedTime) > 0.25
664
+ if !progressed {
665
+ self.performAutoReconnect(resumeNear: savedTime)
666
+ } else {
667
+ self.reconnectAttempts = 0
668
+ }
669
+ }
670
+ }
671
+
672
+ private func performAutoReconnect(resumeNear seconds: Double) {
673
+ guard reconnectAttempts < Self.maxAutoReconnects else { return }
674
+ reconnectAttempts += 1
675
+ markUserInitiatedTransport()
676
+
677
+ let resume = max(0, seconds)
678
+ guard let hybridSource = source as? HybridVideoPlayerSource else { return }
679
+
680
+ mediaPlayer.stop()
681
+ media?.delegate = nil
682
+ media = nil
683
+ mediaPlayer.media = nil
684
+
685
+ hasFiredOnLoad = false
686
+ hasEmittedEndForCurrentItem = false
687
+
688
+ attachMedia()
689
+ mediaPlayer.play()
690
+
691
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) { [weak self] in
692
+ guard let self else { return }
693
+ self.currentTime = resume
694
+ }
695
+ }
696
+
697
+ }
@@ -0,0 +1,15 @@
1
+ //
2
+ // HybridVideoPlayerFactory.swift
3
+ // ReactNativeVideo
4
+ //
5
+ // Created by Krzysztof Moch on 09/10/2024.
6
+ //
7
+
8
+ import Foundation
9
+ import NitroModules
10
+
11
+ class HybridVideoPlayerFactory: HybridVideoPlayerFactorySpec {
12
+ func createPlayer(source: HybridVideoPlayerSourceSpec) throws -> HybridVideoPlayerSpec {
13
+ return try HybridVideoPlayer(source: source)
14
+ }
15
+ }