react-native-queue-player 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/QueuePlayer.podspec +14 -9
  2. package/README.md +3 -3
  3. package/android/build.gradle +7 -0
  4. package/android/consumer-rules.pro +72 -3
  5. package/android/src/main/cpp/airplay2_control.c +4 -4
  6. package/android/src/main/cpp/airplay2_control.h +4 -4
  7. package/android/src/main/cpp/airplay2_jni.cpp +26 -22
  8. package/android/src/main/cpp/airplay2_pair.c +7 -7
  9. package/android/src/main/cpp/airplay2_pair.h +2 -2
  10. package/android/src/main/cpp/airplay2_rtsp.c +8 -8
  11. package/android/src/main/cpp/airplay2_session.c +2 -2
  12. package/android/src/main/cpp/airplay_jni.cpp +20 -72
  13. package/android/src/main/java/com/margelo/nitro/queueplayer/AirPlayEngine.kt +7 -16
  14. package/android/src/main/java/com/margelo/nitro/queueplayer/CacheMimeTypes.kt +1 -1
  15. package/android/src/main/java/com/margelo/nitro/queueplayer/CastManager.kt +2 -14
  16. package/android/src/main/java/com/margelo/nitro/queueplayer/CellularTransportMonitor.kt +77 -0
  17. package/android/src/main/java/com/margelo/nitro/queueplayer/CrossfadeEngine.kt +187 -52
  18. package/android/src/main/java/com/margelo/nitro/queueplayer/Equalizer.kt +27 -7
  19. package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerEngine.kt +33 -12
  20. package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngine.kt +31 -8
  21. package/android/src/main/java/com/margelo/nitro/queueplayer/FFTProcessorTee.kt +45 -30
  22. package/android/src/main/java/com/margelo/nitro/queueplayer/FifoCacheEvictor.kt +111 -15
  23. package/android/src/main/java/com/margelo/nitro/queueplayer/GaplessEngine.kt +60 -33
  24. package/android/src/main/java/com/margelo/nitro/queueplayer/HeadlessJsMediaService.kt +1 -1
  25. package/android/src/main/java/com/margelo/nitro/queueplayer/IEqualizerEngine.kt +3 -1
  26. package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCache.kt +103 -29
  27. package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCacheWriter.kt +77 -29
  28. package/android/src/main/java/com/margelo/nitro/queueplayer/MediaItemBuilder.kt +6 -6
  29. package/android/src/main/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractor.kt +48 -1
  30. package/android/src/main/java/com/margelo/nitro/queueplayer/PitchCorrection.kt +3 -2
  31. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackEngine.kt +71 -76
  32. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackErrorMapping.kt +3 -3
  33. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackModeStateMachine.kt +2 -2
  34. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackService.kt +68 -46
  35. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackServiceCallback.kt +6 -5
  36. package/android/src/main/java/com/margelo/nitro/queueplayer/QueueMutationArithmetic.kt +5 -6
  37. package/android/src/main/java/com/margelo/nitro/queueplayer/QueueSkipArithmetic.kt +11 -8
  38. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessor.kt +26 -6
  39. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainData.kt +22 -3
  40. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainExtractor.kt +38 -12
  41. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainGain.kt +17 -13
  42. package/android/src/main/java/com/margelo/nitro/queueplayer/SuppliedReplayGain.kt +66 -0
  43. package/android/src/main/java/com/margelo/nitro/queueplayer/TrackPlayer.kt +870 -278
  44. package/android/src/main/java/com/margelo/nitro/queueplayer/Visualizer.kt +4 -8
  45. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastBackend.kt +4 -3
  46. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastEventBridge.kt +1 -10
  47. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastSession.kt +17 -3
  48. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastTransportRouter.kt +19 -0
  49. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/RemotePlaybackStateMapping.kt +18 -0
  50. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2JNI.kt +0 -2
  51. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2Session.kt +23 -12
  52. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayBackend.kt +16 -9
  53. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayMetadataSync.kt +58 -21
  54. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayRenderersFactory.kt +6 -14
  55. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlaySession.kt +26 -14
  56. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirplayJNI.kt +1 -13
  57. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/MetadataSyncTarget.kt +20 -0
  58. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/MulticastLockHolder.kt +1 -1
  59. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/chromecast/ChromecastBackend.kt +3 -3
  60. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/chromecast/ChromecastSession.kt +73 -13
  61. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServer.kt +11 -35
  62. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaServerHandle.kt +0 -5
  63. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaTokenRegistry.kt +0 -6
  64. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitor.kt +32 -33
  65. package/android/src/test/java/androidx/media3/session/{MediaSessionControllerRequestTestSeam.kt → MediaSessionControllerRequestTestSupport.kt} +1 -1
  66. package/android/src/test/java/com/margelo/nitro/queueplayer/AvrcpMetadataTest.kt +12 -0
  67. package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineFocusLossTest.kt +115 -0
  68. package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineLifecycleTest.kt +45 -0
  69. package/android/src/test/java/com/margelo/nitro/queueplayer/EngineEndSignalOrderTest.kt +70 -0
  70. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerEngineTest.kt +23 -12
  71. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerKtTest.kt +0 -6
  72. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngineTest.kt +43 -15
  73. package/android/src/test/java/com/margelo/nitro/queueplayer/FFTProcessorTeeTest.kt +15 -0
  74. package/android/src/test/java/com/margelo/nitro/queueplayer/FifoCacheEvictorTest.kt +135 -4
  75. package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineLifecycleTest.kt +1 -0
  76. package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineReplayGainTest.kt +36 -2
  77. package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheTest.kt +24 -18
  78. package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterCancelTest.kt +85 -0
  79. package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterTest.kt +112 -1
  80. package/android/src/test/java/com/margelo/nitro/queueplayer/MediaItemBuilderTest.kt +5 -3
  81. package/android/src/test/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractorTest.kt +45 -0
  82. package/android/src/test/java/com/margelo/nitro/queueplayer/PitchAwareAudioProcessorChainTest.kt +1 -1
  83. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackSearchTest.kt +47 -0
  84. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackTest.kt +53 -29
  85. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceLifecycleTest.kt +8 -8
  86. package/android/src/test/java/com/margelo/nitro/queueplayer/QueueSkipArithmeticTest.kt +33 -1
  87. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessorTest.kt +128 -5
  88. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainExtractorTest.kt +209 -14
  89. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainGainTest.kt +150 -10
  90. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainMergeTest.kt +258 -0
  91. package/android/src/test/java/com/margelo/nitro/queueplayer/RobolectricServiceBindHelper.kt +8 -4
  92. package/android/src/test/java/com/margelo/nitro/queueplayer/SessionCommandForwardingPlayerTest.kt +2 -2
  93. package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowDynamicsProcessingRejectingEnable.kt +19 -0
  94. package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizer.kt +68 -0
  95. package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizerRejectingBandWrites.kt +27 -0
  96. package/android/src/test/java/com/margelo/nitro/queueplayer/SuppliedReplayGainTest.kt +61 -0
  97. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAirPlayMetadataWiringTest.kt +4 -4
  98. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAudioFocusTest.kt +1 -1
  99. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastCommandRoutingTest.kt +163 -0
  100. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastStateTest.kt +123 -0
  101. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerEventsTest.kt +88 -38
  102. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLifecycleTest.kt +205 -27
  103. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLookaheadConfigTest.kt +277 -38
  104. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerMutationTest.kt +5 -3
  105. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerProgressThrottleTest.kt +2 -1
  106. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueChangeTest.kt +85 -3
  107. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueTest.kt +11 -7
  108. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerReadersTest.kt +2 -1
  109. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipCapabilityTest.kt +90 -4
  110. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipTest.kt +8 -26
  111. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerTransportTest.kt +3 -3
  112. package/android/src/test/java/com/margelo/nitro/queueplayer/VisualizerKtTest.kt +0 -4
  113. package/android/src/test/java/com/margelo/nitro/queueplayer/cast/FakeRemotePlayer.kt +27 -11
  114. package/android/src/test/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayMetadataSyncTest.kt +303 -0
  115. package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitorTest.kt +173 -0
  116. package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/ShadowConnectivityManagerRecordingRequests.kt +27 -0
  117. package/app.plugin.js +17 -1
  118. package/ios/AVPlayerItemQueueItemId.swift +26 -12
  119. package/ios/AVQueueBuilder.swift +120 -85
  120. package/ios/ArtworkLoader.swift +0 -7
  121. package/ios/ArtworkResolver.swift +22 -4
  122. package/ios/AssetReplayGainReader.swift +118 -0
  123. package/ios/AudioSession.swift +67 -16
  124. package/ios/AudioTapProvider.swift +284 -149
  125. package/ios/CarPlayBridge.swift +0 -12
  126. package/ios/CarPlayCoordinator.swift +18 -2
  127. package/ios/CarPlaySceneDelegate.swift +2 -2
  128. package/ios/Cast/AirPlayRouteState.swift +9 -8
  129. package/ios/Cast/Chromecast/ChromecastSession.swift +90 -11
  130. package/ios/Cast/Core/CastEventBridge.swift +66 -26
  131. package/ios/Cast/Core/CastNowPlayingController.swift +38 -16
  132. package/ios/Cast/Core/CastSession.swift +11 -0
  133. package/ios/Cast/Core/CastTransportRouter.swift +21 -9
  134. package/ios/Cast/Core/LocalMediaServer.swift +41 -52
  135. package/ios/Cast/Core/LocalNetworkPermissionProbe.swift +32 -11
  136. package/ios/Cast/Core/MediaServerHandle.swift +0 -4
  137. package/ios/Cast/Core/MediaTokenRegistry.swift +0 -6
  138. package/ios/CastManager.swift +1 -1
  139. package/ios/CrossfadeEngine.swift +660 -226
  140. package/ios/EQTap.swift +20 -17
  141. package/ios/Equalizer.swift +1 -1
  142. package/ios/FLACStreamInfo.swift +65 -0
  143. package/ios/GaplessEngine.swift +57 -30
  144. package/ios/InputGuards.swift +35 -5
  145. package/ios/LookaheadCache.swift +202 -58
  146. package/ios/LookaheadCachePrefetcher.swift +48 -36
  147. package/ios/MediaServer/MediaHTTPConnection.swift +691 -0
  148. package/ios/NetworkRecoveryPolicy.swift +32 -0
  149. package/ios/NowPlayingFormatExtractor.swift +25 -18
  150. package/ios/NowPlayingInfo.swift +84 -48
  151. package/ios/OutputRouteMonitor.swift +16 -3
  152. package/ios/PendingBrowseRequests.swift +1 -1
  153. package/ios/PlaceholderArtwork.swift +9 -5
  154. package/ios/PlaybackEngine.swift +165 -76
  155. package/ios/PlaybackErrorMapping.swift +3 -3
  156. package/ios/PlaybackModeStateMachine.swift +2 -2
  157. package/ios/PlaybackNetworkMonitor.swift +73 -0
  158. package/ios/PlayerStateDerivation.swift +6 -6
  159. package/ios/QueueMutationArithmetic.swift +25 -0
  160. package/ios/QueueSkipArithmetic.swift +5 -3
  161. package/ios/QueueWindowArithmetic.swift +152 -0
  162. package/ios/ReadThroughServer.swift +283 -0
  163. package/ios/RemoteCommands.swift +44 -4
  164. package/ios/ReplayGainData.swift +22 -3
  165. package/ios/ReplayGainExtractor.swift +70 -27
  166. package/ios/Siri/VoiceDonation.swift +14 -9
  167. package/ios/StreamingBitrateProbe.swift +22 -68
  168. package/ios/SuppliedReplayGain.swift +83 -0
  169. package/ios/Tests/AVQueueBuilderTests.swift +158 -221
  170. package/ios/Tests/ActiveItemEngineStub.swift +44 -0
  171. package/ios/Tests/AssetReplayGainReaderTests.swift +228 -0
  172. package/ios/Tests/AudioTapProviderDispatchTargetTests.swift +158 -0
  173. package/ios/Tests/AudioTapProviderReplayGainTests.swift +122 -10
  174. package/ios/Tests/BitrateReresolveBudgetTests.swift +71 -0
  175. package/ios/Tests/CastMediaItemTranslationTests.swift +72 -0
  176. package/ios/Tests/CastNowPlayingControllerTests.swift +5 -0
  177. package/ios/Tests/CrossfadeAdvanceWithoutFadeTests.swift +120 -0
  178. package/ios/Tests/CrossfadeEngineIncomingMixTests.swift +122 -0
  179. package/ios/Tests/CrossfadeEngineTests.swift +164 -0
  180. package/ios/Tests/CrossfadeMixReapplyTests.swift +66 -0
  181. package/ios/Tests/CrossfadePlaybackIntentTests.swift +81 -0
  182. package/ios/Tests/EngineSwapTests.swift +91 -0
  183. package/ios/Tests/EqualizerAudioMixProviderTests.swift +46 -0
  184. package/ios/Tests/EqualizerHybridTests.swift +5 -2
  185. package/ios/Tests/FLACStreamInfoTests.swift +88 -0
  186. package/ios/Tests/GaplessEngineLifecycleTests.swift +4 -4
  187. package/ios/Tests/InputGuardsTests.swift +41 -0
  188. package/ios/Tests/InterruptionIntentTests.swift +77 -0
  189. package/ios/Tests/LookaheadCacheCellularAccessTests.swift +185 -0
  190. package/ios/Tests/LookaheadCachePrefetcherTests.swift +53 -30
  191. package/ios/Tests/LookaheadCacheRuntimeConfigTests.swift +160 -1
  192. package/ios/Tests/LookaheadCacheTests.swift +44 -18
  193. package/ios/Tests/MediaHTTPConnectionTests.swift +79 -0
  194. package/ios/Tests/MutationDeferralTests.swift +220 -0
  195. package/ios/Tests/NowPlayingInfoTests.swift +86 -99
  196. package/ios/Tests/NowPlayingSnapshotTests.swift +127 -0
  197. package/ios/Tests/OriginRestartStitcherTests.swift +60 -0
  198. package/ios/Tests/PlaybackNetworkMonitorTests.swift +95 -0
  199. package/ios/Tests/PlaybackStateRouterTests.swift +1 -0
  200. package/ios/Tests/PlayerFixtures.swift +48 -0
  201. package/ios/Tests/PlayerStateDerivationTests.swift +10 -10
  202. package/ios/Tests/QueueMutationGenerationTests.swift +141 -0
  203. package/ios/Tests/QueueRebuildPrefixTests.swift +317 -0
  204. package/ios/Tests/QueueStateTests.swift +3 -1
  205. package/ios/Tests/QueueWindowArithmeticTests.swift +56 -0
  206. package/ios/Tests/QueueWindowSliceTests.swift +162 -0
  207. package/ios/Tests/ReadThroughRoutingLifecycleTests.swift +63 -0
  208. package/ios/Tests/ReadThroughServerTests.swift +345 -0
  209. package/ios/Tests/RemoteCommandsTests.swift +28 -0
  210. package/ios/Tests/ReplayGainExtractorTests.swift +216 -6
  211. package/ios/Tests/ReplayGainMergeTests.swift +230 -0
  212. package/ios/Tests/RetryRecoveryTests.swift +303 -0
  213. package/ios/Tests/SkipCapabilityTests.swift +233 -8
  214. package/ios/Tests/SkipIndexTests.swift +32 -2
  215. package/ios/Tests/SleepTimerPauseIntentTests.swift +43 -0
  216. package/ios/Tests/StallRecoveryTests.swift +97 -0
  217. package/ios/Tests/StreamingBitrateProbeTests.swift +17 -20
  218. package/ios/Tests/TopUpWindowGateTests.swift +394 -0
  219. package/ios/Tests/TrackPlayer+TestHops.swift +14 -0
  220. package/ios/Tests/TrackPlayerCallOrderTests.swift +93 -0
  221. package/ios/Tests/TrackPlayerCastStateTests.swift +78 -0
  222. package/ios/Tests/TrackPlayerConfigureTeardownTests.swift +86 -0
  223. package/ios/Tests/TrackPlayerEndVerdictTests.swift +165 -0
  224. package/ios/Tests/TrackPlayerSeekTests.swift +137 -0
  225. package/ios/Tests/TrackPlayerThreadingTests.swift +127 -0
  226. package/ios/Tests/TrackSourceClassifierTests.swift +33 -7
  227. package/ios/Tests/VoiceVocabularyOptInTests.swift +38 -0
  228. package/ios/TrackPlayer+Automotive.swift +101 -0
  229. package/ios/TrackPlayer+Cache.swift +232 -0
  230. package/ios/TrackPlayer+Config.swift +291 -0
  231. package/ios/TrackPlayer+EngineDelegate.swift +209 -0
  232. package/ios/TrackPlayer+EventsAPI.swift +111 -0
  233. package/ios/TrackPlayer+EventsDispatch.swift +968 -0
  234. package/ios/TrackPlayer+EventsWiring.swift +173 -0
  235. package/ios/TrackPlayer+Lifecycle.swift +930 -0
  236. package/ios/TrackPlayer+NowPlayingFormat.swift +258 -0
  237. package/ios/TrackPlayer+Queue.swift +940 -0
  238. package/ios/TrackPlayer+Recovery.swift +196 -0
  239. package/ios/TrackPlayer+Skip.swift +455 -0
  240. package/ios/TrackPlayer+SleepTimer.swift +175 -0
  241. package/ios/TrackPlayer+State.swift +108 -0
  242. package/ios/TrackPlayer+Threading.swift +135 -0
  243. package/ios/TrackPlayer+Transport.swift +267 -0
  244. package/ios/TrackPlayer+Window.swift +195 -0
  245. package/ios/TrackPlayer.swift +305 -4610
  246. package/ios/Visualizer.swift +6 -5
  247. package/ios/tests-harness/Podfile +1 -1
  248. package/ios/tests-harness/TestHost.xcodeproj/project.pbxproj +19 -11
  249. package/ios/tests-harness/scripts/seed-xcodeproj.rb +2 -2
  250. package/lib/module/hooks/useActiveTrack.js +29 -22
  251. package/lib/module/hooks/useActiveTrack.js.map +1 -1
  252. package/lib/module/hooks/useCast.js +8 -26
  253. package/lib/module/hooks/useCast.js.map +1 -1
  254. package/lib/module/hooks/useEqualizer.js +19 -12
  255. package/lib/module/hooks/useEqualizer.js.map +1 -1
  256. package/lib/module/hooks/useLookaheadCache.js +3 -7
  257. package/lib/module/hooks/useLookaheadCache.js.map +1 -1
  258. package/lib/module/hooks/useQueue.js +66 -19
  259. package/lib/module/hooks/useQueue.js.map +1 -1
  260. package/lib/module/index.js +6 -3
  261. package/lib/module/index.js.map +1 -1
  262. package/lib/module/queueDelta.js +41 -0
  263. package/lib/module/queueDelta.js.map +1 -0
  264. package/lib/module/types.js +28 -5
  265. package/lib/module/types.js.map +1 -1
  266. package/lib/typescript/TrackPlayer.nitro.d.ts +53 -28
  267. package/lib/typescript/TrackPlayer.nitro.d.ts.map +1 -1
  268. package/lib/typescript/hooks/useActiveTrack.d.ts +5 -7
  269. package/lib/typescript/hooks/useActiveTrack.d.ts.map +1 -1
  270. package/lib/typescript/hooks/useCast.d.ts +6 -1
  271. package/lib/typescript/hooks/useCast.d.ts.map +1 -1
  272. package/lib/typescript/hooks/useEqualizer.d.ts +2 -1
  273. package/lib/typescript/hooks/useEqualizer.d.ts.map +1 -1
  274. package/lib/typescript/hooks/useLookaheadCache.d.ts.map +1 -1
  275. package/lib/typescript/hooks/useQueue.d.ts +4 -4
  276. package/lib/typescript/hooks/useQueue.d.ts.map +1 -1
  277. package/lib/typescript/index.d.ts +2 -1
  278. package/lib/typescript/index.d.ts.map +1 -1
  279. package/lib/typescript/queueDelta.d.ts +10 -0
  280. package/lib/typescript/queueDelta.d.ts.map +1 -0
  281. package/lib/typescript/types.d.ts +168 -12
  282. package/lib/typescript/types.d.ts.map +1 -1
  283. package/nitrogen/generated/android/c++/JFunc_void_QueueChangeDelta_double_QueueChangeReason.hpp +85 -0
  284. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +45 -19
  285. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +3 -3
  286. package/nitrogen/generated/android/c++/JLookaheadCacheConfig.hpp +8 -4
  287. package/nitrogen/generated/android/c++/JPlayerConfig.hpp +5 -1
  288. package/nitrogen/generated/android/c++/JQueueChangeDelta.hpp +128 -0
  289. package/nitrogen/generated/android/c++/JTrackItem.hpp +19 -3
  290. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_BrowseItem______std__string.kt +0 -2
  291. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_TrackItem______MediaSearchRequest.kt +0 -2
  292. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_TrackItem______std__string.kt +0 -2
  293. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void.kt +0 -2
  294. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_AudioRoute.kt +0 -2
  295. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_BufferState.kt +0 -2
  296. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CacheStatus.kt +0 -2
  297. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastDiscoveryState.kt +0 -2
  298. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastLocalNetworkPermissionEvent.kt +0 -2
  299. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastRoute.kt +0 -2
  300. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastSessionDiedEvent.kt +0 -2
  301. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlaybackError.kt +0 -2
  302. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerProgress.kt +0 -2
  303. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerState_StateChangeReason.kt +0 -2
  304. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/{Func_void_std__vector_TrackItem__double_QueueChangeReason.kt → Func_void_QueueChangeDelta_double_QueueChangeReason.kt} +14 -16
  305. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_ServiceReadyReason.kt +0 -2
  306. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SkipCapability.kt +0 -2
  307. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SleepTimerState.kt +0 -2
  308. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerErrorReason.kt +0 -2
  309. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerFrame.kt +0 -2
  310. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_bool.kt +0 -2
  311. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_double_double.kt +0 -2
  312. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_TrackItem__double_TrackChangeReason_std__optional_double_.kt +0 -2
  313. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_std__variant_nitro__NullType__NowPlayingFormat__.kt +0 -2
  314. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_CastReceiver_.kt +0 -2
  315. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_EqualizerBand_.kt +0 -2
  316. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridCastManagerSpec.kt +2 -0
  317. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridEqualizerSpec.kt +2 -0
  318. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridTrackPlayerSpec.kt +6 -4
  319. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridVisualizerSpec.kt +2 -0
  320. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/LookaheadCacheConfig.kt +9 -4
  321. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/PlayerConfig.kt +7 -2
  322. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/QueueChangeDelta.kt +86 -0
  323. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/TrackItem.kt +24 -4
  324. package/nitrogen/generated/android/queueplayerOnLoad.cpp +2 -2
  325. package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.cpp +16 -16
  326. package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.hpp +80 -65
  327. package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Umbrella.hpp +3 -0
  328. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +6 -3
  329. package/nitrogen/generated/ios/swift/Func_void_CacheStatus.swift +5 -5
  330. package/nitrogen/generated/ios/swift/Func_void_QueueChangeDelta_double_QueueChangeReason.swift +46 -0
  331. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +3 -3
  332. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +32 -24
  333. package/nitrogen/generated/ios/swift/LookaheadCacheConfig.swift +20 -2
  334. package/nitrogen/generated/ios/swift/PlayerConfig.swift +19 -1
  335. package/nitrogen/generated/ios/swift/QueueChangeDelta.swift +82 -0
  336. package/nitrogen/generated/ios/swift/TrackItem.swift +73 -1
  337. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +6 -3
  338. package/nitrogen/generated/shared/c++/LookaheadCacheConfig.hpp +7 -3
  339. package/nitrogen/generated/shared/c++/PlayerConfig.hpp +5 -1
  340. package/nitrogen/generated/shared/c++/QueueChangeDelta.hpp +113 -0
  341. package/nitrogen/generated/shared/c++/TrackItem.hpp +18 -2
  342. package/package.json +8 -8
  343. package/src/TrackPlayer.nitro.ts +53 -27
  344. package/src/hooks/useActiveTrack.ts +29 -22
  345. package/src/hooks/useCast.ts +14 -15
  346. package/src/hooks/useEqualizer.ts +19 -12
  347. package/src/hooks/useLookaheadCache.ts +3 -7
  348. package/src/hooks/useQueue.ts +66 -17
  349. package/src/index.ts +13 -3
  350. package/src/queueDelta.ts +41 -0
  351. package/src/types.ts +169 -12
  352. package/android/src/main/java/com/margelo/nitro/queueplayer/PendingIntentBuffer.kt +0 -82
  353. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2MetadataSync.kt +0 -189
  354. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServerLifecycle.kt +0 -15
  355. package/android/src/test/java/com/margelo/nitro/queueplayer/PendingIntentBufferTest.kt +0 -192
  356. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackEngineInterfaceTest.kt +0 -135
  357. package/android/src/test/java/com/margelo/nitro/queueplayer/SmokeTest.kt +0 -27
  358. package/ios/Cast/Core/LocalAddressMonitor.swift +0 -110
  359. package/ios/Cast/Core/MediaHTTPConnection.swift +0 -349
  360. package/ios/MetadataReader.swift +0 -555
  361. package/ios/Tests/CrossfadeEngineStubTests.swift +0 -43
  362. package/ios/Tests/MetadataReaderTests.swift +0 -603
  363. package/ios/Tests/PlaybackEngineProtocolTests.swift +0 -92
  364. package/ios/Tests/VoiceDonationTests.swift +0 -26
  365. package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__double_QueueChangeReason.hpp +0 -101
  366. package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem__double_QueueChangeReason.swift +0 -46
  367. /package/ios/{Cast/Core → MediaServer}/MimeTypes.swift +0 -0
