react-native-queue-player 1.2.0 → 2.0.1
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/consumer-rules.pro +1 -1
- 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 +3 -19
- 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 +8 -69
- 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 +111 -29
- package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCacheWriter.kt +78 -30
- package/android/src/main/java/com/margelo/nitro/queueplayer/MediaItemBuilder.kt +6 -6
- package/android/src/main/java/com/margelo/nitro/queueplayer/MediaResponseCheck.kt +156 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/MediaValidatingDataSource.kt +165 -0
- package/android/src/main/java/com/margelo/nitro/queueplayer/MimeCapturingDataSource.kt +18 -9
- 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 +13 -5
- 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 +985 -276
- 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/CastSession.kt +5 -4
- 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 +4 -2
- 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 +1 -1
- 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/AirplayJNI.kt +1 -13
- 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/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 +17 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerKtTest.kt +0 -6
- package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngineTest.kt +17 -0
- 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 +84 -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/MediaResponseCheckTest.kt +163 -0
- package/android/src/test/java/com/margelo/nitro/queueplayer/MediaValidatingDataSourceTest.kt +189 -0
- 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 +2 -2
- 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 +1 -1
- 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 +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastStateTest.kt +2 -1
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerEventsTest.kt +122 -38
- package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLifecycleTest.kt +291 -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 +2 -2
- 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/Core/CastEventBridge.swift +66 -26
- package/ios/Cast/Core/CastNowPlayingController.swift +38 -16
- package/ios/Cast/Core/CastSession.swift +2 -2
- 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 +672 -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 +229 -58
- package/ios/LookaheadCachePrefetcher.swift +48 -36
- package/ios/MediaResponseCheck.swift +122 -0
- 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 +1 -1
- 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/MediaResponseCheckTests.swift +128 -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/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 +418 -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 +441 -0
- package/ios/Tests/TrackPlayer+TestHops.swift +14 -0
- package/ios/Tests/TrackPlayerCallOrderTests.swift +93 -0
- package/ios/Tests/TrackPlayerConfigureTeardownTests.swift +86 -0
- package/ios/Tests/TrackPlayerEndVerdictTests.swift +206 -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 +1042 -0
- package/ios/TrackPlayer+EventsWiring.swift +173 -0
- package/ios/TrackPlayer+Lifecycle.swift +982 -0
- package/ios/TrackPlayer+NowPlayingFormat.swift +258 -0
- package/ios/TrackPlayer+Queue.swift +951 -0
- package/ios/TrackPlayer+Recovery.swift +213 -0
- package/ios/TrackPlayer+Skip.swift +465 -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 +272 -0
- package/ios/TrackPlayer+Window.swift +227 -0
- package/ios/TrackPlayer.swift +331 -4619
- 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/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
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
package com.margelo.nitro.queueplayer
|
|
2
|
-
|
|
3
|
-
import org.junit.Assert.assertEquals
|
|
4
|
-
import org.junit.Assert.assertFalse
|
|
5
|
-
import org.junit.Assert.assertNull
|
|
6
|
-
import org.junit.Assert.assertTrue
|
|
7
|
-
import org.junit.Test
|
|
8
|
-
import java.util.concurrent.CountDownLatch
|
|
9
|
-
import java.util.concurrent.Executors
|
|
10
|
-
import java.util.concurrent.TimeUnit
|
|
11
|
-
import java.util.concurrent.atomic.AtomicLong
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Coverage for the single-slot pending intent buffer.
|
|
15
|
-
* Drives push / drain / peek / clear / isEmpty directly with a
|
|
16
|
-
* synthetic payload so the generic shape is exercised without
|
|
17
|
-
* dragging Nitrogen-bridged request types into the test target.
|
|
18
|
-
*/
|
|
19
|
-
class PendingIntentBufferTest {
|
|
20
|
-
|
|
21
|
-
private data class Sample(val payload: String)
|
|
22
|
-
|
|
23
|
-
private class FakeClock(start: Long) {
|
|
24
|
-
private val now = AtomicLong(start)
|
|
25
|
-
fun nowMillis(): Long = now.get()
|
|
26
|
-
fun advance(byMillis: Long) {
|
|
27
|
-
now.addAndGet(byMillis)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private fun makeBuffer(
|
|
32
|
-
ttlMillis: Long = 20_000L,
|
|
33
|
-
clock: FakeClock,
|
|
34
|
-
): PendingIntentBuffer<Sample> = PendingIntentBuffer(ttlMillis = ttlMillis, clock = clock::nowMillis)
|
|
35
|
-
|
|
36
|
-
@Test
|
|
37
|
-
fun `empty buffer drains null`() {
|
|
38
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
39
|
-
assertNull(buffer.drain())
|
|
40
|
-
assertNull(buffer.peek())
|
|
41
|
-
assertTrue(buffer.isEmpty())
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@Test
|
|
45
|
-
fun `push then drain returns the request`() {
|
|
46
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
47
|
-
buffer.push(Sample("first"))
|
|
48
|
-
assertEquals(Sample("first"), buffer.drain())
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@Test
|
|
52
|
-
fun `drain empties the buffer`() {
|
|
53
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
54
|
-
buffer.push(Sample("first"))
|
|
55
|
-
buffer.drain()
|
|
56
|
-
assertNull(buffer.drain())
|
|
57
|
-
assertTrue(buffer.isEmpty())
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@Test
|
|
61
|
-
fun `second push replaces the first`() {
|
|
62
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
63
|
-
buffer.push(Sample("first"))
|
|
64
|
-
buffer.push(Sample("second"))
|
|
65
|
-
assertEquals(Sample("second"), buffer.drain())
|
|
66
|
-
assertNull(buffer.drain())
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
@Test
|
|
70
|
-
fun `peek does not empty the buffer`() {
|
|
71
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
72
|
-
buffer.push(Sample("first"))
|
|
73
|
-
assertEquals(Sample("first"), buffer.peek())
|
|
74
|
-
assertEquals(Sample("first"), buffer.peek())
|
|
75
|
-
assertEquals(Sample("first"), buffer.drain())
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@Test
|
|
79
|
-
fun `expired entry drains null`() {
|
|
80
|
-
val clock = FakeClock(start = 1_000L)
|
|
81
|
-
val buffer = makeBuffer(ttlMillis = 20_000L, clock = clock)
|
|
82
|
-
buffer.push(Sample("stale"))
|
|
83
|
-
clock.advance(byMillis = 21_000L)
|
|
84
|
-
assertNull(buffer.drain())
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
@Test
|
|
88
|
-
fun `expired entry peeks null and clears`() {
|
|
89
|
-
val clock = FakeClock(start = 1_000L)
|
|
90
|
-
val buffer = makeBuffer(ttlMillis = 20_000L, clock = clock)
|
|
91
|
-
buffer.push(Sample("stale"))
|
|
92
|
-
clock.advance(byMillis = 25_000L)
|
|
93
|
-
assertNull(buffer.peek())
|
|
94
|
-
assertTrue(buffer.isEmpty())
|
|
95
|
-
assertNull(buffer.drain())
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
@Test
|
|
99
|
-
fun `just before TTL boundary still drains`() {
|
|
100
|
-
val clock = FakeClock(start = 1_000L)
|
|
101
|
-
val buffer = makeBuffer(ttlMillis = 20_000L, clock = clock)
|
|
102
|
-
buffer.push(Sample("fresh"))
|
|
103
|
-
clock.advance(byMillis = 19_900L)
|
|
104
|
-
assertEquals(Sample("fresh"), buffer.drain())
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@Test
|
|
108
|
-
fun `zero TTL same instant drains`() {
|
|
109
|
-
val clock = FakeClock(start = 1_000L)
|
|
110
|
-
val buffer = makeBuffer(ttlMillis = 0L, clock = clock)
|
|
111
|
-
buffer.push(Sample("now"))
|
|
112
|
-
assertEquals(Sample("now"), buffer.drain())
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
@Test
|
|
116
|
-
fun `zero TTL after advance drops entry`() {
|
|
117
|
-
val clock = FakeClock(start = 1_000L)
|
|
118
|
-
val buffer = makeBuffer(ttlMillis = 0L, clock = clock)
|
|
119
|
-
buffer.push(Sample("now"))
|
|
120
|
-
clock.advance(byMillis = 1L)
|
|
121
|
-
assertNull(buffer.drain())
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
@Test
|
|
125
|
-
fun `negative clock skew clamps to zero elapsed`() {
|
|
126
|
-
val clock = FakeClock(start = 1_000L)
|
|
127
|
-
val buffer = makeBuffer(ttlMillis = 20_000L, clock = clock)
|
|
128
|
-
buffer.push(Sample("fresh"))
|
|
129
|
-
clock.advance(byMillis = -10_000L)
|
|
130
|
-
assertEquals(Sample("fresh"), buffer.drain())
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
@Test
|
|
134
|
-
fun `push after peek cleared expired slot returns fresh entry`() {
|
|
135
|
-
val clock = FakeClock(start = 1_000L)
|
|
136
|
-
val buffer = makeBuffer(ttlMillis = 20_000L, clock = clock)
|
|
137
|
-
buffer.push(Sample("stale"))
|
|
138
|
-
clock.advance(byMillis = 25_000L)
|
|
139
|
-
assertNull(buffer.peek())
|
|
140
|
-
assertTrue(buffer.isEmpty())
|
|
141
|
-
buffer.push(Sample("fresh"))
|
|
142
|
-
assertEquals(Sample("fresh"), buffer.drain())
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
@Test
|
|
146
|
-
fun `clear empties without return`() {
|
|
147
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
148
|
-
buffer.push(Sample("first"))
|
|
149
|
-
buffer.clear()
|
|
150
|
-
assertNull(buffer.drain())
|
|
151
|
-
assertTrue(buffer.isEmpty())
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
@Test
|
|
155
|
-
fun `interleaved push and drain serialise safely`() {
|
|
156
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
157
|
-
val executor = Executors.newFixedThreadPool(4)
|
|
158
|
-
val latch = CountDownLatch(400)
|
|
159
|
-
try {
|
|
160
|
-
repeat(200) { i ->
|
|
161
|
-
executor.submit {
|
|
162
|
-
buffer.push(Sample("p-$i"))
|
|
163
|
-
latch.countDown()
|
|
164
|
-
}
|
|
165
|
-
executor.submit {
|
|
166
|
-
buffer.drain()
|
|
167
|
-
latch.countDown()
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
val finished = latch.await(2, TimeUnit.SECONDS)
|
|
171
|
-
assertTrue("interleaved push/drain did not finish within 2 s", finished)
|
|
172
|
-
} finally {
|
|
173
|
-
executor.shutdownNow()
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
@Test
|
|
178
|
-
fun `isEmpty reports true after expiry without explicit drain`() {
|
|
179
|
-
val clock = FakeClock(start = 1_000L)
|
|
180
|
-
val buffer = makeBuffer(ttlMillis = 20_000L, clock = clock)
|
|
181
|
-
buffer.push(Sample("stale"))
|
|
182
|
-
clock.advance(byMillis = 21_000L)
|
|
183
|
-
assertTrue(buffer.isEmpty())
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
@Test
|
|
187
|
-
fun `isEmpty reports false when a fresh entry exists`() {
|
|
188
|
-
val buffer = PendingIntentBuffer<Sample>()
|
|
189
|
-
buffer.push(Sample("fresh"))
|
|
190
|
-
assertFalse(buffer.isEmpty())
|
|
191
|
-
}
|
|
192
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
package com.margelo.nitro.queueplayer
|
|
2
|
-
|
|
3
|
-
import androidx.media3.common.MediaItem
|
|
4
|
-
import androidx.media3.common.PlaybackException
|
|
5
|
-
import androidx.media3.common.util.UnstableApi
|
|
6
|
-
import androidx.media3.exoplayer.ExoPlayer
|
|
7
|
-
import androidx.media3.exoplayer.audio.TeeAudioProcessor
|
|
8
|
-
import androidx.test.core.app.ApplicationProvider
|
|
9
|
-
import org.junit.runner.RunWith
|
|
10
|
-
import org.robolectric.RobolectricTestRunner
|
|
11
|
-
import org.robolectric.annotation.Config
|
|
12
|
-
import org.junit.Assert.assertEquals
|
|
13
|
-
import org.junit.Assert.assertNotNull
|
|
14
|
-
import org.junit.Test
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Type-check coverage for [PlaybackEngine] + [PlaybackEngineDelegate].
|
|
18
|
-
* The interface has no runtime; this suite exercises the type
|
|
19
|
-
* surface so a regression that drops a method or rotates a parameter
|
|
20
|
-
* shape surfaces immediately. Goes away once the real `GaplessEngine`
|
|
21
|
-
* impl pins the type surface from a runtime perspective.
|
|
22
|
-
*/
|
|
23
|
-
@RunWith(RobolectricTestRunner::class)
|
|
24
|
-
@Config(sdk = [34])
|
|
25
|
-
@UnstableApi
|
|
26
|
-
class PlaybackEngineInterfaceTest {
|
|
27
|
-
|
|
28
|
-
@Test
|
|
29
|
-
fun `PlaybackEngine surface compiles with all method signatures reachable`() {
|
|
30
|
-
val stub = NoopPlaybackEngine()
|
|
31
|
-
assertNotNull(stub)
|
|
32
|
-
// Empty-queue sentinel: -1 (matches TrackPlayer.currentTrackIndex).
|
|
33
|
-
assertEquals(-1, stub.currentMediaItemIndex)
|
|
34
|
-
assertEquals(0L, stub.currentPositionMs)
|
|
35
|
-
assertEquals(0L, stub.currentDurationMs)
|
|
36
|
-
assertEquals(0L, stub.bufferedPositionMs)
|
|
37
|
-
assertEquals(false, stub.isPlaying)
|
|
38
|
-
assertEquals(null, stub.currentMediaItem)
|
|
39
|
-
assertEquals(0, stub.allMediaItems.size)
|
|
40
|
-
assertEquals(0, stub.currentAudioSessionIds().size)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@Test
|
|
44
|
-
fun `audio-session-id listener add returns a disposer`() {
|
|
45
|
-
val stub = NoopPlaybackEngine()
|
|
46
|
-
val dispose = stub.addAudioSessionIdListener { /* noop */ }
|
|
47
|
-
dispose()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@Test
|
|
51
|
-
fun `delegate surface compiles with all callbacks`() {
|
|
52
|
-
val delegate = NoopPlaybackEngineDelegate()
|
|
53
|
-
val stub = NoopPlaybackEngine()
|
|
54
|
-
stub.delegate = delegate
|
|
55
|
-
assertEquals(delegate, stub.delegate)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Minimal compile-only stub. Every method is a no-op; the goal is
|
|
60
|
-
* to surface a type-system change in [PlaybackEngine] as a Kotlin
|
|
61
|
-
* compile error here, not as a silent contract drift.
|
|
62
|
-
*
|
|
63
|
-
* `mediaSessionPlayer` requires a real ExoPlayer instance for
|
|
64
|
-
* type compatibility — the stub builds one against the
|
|
65
|
-
* Robolectric application context but never plays anything.
|
|
66
|
-
*/
|
|
67
|
-
private class NoopPlaybackEngine : PlaybackEngine {
|
|
68
|
-
override val mediaSessionPlayer: ExoPlayer = ExoPlayer.Builder(
|
|
69
|
-
ApplicationProvider.getApplicationContext()
|
|
70
|
-
).build()
|
|
71
|
-
|
|
72
|
-
override suspend fun prepare(
|
|
73
|
-
mediaItems: List<MediaItem>,
|
|
74
|
-
startIndex: Int,
|
|
75
|
-
startPositionMs: Long,
|
|
76
|
-
) = Unit
|
|
77
|
-
|
|
78
|
-
override fun release() = Unit
|
|
79
|
-
|
|
80
|
-
override fun setMediaItems(
|
|
81
|
-
items: List<MediaItem>,
|
|
82
|
-
startIndex: Int,
|
|
83
|
-
startPositionMs: Long,
|
|
84
|
-
) = Unit
|
|
85
|
-
|
|
86
|
-
override fun addMediaItems(items: List<MediaItem>, insertBefore: Int) = Unit
|
|
87
|
-
override fun removeMediaItems(indices: IntArray) = Unit
|
|
88
|
-
override fun moveMediaItem(fromIndex: Int, toIndex: Int) = Unit
|
|
89
|
-
|
|
90
|
-
override fun play() = Unit
|
|
91
|
-
override fun pause() = Unit
|
|
92
|
-
override fun stop() = Unit
|
|
93
|
-
override fun seekTo(index: Int, positionMs: Long) = Unit
|
|
94
|
-
override fun skipToNext() = Unit
|
|
95
|
-
override fun skipToPrevious() = Unit
|
|
96
|
-
|
|
97
|
-
override fun setVolume(volume: Float) = Unit
|
|
98
|
-
override fun setPlaybackSpeed(speed: Float) = Unit
|
|
99
|
-
override fun setRepeatMode(mode: RepeatMode) = Unit
|
|
100
|
-
override fun setPitchCorrectionMode(mode: PitchCorrectionMode) = Unit
|
|
101
|
-
override fun setWakeMode(mode: Int) = Unit
|
|
102
|
-
|
|
103
|
-
override val currentMediaItemIndex: Int = -1
|
|
104
|
-
override val currentPositionMs: Long = 0
|
|
105
|
-
override val currentDurationMs: Long = 0
|
|
106
|
-
override val bufferedPositionMs: Long = 0
|
|
107
|
-
override val isPlaying: Boolean = false
|
|
108
|
-
override val currentMediaItem: MediaItem? = null
|
|
109
|
-
override val isCrossfadeActive: Boolean = false
|
|
110
|
-
override val allMediaItems: List<MediaItem> = emptyList()
|
|
111
|
-
|
|
112
|
-
override fun currentAudioSessionIds(): IntArray = IntArray(0)
|
|
113
|
-
|
|
114
|
-
override fun addAudioSessionIdListener(listener: (IntArray) -> Unit): () -> Unit = { /* noop */ }
|
|
115
|
-
|
|
116
|
-
override fun attachAudioBufferSink(sink: TeeAudioProcessor.AudioBufferSink) = Unit
|
|
117
|
-
override fun detachAudioBufferSink(sink: TeeAudioProcessor.AudioBufferSink) = Unit
|
|
118
|
-
|
|
119
|
-
override suspend fun handoff(to: PlaybackEngine, atTrackBoundary: Boolean) = Unit
|
|
120
|
-
|
|
121
|
-
override var delegate: PlaybackEngineDelegate? = null
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private class NoopPlaybackEngineDelegate : PlaybackEngineDelegate {
|
|
125
|
-
override fun onStateMaybeChanged(engine: PlaybackEngine, playWhenReadyReason: Int?) = Unit
|
|
126
|
-
override fun onIsPlayingChanged(engine: PlaybackEngine, isPlaying: Boolean) = Unit
|
|
127
|
-
override fun onTrackTransition(engine: PlaybackEngine, platformReason: Int) = Unit
|
|
128
|
-
override fun onActiveItemFormatChanged(engine: PlaybackEngine) = Unit
|
|
129
|
-
override fun onError(engine: PlaybackEngine, exception: PlaybackException) = Unit
|
|
130
|
-
override fun onPlaybackEnded(engine: PlaybackEngine) = Unit
|
|
131
|
-
override fun onAutoTransitionDiscontinuity(engine: PlaybackEngine) = Unit
|
|
132
|
-
override fun onCrossfadeBegin(engine: PlaybackEngine, incomingIndex: Int) = Unit
|
|
133
|
-
override fun onCrossfadeCancel(engine: PlaybackEngine, revertedIndex: Int) = Unit
|
|
134
|
-
}
|
|
135
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
package com.margelo.nitro.queueplayer
|
|
2
|
-
|
|
3
|
-
import org.junit.Assert.assertTrue
|
|
4
|
-
import org.junit.Test
|
|
5
|
-
import org.junit.runner.RunWith
|
|
6
|
-
import org.robolectric.RobolectricTestRunner
|
|
7
|
-
import org.robolectric.annotation.Config
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Proves the JUnit + Robolectric test target is
|
|
11
|
-
* wired + `./gradlew :react-native-queue-player:testDebugUnitTest`
|
|
12
|
-
* executes. Real test suites for the Kotlin audio wrappers
|
|
13
|
-
* (MediaItemBuilder, AudioFocus, PlaybackService, LookaheadCache,
|
|
14
|
-
* etc.) live alongside their wrapper sources.
|
|
15
|
-
*
|
|
16
|
-
* @Config sdk=34 because Robolectric 4.11.1 supports up to API 34,
|
|
17
|
-
* while our library's compileSdkVersion is 36. When Robolectric bumps
|
|
18
|
-
* its max-supported SDK to 36 we drop the annotation.
|
|
19
|
-
*/
|
|
20
|
-
@RunWith(RobolectricTestRunner::class)
|
|
21
|
-
@Config(sdk = [34])
|
|
22
|
-
class SmokeTest {
|
|
23
|
-
@Test
|
|
24
|
-
fun smoke_sanity() {
|
|
25
|
-
assertTrue("smoke", true)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
import Network
|
|
3
|
-
|
|
4
|
-
/// Wraps `NWPathMonitor` to publish the local IPv4 address over the
|
|
5
|
-
/// `.wifi` interface. Cellular addresses can't reach a LAN receiver,
|
|
6
|
-
/// so they are intentionally ignored — Chromecast / DLNA / AirPlay
|
|
7
|
-
/// targets are all wifi-local by design.
|
|
8
|
-
final class LocalAddressMonitor {
|
|
9
|
-
|
|
10
|
-
typealias Listener = (String?) -> Void
|
|
11
|
-
|
|
12
|
-
final class Subscription {
|
|
13
|
-
fileprivate let id: UUID
|
|
14
|
-
fileprivate weak var owner: LocalAddressMonitor?
|
|
15
|
-
fileprivate init(id: UUID, owner: LocalAddressMonitor) {
|
|
16
|
-
self.id = id
|
|
17
|
-
self.owner = owner
|
|
18
|
-
}
|
|
19
|
-
func remove() { owner?.removeListener(id: id) }
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
private let monitor = NWPathMonitor(requiredInterfaceType: .wifi)
|
|
23
|
-
private let queue = DispatchQueue(label: "LocalAddressMonitor")
|
|
24
|
-
private let lock = NSLock()
|
|
25
|
-
private var listeners: [UUID: Listener] = [:]
|
|
26
|
-
private var running = false
|
|
27
|
-
|
|
28
|
-
private let addressLock = NSLock()
|
|
29
|
-
private var _currentAddress: String?
|
|
30
|
-
var currentAddress: String? {
|
|
31
|
-
addressLock.lock(); defer { addressLock.unlock() }
|
|
32
|
-
return _currentAddress
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
func start() {
|
|
36
|
-
lock.lock()
|
|
37
|
-
if running { lock.unlock(); return }
|
|
38
|
-
running = true
|
|
39
|
-
lock.unlock()
|
|
40
|
-
monitor.pathUpdateHandler = { [weak self] path in
|
|
41
|
-
guard let self = self else { return }
|
|
42
|
-
let addr: String? = (path.status == .satisfied) ? Self.firstWifiIPv4() : nil
|
|
43
|
-
self.addressLock.lock()
|
|
44
|
-
let changed: Bool = (addr != self._currentAddress)
|
|
45
|
-
self._currentAddress = addr
|
|
46
|
-
self.addressLock.unlock()
|
|
47
|
-
if changed {
|
|
48
|
-
self.dispatch(addr)
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
monitor.start(queue: queue)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
func stop() {
|
|
55
|
-
lock.lock()
|
|
56
|
-
if !running { lock.unlock(); return }
|
|
57
|
-
running = false
|
|
58
|
-
lock.unlock()
|
|
59
|
-
monitor.cancel()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
func addListener(_ listener: @escaping Listener) -> Subscription {
|
|
63
|
-
let id = UUID()
|
|
64
|
-
lock.lock()
|
|
65
|
-
listeners[id] = listener
|
|
66
|
-
lock.unlock()
|
|
67
|
-
return Subscription(id: id, owner: self)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
fileprivate func removeListener(id: UUID) {
|
|
71
|
-
lock.lock()
|
|
72
|
-
listeners.removeValue(forKey: id)
|
|
73
|
-
lock.unlock()
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
private func dispatch(_ addr: String?) {
|
|
77
|
-
lock.lock()
|
|
78
|
-
let snapshot = Array(listeners.values)
|
|
79
|
-
lock.unlock()
|
|
80
|
-
for l in snapshot { l(addr) }
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/// Enumerate BSD interfaces and return the first IPv4 address on an
|
|
84
|
-
/// `en*` interface (Wi-Fi). Synchronous so callers can probe without
|
|
85
|
-
/// waiting for the `NWPathMonitor` first-update callback.
|
|
86
|
-
static func firstWifiIPv4() -> String? {
|
|
87
|
-
var ifaddrPtr: UnsafeMutablePointer<ifaddrs>?
|
|
88
|
-
guard getifaddrs(&ifaddrPtr) == 0, let first = ifaddrPtr else { return nil }
|
|
89
|
-
defer { freeifaddrs(ifaddrPtr) }
|
|
90
|
-
var ptr: UnsafeMutablePointer<ifaddrs>? = first
|
|
91
|
-
while let current = ptr {
|
|
92
|
-
defer { ptr = current.pointee.ifa_next }
|
|
93
|
-
let name = String(cString: current.pointee.ifa_name)
|
|
94
|
-
guard name.hasPrefix("en") else { continue }
|
|
95
|
-
guard let sa = current.pointee.ifa_addr else { continue }
|
|
96
|
-
guard sa.pointee.sa_family == UInt8(AF_INET) else { continue }
|
|
97
|
-
var hostBuf = [CChar](repeating: 0, count: Int(NI_MAXHOST))
|
|
98
|
-
let result = getnameinfo(
|
|
99
|
-
sa, socklen_t(sa.pointee.sa_len),
|
|
100
|
-
&hostBuf, socklen_t(hostBuf.count),
|
|
101
|
-
nil, 0, NI_NUMERICHOST
|
|
102
|
-
)
|
|
103
|
-
if result == 0 {
|
|
104
|
-
let host = String(cString: hostBuf)
|
|
105
|
-
if !host.isEmpty && host != "0.0.0.0" { return host }
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return nil
|
|
109
|
-
}
|
|
110
|
-
}
|