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.
- package/QueuePlayer.podspec +14 -9
- package/README.md +3 -3
- package/android/build.gradle +7 -0
- package/android/consumer-rules.pro +72 -3
- package/android/src/main/cpp/airplay2_control.c +4 -4
- package/android/src/main/cpp/airplay2_control.h +4 -4
- package/android/src/main/cpp/airplay2_jni.cpp +26 -22
- package/android/src/main/cpp/airplay2_pair.c +7 -7
- package/android/src/main/cpp/airplay2_pair.h +2 -2
- package/android/src/main/cpp/airplay2_rtsp.c +8 -8
- package/android/src/main/cpp/airplay2_session.c +2 -2
- package/android/src/main/cpp/airplay_jni.cpp +20 -72
- package/android/src/main/java/com/margelo/nitro/queueplayer/AirPlayEngine.kt +7 -16
- package/android/src/main/java/com/margelo/nitro/queueplayer/CacheMimeTypes.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/CastManager.kt +2 -14
- package/android/src/main/java/com/margelo/nitro/queueplayer/CellularTransportMonitor.kt +77 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/CrossfadeEngine.kt +187 -52
- package/android/src/main/java/com/margelo/nitro/queueplayer/Equalizer.kt +27 -7
- package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerEngine.kt +33 -12
- package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngine.kt +31 -8
- package/android/src/main/java/com/margelo/nitro/queueplayer/FFTProcessorTee.kt +45 -30
- package/android/src/main/java/com/margelo/nitro/queueplayer/FifoCacheEvictor.kt +111 -15
- package/android/src/main/java/com/margelo/nitro/queueplayer/GaplessEngine.kt +60 -33
- package/android/src/main/java/com/margelo/nitro/queueplayer/HeadlessJsMediaService.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/IEqualizerEngine.kt +3 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCache.kt +103 -29
- package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCacheWriter.kt +77 -29
- package/android/src/main/java/com/margelo/nitro/queueplayer/MediaItemBuilder.kt +6 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractor.kt +48 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/PitchCorrection.kt +3 -2
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackEngine.kt +71 -76
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackErrorMapping.kt +3 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackModeStateMachine.kt +2 -2
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackService.kt +68 -46
- package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackServiceCallback.kt +6 -5
- package/android/src/main/java/com/margelo/nitro/queueplayer/QueueMutationArithmetic.kt +5 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/QueueSkipArithmetic.kt +11 -8
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessor.kt +26 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainData.kt +22 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainExtractor.kt +38 -12
- package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainGain.kt +17 -13
- package/android/src/main/java/com/margelo/nitro/queueplayer/SuppliedReplayGain.kt +66 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/TrackPlayer.kt +870 -278
- package/android/src/main/java/com/margelo/nitro/queueplayer/Visualizer.kt +4 -8
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastBackend.kt +4 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastEventBridge.kt +1 -10
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastSession.kt +17 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastTransportRouter.kt +19 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/RemotePlaybackStateMapping.kt +18 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2JNI.kt +0 -2
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2Session.kt +23 -12
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayBackend.kt +16 -9
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayMetadataSync.kt +58 -21
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayRenderersFactory.kt +6 -14
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlaySession.kt +26 -14
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirplayJNI.kt +1 -13
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/MetadataSyncTarget.kt +20 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/MulticastLockHolder.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/chromecast/ChromecastBackend.kt +3 -3
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/chromecast/ChromecastSession.kt +73 -13
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServer.kt +11 -35
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaServerHandle.kt +0 -5
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaTokenRegistry.kt +0 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitor.kt +32 -33
- package/android/src/test/java/androidx/media3/session/{MediaSessionControllerRequestTestSeam.kt → MediaSessionControllerRequestTestSupport.kt} +1 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/AvrcpMetadataTest.kt +12 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineFocusLossTest.kt +115 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineLifecycleTest.kt +45 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/EngineEndSignalOrderTest.kt +70 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerEngineTest.kt +23 -12
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerKtTest.kt +0 -6
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngineTest.kt +43 -15
- package/android/src/test/java/com/margelo/nitro/queueplayer/FFTProcessorTeeTest.kt +15 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/FifoCacheEvictorTest.kt +135 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineLifecycleTest.kt +1 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineReplayGainTest.kt +36 -2
- package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheTest.kt +24 -18
- package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterCancelTest.kt +85 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterTest.kt +112 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/MediaItemBuilderTest.kt +5 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractorTest.kt +45 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/PitchAwareAudioProcessorChainTest.kt +1 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackSearchTest.kt +47 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackTest.kt +53 -29
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceLifecycleTest.kt +8 -8
- package/android/src/test/java/com/margelo/nitro/queueplayer/QueueSkipArithmeticTest.kt +33 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessorTest.kt +128 -5
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainExtractorTest.kt +209 -14
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainGainTest.kt +150 -10
- package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainMergeTest.kt +258 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/RobolectricServiceBindHelper.kt +8 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/SessionCommandForwardingPlayerTest.kt +2 -2
- package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowDynamicsProcessingRejectingEnable.kt +19 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizer.kt +68 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizerRejectingBandWrites.kt +27 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/SuppliedReplayGainTest.kt +61 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAirPlayMetadataWiringTest.kt +4 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAudioFocusTest.kt +1 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastCommandRoutingTest.kt +163 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastStateTest.kt +123 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerEventsTest.kt +88 -38
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLifecycleTest.kt +205 -27
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLookaheadConfigTest.kt +277 -38
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerMutationTest.kt +5 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerProgressThrottleTest.kt +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueChangeTest.kt +85 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueTest.kt +11 -7
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerReadersTest.kt +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipCapabilityTest.kt +90 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipTest.kt +8 -26
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerTransportTest.kt +3 -3
- package/android/src/test/java/com/margelo/nitro/queueplayer/VisualizerKtTest.kt +0 -4
- package/android/src/test/java/com/margelo/nitro/queueplayer/cast/FakeRemotePlayer.kt +27 -11
- package/android/src/test/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayMetadataSyncTest.kt +303 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitorTest.kt +173 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/ShadowConnectivityManagerRecordingRequests.kt +27 -0
- package/app.plugin.js +17 -1
- package/ios/AVPlayerItemQueueItemId.swift +26 -12
- package/ios/AVQueueBuilder.swift +120 -85
- package/ios/ArtworkLoader.swift +0 -7
- package/ios/ArtworkResolver.swift +22 -4
- package/ios/AssetReplayGainReader.swift +118 -0
- package/ios/AudioSession.swift +67 -16
- package/ios/AudioTapProvider.swift +284 -149
- package/ios/CarPlayBridge.swift +0 -12
- package/ios/CarPlayCoordinator.swift +18 -2
- package/ios/CarPlaySceneDelegate.swift +2 -2
- package/ios/Cast/AirPlayRouteState.swift +9 -8
- package/ios/Cast/Chromecast/ChromecastSession.swift +90 -11
- package/ios/Cast/Core/CastEventBridge.swift +66 -26
- package/ios/Cast/Core/CastNowPlayingController.swift +38 -16
- package/ios/Cast/Core/CastSession.swift +11 -0
- package/ios/Cast/Core/CastTransportRouter.swift +21 -9
- package/ios/Cast/Core/LocalMediaServer.swift +41 -52
- package/ios/Cast/Core/LocalNetworkPermissionProbe.swift +32 -11
- package/ios/Cast/Core/MediaServerHandle.swift +0 -4
- package/ios/Cast/Core/MediaTokenRegistry.swift +0 -6
- package/ios/CastManager.swift +1 -1
- package/ios/CrossfadeEngine.swift +660 -226
- package/ios/EQTap.swift +20 -17
- package/ios/Equalizer.swift +1 -1
- package/ios/FLACStreamInfo.swift +65 -0
- package/ios/GaplessEngine.swift +57 -30
- package/ios/InputGuards.swift +35 -5
- package/ios/LookaheadCache.swift +202 -58
- package/ios/LookaheadCachePrefetcher.swift +48 -36
- package/ios/MediaServer/MediaHTTPConnection.swift +691 -0
- package/ios/NetworkRecoveryPolicy.swift +32 -0
- package/ios/NowPlayingFormatExtractor.swift +25 -18
- package/ios/NowPlayingInfo.swift +84 -48
- package/ios/OutputRouteMonitor.swift +16 -3
- package/ios/PendingBrowseRequests.swift +1 -1
- package/ios/PlaceholderArtwork.swift +9 -5
- package/ios/PlaybackEngine.swift +165 -76
- package/ios/PlaybackErrorMapping.swift +3 -3
- package/ios/PlaybackModeStateMachine.swift +2 -2
- package/ios/PlaybackNetworkMonitor.swift +73 -0
- package/ios/PlayerStateDerivation.swift +6 -6
- package/ios/QueueMutationArithmetic.swift +25 -0
- package/ios/QueueSkipArithmetic.swift +5 -3
- package/ios/QueueWindowArithmetic.swift +152 -0
- package/ios/ReadThroughServer.swift +283 -0
- package/ios/RemoteCommands.swift +44 -4
- package/ios/ReplayGainData.swift +22 -3
- package/ios/ReplayGainExtractor.swift +70 -27
- package/ios/Siri/VoiceDonation.swift +14 -9
- package/ios/StreamingBitrateProbe.swift +22 -68
- package/ios/SuppliedReplayGain.swift +83 -0
- package/ios/Tests/AVQueueBuilderTests.swift +158 -221
- package/ios/Tests/ActiveItemEngineStub.swift +44 -0
- package/ios/Tests/AssetReplayGainReaderTests.swift +228 -0
- package/ios/Tests/AudioTapProviderDispatchTargetTests.swift +158 -0
- package/ios/Tests/AudioTapProviderReplayGainTests.swift +122 -10
- package/ios/Tests/BitrateReresolveBudgetTests.swift +71 -0
- package/ios/Tests/CastMediaItemTranslationTests.swift +72 -0
- package/ios/Tests/CastNowPlayingControllerTests.swift +5 -0
- package/ios/Tests/CrossfadeAdvanceWithoutFadeTests.swift +120 -0
- package/ios/Tests/CrossfadeEngineIncomingMixTests.swift +122 -0
- package/ios/Tests/CrossfadeEngineTests.swift +164 -0
- package/ios/Tests/CrossfadeMixReapplyTests.swift +66 -0
- package/ios/Tests/CrossfadePlaybackIntentTests.swift +81 -0
- package/ios/Tests/EngineSwapTests.swift +91 -0
- package/ios/Tests/EqualizerAudioMixProviderTests.swift +46 -0
- package/ios/Tests/EqualizerHybridTests.swift +5 -2
- package/ios/Tests/FLACStreamInfoTests.swift +88 -0
- package/ios/Tests/GaplessEngineLifecycleTests.swift +4 -4
- package/ios/Tests/InputGuardsTests.swift +41 -0
- package/ios/Tests/InterruptionIntentTests.swift +77 -0
- package/ios/Tests/LookaheadCacheCellularAccessTests.swift +185 -0
- package/ios/Tests/LookaheadCachePrefetcherTests.swift +53 -30
- package/ios/Tests/LookaheadCacheRuntimeConfigTests.swift +160 -1
- package/ios/Tests/LookaheadCacheTests.swift +44 -18
- package/ios/Tests/MediaHTTPConnectionTests.swift +79 -0
- package/ios/Tests/MutationDeferralTests.swift +220 -0
- package/ios/Tests/NowPlayingInfoTests.swift +86 -99
- package/ios/Tests/NowPlayingSnapshotTests.swift +127 -0
- package/ios/Tests/OriginRestartStitcherTests.swift +60 -0
- package/ios/Tests/PlaybackNetworkMonitorTests.swift +95 -0
- package/ios/Tests/PlaybackStateRouterTests.swift +1 -0
- package/ios/Tests/PlayerFixtures.swift +48 -0
- package/ios/Tests/PlayerStateDerivationTests.swift +10 -10
- package/ios/Tests/QueueMutationGenerationTests.swift +141 -0
- package/ios/Tests/QueueRebuildPrefixTests.swift +317 -0
- package/ios/Tests/QueueStateTests.swift +3 -1
- package/ios/Tests/QueueWindowArithmeticTests.swift +56 -0
- package/ios/Tests/QueueWindowSliceTests.swift +162 -0
- package/ios/Tests/ReadThroughRoutingLifecycleTests.swift +63 -0
- package/ios/Tests/ReadThroughServerTests.swift +345 -0
- package/ios/Tests/RemoteCommandsTests.swift +28 -0
- package/ios/Tests/ReplayGainExtractorTests.swift +216 -6
- package/ios/Tests/ReplayGainMergeTests.swift +230 -0
- package/ios/Tests/RetryRecoveryTests.swift +303 -0
- package/ios/Tests/SkipCapabilityTests.swift +233 -8
- package/ios/Tests/SkipIndexTests.swift +32 -2
- package/ios/Tests/SleepTimerPauseIntentTests.swift +43 -0
- package/ios/Tests/StallRecoveryTests.swift +97 -0
- package/ios/Tests/StreamingBitrateProbeTests.swift +17 -20
- package/ios/Tests/TopUpWindowGateTests.swift +394 -0
- package/ios/Tests/TrackPlayer+TestHops.swift +14 -0
- package/ios/Tests/TrackPlayerCallOrderTests.swift +93 -0
- package/ios/Tests/TrackPlayerCastStateTests.swift +78 -0
- package/ios/Tests/TrackPlayerConfigureTeardownTests.swift +86 -0
- package/ios/Tests/TrackPlayerEndVerdictTests.swift +165 -0
- package/ios/Tests/TrackPlayerSeekTests.swift +137 -0
- package/ios/Tests/TrackPlayerThreadingTests.swift +127 -0
- package/ios/Tests/TrackSourceClassifierTests.swift +33 -7
- package/ios/Tests/VoiceVocabularyOptInTests.swift +38 -0
- package/ios/TrackPlayer+Automotive.swift +101 -0
- package/ios/TrackPlayer+Cache.swift +232 -0
- package/ios/TrackPlayer+Config.swift +291 -0
- package/ios/TrackPlayer+EngineDelegate.swift +209 -0
- package/ios/TrackPlayer+EventsAPI.swift +111 -0
- package/ios/TrackPlayer+EventsDispatch.swift +968 -0
- package/ios/TrackPlayer+EventsWiring.swift +173 -0
- package/ios/TrackPlayer+Lifecycle.swift +930 -0
- package/ios/TrackPlayer+NowPlayingFormat.swift +258 -0
- package/ios/TrackPlayer+Queue.swift +940 -0
- package/ios/TrackPlayer+Recovery.swift +196 -0
- package/ios/TrackPlayer+Skip.swift +455 -0
- package/ios/TrackPlayer+SleepTimer.swift +175 -0
- package/ios/TrackPlayer+State.swift +108 -0
- package/ios/TrackPlayer+Threading.swift +135 -0
- package/ios/TrackPlayer+Transport.swift +267 -0
- package/ios/TrackPlayer+Window.swift +195 -0
- package/ios/TrackPlayer.swift +305 -4610
- package/ios/Visualizer.swift +6 -5
- package/ios/tests-harness/Podfile +1 -1
- package/ios/tests-harness/TestHost.xcodeproj/project.pbxproj +19 -11
- package/ios/tests-harness/scripts/seed-xcodeproj.rb +2 -2
- package/lib/module/hooks/useActiveTrack.js +29 -22
- package/lib/module/hooks/useActiveTrack.js.map +1 -1
- package/lib/module/hooks/useCast.js +8 -26
- package/lib/module/hooks/useCast.js.map +1 -1
- package/lib/module/hooks/useEqualizer.js +19 -12
- package/lib/module/hooks/useEqualizer.js.map +1 -1
- package/lib/module/hooks/useLookaheadCache.js +3 -7
- package/lib/module/hooks/useLookaheadCache.js.map +1 -1
- package/lib/module/hooks/useQueue.js +66 -19
- package/lib/module/hooks/useQueue.js.map +1 -1
- package/lib/module/index.js +6 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/queueDelta.js +41 -0
- package/lib/module/queueDelta.js.map +1 -0
- package/lib/module/types.js +28 -5
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/TrackPlayer.nitro.d.ts +53 -28
- package/lib/typescript/TrackPlayer.nitro.d.ts.map +1 -1
- package/lib/typescript/hooks/useActiveTrack.d.ts +5 -7
- package/lib/typescript/hooks/useActiveTrack.d.ts.map +1 -1
- package/lib/typescript/hooks/useCast.d.ts +6 -1
- package/lib/typescript/hooks/useCast.d.ts.map +1 -1
- package/lib/typescript/hooks/useEqualizer.d.ts +2 -1
- package/lib/typescript/hooks/useEqualizer.d.ts.map +1 -1
- package/lib/typescript/hooks/useLookaheadCache.d.ts.map +1 -1
- package/lib/typescript/hooks/useQueue.d.ts +4 -4
- package/lib/typescript/hooks/useQueue.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/queueDelta.d.ts +10 -0
- package/lib/typescript/queueDelta.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +168 -12
- package/lib/typescript/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JFunc_void_QueueChangeDelta_double_QueueChangeReason.hpp +85 -0
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +45 -19
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +3 -3
- package/nitrogen/generated/android/c++/JLookaheadCacheConfig.hpp +8 -4
- package/nitrogen/generated/android/c++/JPlayerConfig.hpp +5 -1
- package/nitrogen/generated/android/c++/JQueueChangeDelta.hpp +128 -0
- package/nitrogen/generated/android/c++/JTrackItem.hpp +19 -3
- 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
- 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
- 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
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_AudioRoute.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_BufferState.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CacheStatus.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastDiscoveryState.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastLocalNetworkPermissionEvent.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastRoute.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastSessionDiedEvent.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlaybackError.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerProgress.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerState_StateChangeReason.kt +0 -2
- 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
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_ServiceReadyReason.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SkipCapability.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SleepTimerState.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerErrorReason.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerFrame.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_bool.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_double_double.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_TrackItem__double_TrackChangeReason_std__optional_double_.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_std__variant_nitro__NullType__NowPlayingFormat__.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_CastReceiver_.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_EqualizerBand_.kt +0 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridCastManagerSpec.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridEqualizerSpec.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridTrackPlayerSpec.kt +6 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridVisualizerSpec.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/LookaheadCacheConfig.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/PlayerConfig.kt +7 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/QueueChangeDelta.kt +86 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/TrackItem.kt +24 -4
- package/nitrogen/generated/android/queueplayerOnLoad.cpp +2 -2
- package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.cpp +16 -16
- package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.hpp +80 -65
- package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +6 -3
- package/nitrogen/generated/ios/swift/Func_void_CacheStatus.swift +5 -5
- package/nitrogen/generated/ios/swift/Func_void_QueueChangeDelta_double_QueueChangeReason.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +3 -3
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +32 -24
- package/nitrogen/generated/ios/swift/LookaheadCacheConfig.swift +20 -2
- package/nitrogen/generated/ios/swift/PlayerConfig.swift +19 -1
- package/nitrogen/generated/ios/swift/QueueChangeDelta.swift +82 -0
- package/nitrogen/generated/ios/swift/TrackItem.swift +73 -1
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +6 -3
- package/nitrogen/generated/shared/c++/LookaheadCacheConfig.hpp +7 -3
- package/nitrogen/generated/shared/c++/PlayerConfig.hpp +5 -1
- package/nitrogen/generated/shared/c++/QueueChangeDelta.hpp +113 -0
- package/nitrogen/generated/shared/c++/TrackItem.hpp +18 -2
- package/package.json +8 -8
- package/src/TrackPlayer.nitro.ts +53 -27
- package/src/hooks/useActiveTrack.ts +29 -22
- package/src/hooks/useCast.ts +14 -15
- package/src/hooks/useEqualizer.ts +19 -12
- package/src/hooks/useLookaheadCache.ts +3 -7
- package/src/hooks/useQueue.ts +66 -17
- package/src/index.ts +13 -3
- package/src/queueDelta.ts +41 -0
- package/src/types.ts +169 -12
- package/android/src/main/java/com/margelo/nitro/queueplayer/PendingIntentBuffer.kt +0 -82
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2MetadataSync.kt +0 -189
- package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServerLifecycle.kt +0 -15
- package/android/src/test/java/com/margelo/nitro/queueplayer/PendingIntentBufferTest.kt +0 -192
- package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackEngineInterfaceTest.kt +0 -135
- package/android/src/test/java/com/margelo/nitro/queueplayer/SmokeTest.kt +0 -27
- package/ios/Cast/Core/LocalAddressMonitor.swift +0 -110
- package/ios/Cast/Core/MediaHTTPConnection.swift +0 -349
- package/ios/MetadataReader.swift +0 -555
- package/ios/Tests/CrossfadeEngineStubTests.swift +0 -43
- package/ios/Tests/MetadataReaderTests.swift +0 -603
- package/ios/Tests/PlaybackEngineProtocolTests.swift +0 -92
- package/ios/Tests/VoiceDonationTests.swift +0 -26
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__double_QueueChangeReason.hpp +0 -101
- package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem__double_QueueChangeReason.swift +0 -46
- /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": "
|
|
4
|
-
"description": "Nitro Modules audio playback library for React Native
|
|
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.
|
|
87
|
-
"@react-native/jest-preset": "0.
|
|
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.
|
|
92
|
+
"nitrogen": "^0.37.1",
|
|
93
93
|
"react": "19.2.3",
|
|
94
|
-
"react-native": "0.
|
|
94
|
+
"react-native": "0.86.3",
|
|
95
95
|
"react-native-builder-bob": "^0.41.0",
|
|
96
|
-
"react-native-nitro-modules": "^0.
|
|
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.
|
|
105
|
+
"react-native-nitro-modules": "^0.37.1"
|
|
106
106
|
},
|
|
107
107
|
"peerDependenciesMeta": {
|
|
108
108
|
"@expo/config-plugins": {
|
package/src/TrackPlayer.nitro.ts
CHANGED
|
@@ -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
|
-
*
|
|
115
|
+
* Resolves with the current queue snapshot.
|
|
115
116
|
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* `
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
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
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
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 `(
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
* `
|
|
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()`
|
|
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
|
-
|
|
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
|
|
456
|
-
* a breaking API change.
|
|
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
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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
|
|
55
|
+
return () => {
|
|
56
|
+
disposed = true;
|
|
57
|
+
dispose();
|
|
58
|
+
};
|
|
52
59
|
}, []);
|
|
53
60
|
|
|
54
61
|
return snapshot;
|
package/src/hooks/useCast.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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:
|
|
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`
|
|
83
|
-
// subscribe
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
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
|
|
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
|
|
49
|
+
const disposeBands = eq.onBandChange((updated) => {
|
|
49
50
|
setBands(updated);
|
|
50
51
|
});
|
|
51
|
-
|
|
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
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
// `
|
|
61
|
-
// the
|
|
62
|
-
//
|
|
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
|
-
//
|
|
83
|
-
//
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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();
|