@@ -0,0 +1,113 @@
1
+ ///
2
+ /// QueueChangeDelta.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
11
+ #include <NitroModules/JSIConverter.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
16
+ #include <NitroModules/NitroDefines.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
21
+ #include <NitroModules/JSIHelpers.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
26
+ #include <NitroModules/PropNameIDCache.hpp>
27
+ #else
28
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
29
+ #endif
30
+
31
+ // Forward declaration of `TrackItem` to properly resolve imports.
32
+ namespace margelo::nitro::queueplayer { struct TrackItem; }
33
+
34
+ #include "TrackItem.hpp"
35
+ #include <vector>
36
+
37
+ namespace margelo::nitro::queueplayer {
38
+
39
+ /**
40
+ * A struct which can be represented as a JavaScript object (QueueChangeDelta).
41
+ */
42
+ struct QueueChangeDelta final {
43
+ public:
44
+ double revision SWIFT_PRIVATE;
45
+ double length SWIFT_PRIVATE;
46
+ std::vector<TrackItem> inserted SWIFT_PRIVATE;
47
+ double insertedAt SWIFT_PRIVATE;
48
+ std::vector<double> removed SWIFT_PRIVATE;
49
+ double movedFrom SWIFT_PRIVATE;
50
+ double movedTo SWIFT_PRIVATE;
51
+ std::vector<double> order SWIFT_PRIVATE;
52
+
53
+ public:
54
+ QueueChangeDelta() = default;
55
+ explicit QueueChangeDelta(double revision, double length, std::vector<TrackItem> inserted, double insertedAt, std::vector<double> removed, double movedFrom, double movedTo, std::vector<double> order): revision(revision), length(length), inserted(inserted), insertedAt(insertedAt), removed(removed), movedFrom(movedFrom), movedTo(movedTo), order(order) {}
56
+
57
+ public:
58
+ friend bool operator==(const QueueChangeDelta& lhs, const QueueChangeDelta& rhs) = default;
59
+ };
60
+
61
+ } // namespace margelo::nitro::queueplayer
62
+
63
+ namespace margelo::nitro {
64
+
65
+ // C++ QueueChangeDelta <> JS QueueChangeDelta (object)
66
+ template <>
67
+ struct JSIConverter<margelo::nitro::queueplayer::QueueChangeDelta> final {
68
+ static inline margelo::nitro::queueplayer::QueueChangeDelta fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
69
+ jsi::Object obj = arg.asObject(runtime);
70
+ return margelo::nitro::queueplayer::QueueChangeDelta(
71
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "revision"))),
72
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "length"))),
73
+ JSIConverter<std::vector<margelo::nitro::queueplayer::TrackItem>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "inserted"))),
74
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "insertedAt"))),
75
+ JSIConverter<std::vector<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "removed"))),
76
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "movedFrom"))),
77
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "movedTo"))),
78
+ JSIConverter<std::vector<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "order")))
79
+ );
80
+ }
81
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::queueplayer::QueueChangeDelta& arg) {
82
+ jsi::Object obj(runtime);
83
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "revision"), JSIConverter<double>::toJSI(runtime, arg.revision));
84
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "length"), JSIConverter<double>::toJSI(runtime, arg.length));
85
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "inserted"), JSIConverter<std::vector<margelo::nitro::queueplayer::TrackItem>>::toJSI(runtime, arg.inserted));
86
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "insertedAt"), JSIConverter<double>::toJSI(runtime, arg.insertedAt));
87
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "removed"), JSIConverter<std::vector<double>>::toJSI(runtime, arg.removed));
88
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "movedFrom"), JSIConverter<double>::toJSI(runtime, arg.movedFrom));
89
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "movedTo"), JSIConverter<double>::toJSI(runtime, arg.movedTo));
90
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "order"), JSIConverter<std::vector<double>>::toJSI(runtime, arg.order));
91
+ return obj;
92
+ }
93
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
94
+ if (!value.isObject()) {
95
+ return false;
96
+ }
97
+ jsi::Object obj = value.getObject(runtime);
98
+ if (!nitro::isPlainObject(runtime, obj)) {
99
+ return false;
100
+ }
101
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "revision")))) return false;
102
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "length")))) return false;
103
+ if (!JSIConverter<std::vector<margelo::nitro::queueplayer::TrackItem>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "inserted")))) return false;
104
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "insertedAt")))) return false;
105
+ if (!JSIConverter<std::vector<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "removed")))) return false;
106
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "movedFrom")))) return false;
107
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "movedTo")))) return false;
108
+ if (!JSIConverter<std::vector<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "order")))) return false;
109
+ return true;
110
+ }
111
+ };
112
+
113
+ } // namespace margelo::nitro
@@ -49,10 +49,14 @@ namespace margelo::nitro::queueplayer {
49
49
  std::optional<double> duration SWIFT_PRIVATE;
50
50
  std::optional<std::string> artworkUrl SWIFT_PRIVATE;
51
51
  std::optional<std::unordered_map<std::string, std::string>> extras SWIFT_PRIVATE;
52
+ std::optional<double> replayGainTrackGain SWIFT_PRIVATE;
53
+ std::optional<double> replayGainTrackPeak SWIFT_PRIVATE;
54
+ std::optional<double> replayGainAlbumGain SWIFT_PRIVATE;
55
+ std::optional<double> replayGainAlbumPeak SWIFT_PRIVATE;
52
56
 
53
57
  public:
54
58
  TrackItem() = default;
55
- explicit TrackItem(std::optional<std::string> id, std::string url, std::optional<std::string> title, std::optional<std::string> artist, std::optional<std::string> album, std::optional<double> duration, std::optional<std::string> artworkUrl, std::optional<std::unordered_map<std::string, std::string>> extras): id(id), url(url), title(title), artist(artist), album(album), duration(duration), artworkUrl(artworkUrl), extras(extras) {}
59
+ explicit TrackItem(std::optional<std::string> id, std::string url, std::optional<std::string> title, std::optional<std::string> artist, std::optional<std::string> album, std::optional<double> duration, std::optional<std::string> artworkUrl, std::optional<std::unordered_map<std::string, std::string>> extras, std::optional<double> replayGainTrackGain, std::optional<double> replayGainTrackPeak, std::optional<double> replayGainAlbumGain, std::optional<double> replayGainAlbumPeak): id(id), url(url), title(title), artist(artist), album(album), duration(duration), artworkUrl(artworkUrl), extras(extras), replayGainTrackGain(replayGainTrackGain), replayGainTrackPeak(replayGainTrackPeak), replayGainAlbumGain(replayGainAlbumGain), replayGainAlbumPeak(replayGainAlbumPeak) {}
56
60
 
57
61
  public:
58
62
  friend bool operator==(const TrackItem& lhs, const TrackItem& rhs) = default;
@@ -75,7 +79,11 @@ namespace margelo::nitro {
75
79
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "album"))),
76
80
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "duration"))),
77
81
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "artworkUrl"))),
78
- JSIConverter<std::optional<std::unordered_map<std::string, std::string>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "extras")))
82
+ JSIConverter<std::optional<std::unordered_map<std::string, std::string>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "extras"))),
83
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainTrackGain"))),
84
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainTrackPeak"))),
85
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainAlbumGain"))),
86
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainAlbumPeak")))
79
87
  );
80
88
  }
81
89
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::queueplayer::TrackItem& arg) {
@@ -88,6 +96,10 @@ namespace margelo::nitro {
88
96
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "duration"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.duration));
89
97
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "artworkUrl"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.artworkUrl));
90
98
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "extras"), JSIConverter<std::optional<std::unordered_map<std::string, std::string>>>::toJSI(runtime, arg.extras));
99
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "replayGainTrackGain"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.replayGainTrackGain));
100
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "replayGainTrackPeak"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.replayGainTrackPeak));
101
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "replayGainAlbumGain"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.replayGainAlbumGain));
102
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "replayGainAlbumPeak"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.replayGainAlbumPeak));
91
103
  return obj;
92
104
  }
93
105
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -106,6 +118,10 @@ namespace margelo::nitro {
106
118
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "duration")))) return false;
107
119
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "artworkUrl")))) return false;
108
120
  if (!JSIConverter<std::optional<std::unordered_map<std::string, std::string>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "extras")))) return false;
121
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainTrackGain")))) return false;
122
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainTrackPeak")))) return false;
123
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainAlbumGain")))) return false;
124
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "replayGainAlbumPeak")))) return false;
109
125
  return true;
110
126
  }
111
127
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-queue-player",
3
- "version": "1.1.2",
4
- "description": "Nitro Modules audio playback library for React Native gapless, EQ, crossfade, automotive, voice, casting",
3
+ "version": "2.0.0",
4
+ "description": "Nitro Modules audio playback library for React Native \u2014 gapless, EQ, crossfade, automotive, voice, casting",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/index.d.ts",
7
7
  "exports": {
@@ -83,17 +83,17 @@
83
83
  "devDependencies": {
84
84
  "@expo/config-plugins": "^54.0.0",
85
85
  "@jest/globals": "^29.7.0",
86
- "@react-native/babel-preset": "0.85.3",
87
- "@react-native/jest-preset": "0.85.3",
86
+ "@react-native/babel-preset": "0.86.3",
87
+ "@react-native/jest-preset": "0.86.3",
88
88
  "@types/react": "^19.2.0",
89
89
  "@types/react-test-renderer": "19.1.0",
90
90
  "del-cli": "^7.0.0",
91
91
  "jest": "^29.7.0",
92
- "nitrogen": "^0.36.1",
92
+ "nitrogen": "^0.37.1",
93
93
  "react": "19.2.3",
94
- "react-native": "0.85.3",
94
+ "react-native": "0.86.3",
95
95
  "react-native-builder-bob": "^0.41.0",
96
- "react-native-nitro-modules": "^0.36.1",
96
+ "react-native-nitro-modules": "^0.37.1",
97
97
  "react-test-renderer": "19.2.3",
98
98
  "turbo": "^2.8.21",
99
99
  "typescript": "^6.0.2"
@@ -102,7 +102,7 @@
102
102
  "@expo/config-plugins": ">=10.0.0",
103
103
  "react": "*",
104
104
  "react-native": "*",
105
- "react-native-nitro-modules": "^0.36.1"
105
+ "react-native-nitro-modules": "^0.37.1"
106
106
  },
107
107
  "peerDependenciesMeta": {
108
108
  "@expo/config-plugins": {
@@ -10,6 +10,7 @@ import type {
10
10
  StateChangeReason,
11
11
  TrackChangeReason,
12
12
  QueueChangeReason,
13
+ QueueChangeDelta,
13
14
  TrackSource,
14
15
  PlaybackError,
15
16
  PlayerProgress,
@@ -111,17 +112,18 @@ export interface TrackPlayer
111
112
  */
112
113
  moveInQueue(fromIndex: number, toIndex: number): Promise<void>;
113
114
  /**
114
- * Returns the current queue snapshot.
115
+ * Resolves with the current queue snapshot.
115
116
  *
116
- * Cross-platform note: on Android the read crosses thread boundaries
117
- * (`@Volatile tracks` field, no main-hop) calling `getQueue()` and
118
- * `getCurrentTrackIndex()` back-to-back can observe a one-tick skew
119
- * during a concurrent queue mutation (e.g. mid-`setQueue`). For UI
120
- * code that needs the pair to be consistent, prefer the
121
- * `useActiveTrack` hook which subscribes to `onTrackChange` and
122
- * receives both atomically.
117
+ * Each platform reads the queue on the thread that owns it (the player's
118
+ * serial queue on iOS, main on Android), so the array is internally
119
+ * consistent. The pair `getQueue()` + `getCurrentTrackIndex()` is still
120
+ * **not** atomic — awaiting the first leaves a gap in which a mutation can
121
+ * land, so the index can name a position in a queue you no longer hold. For
122
+ * UI that needs the pair consistent, subscribe: `onTrackChange` delivers
123
+ * `(track, index)` together, and `onQueueChange` delivers the delta and the
124
+ * post-mutation index together under the same mutation.
123
125
  */
124
- getQueue(): TrackItem[];
126
+ getQueue(): Promise<TrackItem[]>;
125
127
  clearQueue(): Promise<void>;
126
128
 
127
129
  // Transport
@@ -129,12 +131,12 @@ export interface TrackPlayer
129
131
  pause(): Promise<void>;
130
132
  stop(): Promise<void>;
131
133
  /**
132
- * Manually re-attempt the current track after its automatic retries were
133
- * exhausted (the track is in the error state). Rebuilds the failed item and
134
- * resumes from where it stopped, then plays. Use for a "tap to retry" button:
135
- * e.g. the user left WiFi coverage so the auto-retries failed, then came back
136
- * in range and taps retry. A no-op when there is no current track or the
137
- * current track is not in the error state.
134
+ * Re-attempt the current track, from any state. Rebuilds the item, resumes
135
+ * from where it stopped, then plays, and restores the track's automatic
136
+ * retry budget. Use for a "tap to retry" button: e.g. the user left WiFi
137
+ * coverage so the auto-retries failed, then came back in range and taps
138
+ * retry. While casting, forwards a play to the receiver instead. A no-op
139
+ * only when there is no current track.
138
140
  */
139
141
  retry(): Promise<void>;
140
142
  /** position in seconds from the start of the current track */
@@ -381,10 +383,12 @@ export interface TrackPlayer
381
383
  * e.g. inserting a "play next" item or removing an upcoming track — so
382
384
  * a reactive queue UI stays in sync.
383
385
  *
384
- * The `(queue, currentIndex)` pair is delivered **atomically**: it is
385
- * the post-mutation snapshot captured on the native side under the same
386
- * mutation, so it never exhibits the one-tick skew of reading
387
- * `getQueue()` + `getCurrentTrackIndex()` back-to-back. `currentIndex`
386
+ * The `(delta, currentIndex)` pair is delivered **atomically**: both are
387
+ * captured on the native side under the same mutation, so they never exhibit
388
+ * the skew of awaiting `getQueue()` and then reading
389
+ * `getCurrentTrackIndex()`. The delta describes the change rather than
390
+ * carrying the whole queue, so a reorder costs two numbers instead of one
391
+ * `TrackItem` per entry — see `QueueChangeDelta`. `currentIndex`
388
392
  * is `-1` when the queue is empty; note it can shift without the active
389
393
  * track changing (e.g. an insert before the current item), which is the
390
394
  * case `onTrackChange` does not cover.
@@ -393,14 +397,14 @@ export interface TrackPlayer
393
397
  * `addToQueue`, out-of-range `removeFromQueue`, `moveInQueue` with
394
398
  * `from === to`) does not fire, and neither do current-index-only
395
399
  * changes from auto-advance / skip (those are `onTrackChange`). Does not
396
- * auto-fire on subscribe; seed initial state from `getQueue()` (the
397
- * `useQueue()` hook does this). For a mutation that also changes the
400
+ * auto-fire on subscribe; seed initial state from `getQueue()` once, then
401
+ * apply each delta (the `useQueue()` hook does this). For a mutation that also changes the
398
402
  * active track (`set-queue` / `clear` / `shuffle`) this fires first,
399
403
  * then `onTrackChange` follows.
400
404
  */
401
405
  onQueueChange(
402
406
  callback: (
403
- queue: TrackItem[],
407
+ delta: QueueChangeDelta,
404
408
  currentIndex: number,
405
409
  reason: QueueChangeReason
406
410
  ) => void
@@ -452,10 +456,8 @@ export interface TrackPlayer
452
456
  * call `getCanSkipNext` / `getCanSkipPrevious` first).
453
457
  *
454
458
  * Wrapped in a `SkipCapability` struct (rather than two boolean
455
- * callback args) so future capability flags can be added without
456
- * a breaking API change. Also works around a Nitrogen 0.35.4
457
- * codegen bug for `(bool, bool) → void` callback signatures
458
- * specifically.
459
+ * callback args) so further capability flags can be added without
460
+ * a breaking API change.
459
461
  */
460
462
  onSkipCapabilityChange(
461
463
  callback: (capability: SkipCapability) => void
@@ -562,6 +564,16 @@ export interface TrackPlayer
562
564
  * library refresh — not every launch — and the lib dispatches the
563
565
  * actual write to a background queue per Apple's guidance.
564
566
  *
567
+ * **Inert unless `PlayerConfig.voiceVocabularyDonationEnabled` was `true` at
568
+ * the first `configure()`,** and enabling that requires the
569
+ * `com.apple.developer.siri` entitlement — Xcode's Siri capability — not
570
+ * just `NSSiriUsageDescription` in Info.plist. `INVocabulary` checks for the
571
+ * entitlement at runtime and raises an Objective-C exception without it,
572
+ * which cannot be caught from Swift and terminates the app. iOS gives a
573
+ * process no way to read its own entitlements, so the opt-in is the
574
+ * library's only signal that this is safe to call: leave it `false` unless
575
+ * the Siri capability is on the target.
576
+ *
565
577
  * **Android**: no-op. Google Assistant has no in-app vocabulary
566
578
  * donation API.
567
579
  */
@@ -641,6 +653,15 @@ export interface TrackPlayer
641
653
  * immediate Android eviction must `await player.destroy()` then
642
654
  * `await player.configure({ ... })` to force a rebuild.
643
655
  *
656
+ * **Cross-platform note on `allowsCellularAccess`**: live on both,
657
+ * but enforced at different points. iOS sets it on each prefetch
658
+ * request and the OS refuses the request; a download already on
659
+ * the wire finishes under the value it started with. Android has
660
+ * no per-request equivalent, so prefetch stops being scheduled
661
+ * while the default network is cellular, which also cancels the
662
+ * download in flight — its partial data stays cached and resumes
663
+ * later. Neither platform gates playback on it.
664
+ *
644
665
  * **Cross-platform note on enable transition**: flipping `enabled`
645
666
  * from `false` → `true` follows the same Android limitation —
646
667
  * a fresh SimpleCache is only constructed during `configureInternal`,
@@ -650,7 +671,7 @@ export interface TrackPlayer
650
671
  * immediate.
651
672
  */
652
673
  setLookaheadCache(config: LookaheadCacheConfig): Promise<void>;
653
- getLookaheadCacheStatus(): CacheStatus;
674
+ getLookaheadCacheStatus(): Promise<CacheStatus>;
654
675
  /**
655
676
  * Wipe every cached entry + cancel any in-flight prefetch. Does
656
677
  * NOT auto-restart the prefetcher — `clear` means "wipe and stop".
@@ -659,6 +680,11 @@ export interface TrackPlayer
659
680
  * prefetch window.
660
681
  */
661
682
  clearLookaheadCache(): Promise<void>;
683
+ /**
684
+ * Fires once on subscribe with the current status, then after every
685
+ * `setLookaheadCache()`, prefetch completion and `clearLookaheadCache()`.
686
+ * An eviction shows in the next snapshot those produce.
687
+ */
662
688
  onCacheStatusChange(callback: (status: CacheStatus) => void): () => void;
663
689
 
664
690
  /**
@@ -19,36 +19,43 @@ const INITIAL: ActiveTrackSnapshot = {
19
19
  /**
20
20
  * Subscribes to native `onTrackChange` updates.
21
21
  *
22
- * The first-render seed reads `getQueue()` and `getCurrentTrackIndex()`
23
- * separately the pair is not atomic against a concurrent queue
24
- * mutation on either platform, so the seed can briefly observe the
25
- * new list with the old index (or vice versa). Self-healing: the
26
- * next `onTrackChange` event delivers a consistent
27
- * `(track, index, reason)` triple. Consumers needing an atomic
28
- * snapshot should wait for the first listener fire.
22
+ * Renders empty for the first frame, then fills in: the seed reads
23
+ * `getQueue()`, which resolves asynchronously, and pairs it with a separately
24
+ * read index so it can briefly observe a new list against an old index. Any
25
+ * `onTrackChange` that arrives first wins and the seed is dropped, since the
26
+ * event delivers a consistent `(track, index, reason)` triple.
29
27
  */
30
28
  export function useActiveTrack(): ActiveTrackSnapshot {
31
- const [snapshot, setSnapshot] = useState<ActiveTrackSnapshot>(() => {
32
- try {
33
- const player = getTrackPlayer();
34
- const queue = player.getQueue();
35
- const index = player.getCurrentTrackIndex();
36
- return {
37
- track: index >= 0 && index < queue.length ? queue[index] : undefined,
38
- index,
39
- reason: 'queue-replaced',
40
- };
41
- } catch {
42
- return INITIAL;
43
- }
44
- });
29
+ const [snapshot, setSnapshot] = useState<ActiveTrackSnapshot>(INITIAL);
45
30
 
46
31
  useEffect(() => {
47
32
  const player = getTrackPlayer();
33
+ let seeded = false;
34
+ // A seed still in flight when this effect is cleaned up (a StrictMode
35
+ // remount, an unmount) must not land on a later mount's state.
36
+ let disposed = false;
37
+ void (async () => {
38
+ try {
39
+ const queue = await player.getQueue();
40
+ const index = player.getCurrentTrackIndex();
41
+ if (disposed || seeded) return;
42
+ setSnapshot({
43
+ track: index >= 0 && index < queue.length ? queue[index] : undefined,
44
+ index,
45
+ reason: 'queue-replaced',
46
+ });
47
+ } catch {
48
+ // Player not configured yet; the first event seeds instead.
49
+ }
50
+ })();
48
51
  const dispose = player.onTrackChange((track, index, reason) => {
52
+ seeded = true;
49
53
  setSnapshot({ track, index, reason });
50
54
  });
51
- return dispose;
55
+ return () => {
56
+ disposed = true;
57
+ dispose();
58
+ };
52
59
  }, []);
53
60
 
54
61
  return snapshot;
@@ -6,6 +6,7 @@ import {
6
6
  addRouteListener,
7
7
  addSessionDiedListener,
8
8
  getCurrentRoute,
9
+ getLocalNetworkPermissionState,
9
10
  getReceivers,
10
11
  getSupportedProtocols,
11
12
  isCastAvailable,
@@ -34,7 +35,12 @@ export interface CastSnapshot {
34
35
  * clear by re-reading state after surfacing a banner.
35
36
  */
36
37
  lastSessionDied: CastSessionDiedEvent | null;
37
- /** iOS Local Network permission state; `'granted'` on Android. */
38
+ /**
39
+ * Local Network permission state. Seeded from
40
+ * `getLocalNetworkPermissionState()` on mount and updated by every
41
+ * `onLocalNetworkPermissionChange` delivery; `'granted'` on Android below
42
+ * target SDK 37, which never emits a change.
43
+ */
38
44
  permission: CastLocalNetworkPermission;
39
45
  }
40
46
 
@@ -69,7 +75,7 @@ export function useCast(): CastSnapshot {
69
75
  route: getCurrentRoute(),
70
76
  isDiscovering: isDiscovering(),
71
77
  lastSessionDied: null,
72
- permission: 'undetermined',
78
+ permission: getLocalNetworkPermissionState(),
73
79
  };
74
80
  } catch {
75
81
  return INITIAL;
@@ -79,32 +85,25 @@ export function useCast(): CastSnapshot {
79
85
  useEffect(() => {
80
86
  if (!isCastAvailable()) return;
81
87
 
82
- // Each `addXxxListener` synchronously replays the current value on
83
- // subscribe. The initial `useState` initializer already captured
84
- // every initial value; skipping the first replay per stream avoids
85
- // five back-to-back `setSnapshot` calls on mount.
86
- let firstRoute = true;
87
- let firstReceivers = true;
88
- let firstDiscovery = true;
89
- let firstPermission = true;
90
-
88
+ // Each `addXxxListener` replays the current value synchronously on
89
+ // subscribe, and every delivery is applied: a replay that equals the
90
+ // `useState` seed costs one batched render, while a replay that differs
91
+ // is a change that landed between the render and this effect — dropping
92
+ // it would leave the snapshot on the stale seed (on Android the
93
+ // permission replay is the only delivery there ever is).
91
94
  const routeSub = addRouteListener((route) => {
92
- if (firstRoute) { firstRoute = false; return; }
93
95
  setSnapshot((prev) => ({ ...prev, route }));
94
96
  });
95
97
  const receiversSub = addReceiversListener((receivers) => {
96
- if (firstReceivers) { firstReceivers = false; return; }
97
98
  setSnapshot((prev) => ({ ...prev, receivers }));
98
99
  });
99
100
  const discoverySub = addDiscoveryStateListener((state) => {
100
- if (firstDiscovery) { firstDiscovery = false; return; }
101
101
  setSnapshot((prev) => ({ ...prev, isDiscovering: state.isDiscovering }));
102
102
  });
103
103
  const deathSub = addSessionDiedListener((event) =>
104
104
  setSnapshot((prev) => ({ ...prev, lastSessionDied: event }))
105
105
  );
106
106
  const permissionSub = addLocalNetworkPermissionListener((event) => {
107
- if (firstPermission) { firstPermission = false; return; }
108
107
  setSnapshot((prev) => ({ ...prev, permission: event.state }));
109
108
  });
110
109
 
@@ -16,7 +16,8 @@ export interface UseEqualizerResult {
16
16
  }
17
17
 
18
18
  /**
19
- * Subscribes to Equalizer band-change events and exposes imperative setters.
19
+ * Subscribes to Equalizer band-change and enabled-change events and
20
+ * exposes imperative setters.
20
21
  * Initial state is pulled synchronously on mount so consumers don't flash
21
22
  * empty bands.
22
23
  */
@@ -45,21 +46,28 @@ export function useEqualizer(): UseEqualizerResult {
45
46
 
46
47
  useEffect(() => {
47
48
  const eq = getEqualizer();
48
- const dispose = eq.onBandChange((updated) => {
49
+ const disposeBands = eq.onBandChange((updated) => {
49
50
  setBands(updated);
50
51
  });
51
- return dispose;
52
+ const disposeEnabled = eq.onEnabledChange((next) => {
53
+ setEnabledState(next);
54
+ });
55
+ return () => {
56
+ disposeBands();
57
+ disposeEnabled();
58
+ };
52
59
  }, []);
53
60
 
54
61
  const setEnabled = useCallback(async (next: boolean) => {
55
62
  const eq = getEqualizer();
56
63
  await eq.setEnabled(next);
57
- // Read back rather than echoing the requested value: the native
58
- // side may reject (or coerce) the change in a future build, and
59
- // mirroring its actual state keeps JS aligned without a separate
60
- // `onEnabledChange` event. Fall back to the requested value when
61
- // the read-back throws (today's behaviour against the
62
- // unimplemented native matches the seed's try/catch on init).
64
+ // `isEnabled()` is the authority on what the native side committed,
65
+ // so read it back rather than echoing the request. `onEnabledChange`
66
+ // has already delivered the same value both platforms emit it
67
+ // synchronously inside `setEnabled`'s promise body which makes this
68
+ // a redundant write on the happy path and the only correction if a
69
+ // future native build stops emitting. Fall back to the requested
70
+ // value when the read-back throws, matching the seed's try/catch.
63
71
  try {
64
72
  setEnabledState(eq.isEnabled());
65
73
  } catch {
@@ -79,9 +87,8 @@ export function useEqualizer(): UseEqualizerResult {
79
87
  await getEqualizer().applyPreset(name);
80
88
  }, []);
81
89
 
82
- // TODO: wire onPresetsChange when added to Equalizer.nitro.ts
83
- // until then, save/delete refresh the local presets list with a
84
- // manual sync re-fetch.
90
+ // The spec carries no presets-changed event, so save and delete
91
+ // re-read `getPresets()` themselves to refresh the local list.
85
92
  const saveCustomPreset = useCallback(async (name: string) => {
86
93
  await getEqualizer().saveCustomPreset(name);
87
94
  setPresets(getEqualizer().getPresets());
@@ -26,13 +26,9 @@ const INITIAL: CacheStatus = {
26
26
  * and drop the lookahead count).
27
27
  */
28
28
  export function useLookaheadCache(): UseLookaheadCacheResult {
29
- const [status, setStatus] = useState<CacheStatus>(() => {
30
- try {
31
- return getTrackPlayer().getLookaheadCacheStatus();
32
- } catch {
33
- return INITIAL;
34
- }
35
- });
29
+ // Seeded by the listener's own first fire, which delivers current status on
30
+ // registration — no getter call, so this survives the getter being async.
31
+ const [status, setStatus] = useState<CacheStatus>(INITIAL);
36
32
 
37
33
  useEffect(() => {
38
34
  const player = getTrackPlayer();