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
|
@@ -174,14 +174,6 @@ static struct raopcl_s *toRaop(jlong handle) {
|
|
|
174
174
|
// JNI methods
|
|
175
175
|
// ---------------------------------------------------------------------------
|
|
176
176
|
|
|
177
|
-
static jstring nativeVersion(JNIEnv *env, jclass) {
|
|
178
|
-
return env->NewStringUTF("libraop-0.2.0");
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
static jboolean nativeInitSsl(JNIEnv *, jclass) {
|
|
182
|
-
return cross_ssl_load() ? JNI_TRUE : JNI_FALSE;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
177
|
/**
|
|
186
178
|
* Open a RAOP session. Returns a handle (pointer-as-long) or 0 on failure.
|
|
187
179
|
*
|
|
@@ -356,34 +348,7 @@ static jint nativeRingAvailable(JNIEnv *, jclass, jlong handle) {
|
|
|
356
348
|
return static_cast<jint>(avail);
|
|
357
349
|
}
|
|
358
350
|
|
|
359
|
-
// --
|
|
360
|
-
|
|
361
|
-
static jboolean nativeAcceptFrames(JNIEnv *, jclass, jlong handle) {
|
|
362
|
-
auto *r = toRaop(handle);
|
|
363
|
-
return (r && raopcl_accept_frames(r)) ? JNI_TRUE : JNI_FALSE;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
static jboolean nativeSendChunk(JNIEnv *env, jclass,
|
|
367
|
-
jlong handle,
|
|
368
|
-
jbyteArray data, jint offset, jint length) {
|
|
369
|
-
auto *r = toRaop(handle);
|
|
370
|
-
if (!r) return JNI_FALSE;
|
|
371
|
-
|
|
372
|
-
jbyte *buf = env->GetByteArrayElements(data, nullptr);
|
|
373
|
-
if (!buf) return JNI_FALSE;
|
|
374
|
-
|
|
375
|
-
uint64_t playtime = 0;
|
|
376
|
-
// Fix: length is bytes, send_chunk expects frames (bytes / 4 for stereo S16)
|
|
377
|
-
bool ok = raopcl_send_chunk(
|
|
378
|
-
r,
|
|
379
|
-
reinterpret_cast<uint8_t *>(buf + offset),
|
|
380
|
-
static_cast<int>(length / 4),
|
|
381
|
-
&playtime
|
|
382
|
-
);
|
|
383
|
-
|
|
384
|
-
env->ReleaseByteArrayElements(data, buf, JNI_ABORT);
|
|
385
|
-
return ok ? JNI_TRUE : JNI_FALSE;
|
|
386
|
-
}
|
|
351
|
+
// -- Transport control --
|
|
387
352
|
|
|
388
353
|
static void nativePause(JNIEnv *, jclass, jlong handle) {
|
|
389
354
|
auto *r = toRaop(handle);
|
|
@@ -409,6 +374,8 @@ static jboolean nativeFlush(JNIEnv *, jclass, jlong handle) {
|
|
|
409
374
|
return (r && raopcl_flush(r)) ? JNI_TRUE : JNI_FALSE;
|
|
410
375
|
}
|
|
411
376
|
|
|
377
|
+
// -- Volume & progress --
|
|
378
|
+
|
|
412
379
|
static jboolean nativeSetVolume(JNIEnv *, jclass, jlong handle, jfloat vol) {
|
|
413
380
|
auto *r = toRaop(handle);
|
|
414
381
|
return (r && raopcl_set_volume(r, vol)) ? JNI_TRUE : JNI_FALSE;
|
|
@@ -422,41 +389,20 @@ static jboolean nativeSetProgressMs(JNIEnv *, jclass, jlong handle,
|
|
|
422
389
|
static_cast<uint32_t>(duration))) ? JNI_TRUE : JNI_FALSE;
|
|
423
390
|
}
|
|
424
391
|
|
|
425
|
-
|
|
426
|
-
auto *r = toRaop(handle);
|
|
427
|
-
return r ? static_cast<jlong>(raopcl_get_progress_ms(r)) : 0;
|
|
428
|
-
}
|
|
392
|
+
// -- State queries --
|
|
429
393
|
|
|
430
394
|
static jboolean nativeIsConnected(JNIEnv *, jclass, jlong handle) {
|
|
431
395
|
auto *r = toRaop(handle);
|
|
432
396
|
return (r && raopcl_is_connected(r)) ? JNI_TRUE : JNI_FALSE;
|
|
433
397
|
}
|
|
434
398
|
|
|
435
|
-
static jboolean nativeIsPlaying(JNIEnv *, jclass, jlong handle) {
|
|
436
|
-
auto *r = toRaop(handle);
|
|
437
|
-
return (r && raopcl_is_playing(r)) ? JNI_TRUE : JNI_FALSE;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
static jint nativeGetState(JNIEnv *, jclass, jlong handle) {
|
|
441
|
-
auto *r = toRaop(handle);
|
|
442
|
-
return r ? static_cast<jint>(raopcl_state(r)) : 0;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
static jint nativeGetLatency(JNIEnv *, jclass, jlong handle) {
|
|
446
|
-
auto *r = toRaop(handle);
|
|
447
|
-
return r ? static_cast<jint>(raopcl_latency(r)) : 0;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
static jint nativeGetSampleRate(JNIEnv *, jclass, jlong handle) {
|
|
451
|
-
auto *r = toRaop(handle);
|
|
452
|
-
return r ? static_cast<jint>(raopcl_sample_rate(r)) : 0;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
399
|
static jboolean nativeKeepalive(JNIEnv *, jclass, jlong handle) {
|
|
456
400
|
auto *r = toRaop(handle);
|
|
457
401
|
return (r && raopcl_keepalive(r)) ? JNI_TRUE : JNI_FALSE;
|
|
458
402
|
}
|
|
459
403
|
|
|
404
|
+
// -- Configuration --
|
|
405
|
+
|
|
460
406
|
static jint nativeGetLastRtspStatus(JNIEnv *, jclass, jlong handle) {
|
|
461
407
|
auto *r = toRaop(handle);
|
|
462
408
|
return r ? static_cast<jint>(raopcl_last_rtsp_status(r)) : 0;
|
|
@@ -484,6 +430,8 @@ static void nativeSetPassword(JNIEnv *env, jclass, jlong handle, jstring jPasswd
|
|
|
484
430
|
}
|
|
485
431
|
}
|
|
486
432
|
|
|
433
|
+
// -- Metadata --
|
|
434
|
+
|
|
487
435
|
static jboolean nativeSetDaap(JNIEnv *env, jclass, jlong handle,
|
|
488
436
|
jstring jTitle, jstring jArtist, jstring jAlbum) {
|
|
489
437
|
auto *r = toRaop(handle);
|
|
@@ -533,8 +481,6 @@ static jboolean nativeSetArtwork(JNIEnv *env, jclass, jlong handle,
|
|
|
533
481
|
// RegisterNatives table
|
|
534
482
|
// ---------------------------------------------------------------------------
|
|
535
483
|
static const JNINativeMethod sMethods[] = {
|
|
536
|
-
{"nativeVersion", "()Ljava/lang/String;", reinterpret_cast<void *>(nativeVersion)},
|
|
537
|
-
{"nativeInitSsl", "()Z", reinterpret_cast<void *>(nativeInitSsl)},
|
|
538
484
|
{"nativeOpen", "(Ljava/lang/String;IIIIIZIIIF)J", reinterpret_cast<void *>(nativeOpen)},
|
|
539
485
|
{"nativeConnect", "(JLjava/lang/String;I)Z", reinterpret_cast<void *>(nativeConnect)},
|
|
540
486
|
{"nativeDisconnect", "(J)Z", reinterpret_cast<void *>(nativeDisconnect)},
|
|
@@ -542,19 +488,12 @@ static const JNINativeMethod sMethods[] = {
|
|
|
542
488
|
{"nativeFeedPcm", "(J[BII)I", reinterpret_cast<void *>(nativeFeedPcm)},
|
|
543
489
|
{"nativeBytesSent", "(J)J", reinterpret_cast<void *>(nativeBytesSent)},
|
|
544
490
|
{"nativeRingAvailable", "(J)I", reinterpret_cast<void *>(nativeRingAvailable)},
|
|
545
|
-
{"nativeAcceptFrames", "(J)Z", reinterpret_cast<void *>(nativeAcceptFrames)},
|
|
546
|
-
{"nativeSendChunk", "(J[BII)Z", reinterpret_cast<void *>(nativeSendChunk)},
|
|
547
491
|
{"nativePause", "(J)V", reinterpret_cast<void *>(nativePause)},
|
|
548
492
|
{"nativeStop", "(J)V", reinterpret_cast<void *>(nativeStop)},
|
|
549
493
|
{"nativeFlush", "(J)Z", reinterpret_cast<void *>(nativeFlush)},
|
|
550
494
|
{"nativeSetVolume", "(JF)Z", reinterpret_cast<void *>(nativeSetVolume)},
|
|
551
495
|
{"nativeSetProgressMs", "(JII)Z", reinterpret_cast<void *>(nativeSetProgressMs)},
|
|
552
|
-
{"nativeGetProgressMs", "(J)J", reinterpret_cast<void *>(nativeGetProgressMs)},
|
|
553
496
|
{"nativeIsConnected", "(J)Z", reinterpret_cast<void *>(nativeIsConnected)},
|
|
554
|
-
{"nativeIsPlaying", "(J)Z", reinterpret_cast<void *>(nativeIsPlaying)},
|
|
555
|
-
{"nativeGetState", "(J)I", reinterpret_cast<void *>(nativeGetState)},
|
|
556
|
-
{"nativeGetLatency", "(J)I", reinterpret_cast<void *>(nativeGetLatency)},
|
|
557
|
-
{"nativeGetSampleRate", "(J)I", reinterpret_cast<void *>(nativeGetSampleRate)},
|
|
558
497
|
{"nativeKeepalive", "(J)Z", reinterpret_cast<void *>(nativeKeepalive)},
|
|
559
498
|
{"nativeGetLastRtspStatus", "(J)I", reinterpret_cast<void *>(nativeGetLastRtspStatus)},
|
|
560
499
|
{"nativeSetPassword", "(JLjava/lang/String;)V", reinterpret_cast<void *>(nativeSetPassword)},
|
|
@@ -576,13 +515,22 @@ jint JNI_OnLoad(JavaVM *vm, void * /* reserved */) {
|
|
|
576
515
|
|
|
577
516
|
jclass clazz = env->FindClass(sClassName);
|
|
578
517
|
if (clazz == nullptr) {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
518
|
+
/* Leaves a pending NoClassDefFoundError. Clear it and fail the load
|
|
519
|
+
* outright: nothing retries registration, so reporting success here
|
|
520
|
+
* would leave the Kotlin object reporting AirPlay 1 as available with
|
|
521
|
+
* no natives bound, and the first call would throw
|
|
522
|
+
* UnsatisfiedLinkError. Failing makes System.loadLibrary throw, and
|
|
523
|
+
* AirplayJNI's initialiser catches that and sets isAvailable false. */
|
|
524
|
+
env->ExceptionClear();
|
|
525
|
+
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
|
526
|
+
"AirplayJNI class not found — AirPlay 1 unavailable");
|
|
527
|
+
return JNI_ERR;
|
|
582
528
|
}
|
|
583
529
|
|
|
584
530
|
if (env->RegisterNatives(clazz, sMethods,
|
|
585
531
|
sizeof(sMethods) / sizeof(sMethods[0])) < 0) {
|
|
532
|
+
/* An unresolved table entry leaves a pending NoSuchMethodError. */
|
|
533
|
+
env->ExceptionClear();
|
|
586
534
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "RegisterNatives failed");
|
|
587
535
|
return JNI_ERR;
|
|
588
536
|
}
|
|
@@ -66,10 +66,11 @@ internal class AirPlayEngine(
|
|
|
66
66
|
|
|
67
67
|
private val playerListener = object : Player.Listener {
|
|
68
68
|
override fun onPlaybackStateChanged(playbackState: Int) {
|
|
69
|
-
|
|
69
|
+
// End signal before the generic state callback, as in GaplessEngine.
|
|
70
70
|
if (playbackState == Player.STATE_ENDED) {
|
|
71
71
|
delegate?.onPlaybackEnded(this@AirPlayEngine)
|
|
72
72
|
}
|
|
73
|
+
delegate?.onStateMaybeChanged(this@AirPlayEngine, playWhenReadyReason = null)
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
|
|
@@ -129,15 +130,6 @@ internal class AirPlayEngine(
|
|
|
129
130
|
|
|
130
131
|
// --- PlaybackEngine — lifecycle ---
|
|
131
132
|
|
|
132
|
-
override suspend fun prepare(
|
|
133
|
-
mediaItems: List<MediaItem>,
|
|
134
|
-
startIndex: Int,
|
|
135
|
-
startPositionMs: Long,
|
|
136
|
-
) {
|
|
137
|
-
exoPlayer.setMediaItems(mediaItems, startIndex, startPositionMs)
|
|
138
|
-
exoPlayer.prepare()
|
|
139
|
-
}
|
|
140
|
-
|
|
141
133
|
override fun release() {
|
|
142
134
|
if (released) return
|
|
143
135
|
released = true
|
|
@@ -168,6 +160,11 @@ internal class AirPlayEngine(
|
|
|
168
160
|
startIndex: Int,
|
|
169
161
|
startPositionMs: Long,
|
|
170
162
|
) {
|
|
163
|
+
if (items.isEmpty()) {
|
|
164
|
+
// Draining is not pausing: `playWhenReady` survives an empty playlist,
|
|
165
|
+
// so the next queue seated on this player would start on contact.
|
|
166
|
+
exoPlayer.pause()
|
|
167
|
+
}
|
|
171
168
|
exoPlayer.setMediaItems(items, startIndex, startPositionMs)
|
|
172
169
|
// ExoPlayer is IDLE after construction; prepare() is required before any
|
|
173
170
|
// subsequent play() can take effect (mirrors GaplessEngine).
|
|
@@ -272,12 +269,6 @@ internal class AirPlayEngine(
|
|
|
272
269
|
|
|
273
270
|
// ReplayGain absent on the AirPlay engine — interface defaults
|
|
274
271
|
// (currentReplayGainData() = null, currentReplayGainActive() = false) apply.
|
|
275
|
-
|
|
276
|
-
// --- PlaybackEngine — handoff ---
|
|
277
|
-
|
|
278
|
-
override suspend fun handoff(to: PlaybackEngine, atTrackBoundary: Boolean) {
|
|
279
|
-
throw NotImplementedError("PlaybackEngine.handoff is not supported by AirPlayEngine")
|
|
280
|
-
}
|
|
281
272
|
}
|
|
282
273
|
|
|
283
274
|
/**
|
|
@@ -3,7 +3,7 @@ package com.margelo.nitro.queueplayer
|
|
|
3
3
|
import java.net.URI
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* MIME-type
|
|
6
|
+
* MIME-type handling for the lookahead cache. Mirrors iOS's
|
|
7
7
|
* `LookaheadCache.extensionFromMimeType` / `extensionFromUrl` —
|
|
8
8
|
* lets the Android cache record the same Content-Type signal so
|
|
9
9
|
* Media3 can be told the format up front via
|
|
@@ -526,12 +526,8 @@ class CastManager : HybridCastManagerSpec() {
|
|
|
526
526
|
}
|
|
527
527
|
airplayScope.launch {
|
|
528
528
|
try {
|
|
529
|
-
val
|
|
530
|
-
|
|
531
|
-
val receiverId = pendingId ?: lastConnectedAirplayReceiverId() ?: ""
|
|
532
|
-
if (receiverId.isNotEmpty()) {
|
|
533
|
-
installAirplaySession(session, receiverId)
|
|
534
|
-
}
|
|
529
|
+
val paired = backend.submitPairingPin(pin)
|
|
530
|
+
installAirplaySession(paired.session, paired.receiverId)
|
|
535
531
|
promise.resolve(Unit)
|
|
536
532
|
} catch (t: Throwable) {
|
|
537
533
|
promise.reject(t)
|
|
@@ -540,14 +536,6 @@ class CastManager : HybridCastManagerSpec() {
|
|
|
540
536
|
return promise
|
|
541
537
|
}
|
|
542
538
|
|
|
543
|
-
/// Look up the most recently visible AirPlay receiver that pair-setup
|
|
544
|
-
/// would have stashed against. The pending pair's receiverId isn't
|
|
545
|
-
/// directly accessible from the public backend surface; lookup via
|
|
546
|
-
/// the discovered snapshot is good enough — the user pairs the device
|
|
547
|
-
/// they just saw in the picker.
|
|
548
|
-
private fun lastConnectedAirplayReceiverId(): String? =
|
|
549
|
-
airplayReceivers.firstOrNull()?.id
|
|
550
|
-
|
|
551
539
|
override fun getLocalNetworkPermissionState(): CastLocalNetworkPermission =
|
|
552
540
|
localNetworkPermissionState()
|
|
553
541
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
package com.margelo.nitro.queueplayer
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.net.ConnectivityManager
|
|
5
|
+
import android.net.Network
|
|
6
|
+
import android.net.NetworkCapabilities
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Reports whether the default network is cellular, and fires when that
|
|
10
|
+
* changes.
|
|
11
|
+
*
|
|
12
|
+
* Prefetch downloads whole upcoming tracks, so a consumer that has turned
|
|
13
|
+
* `allowsCellularAccess` off needs the window to empty the moment the device
|
|
14
|
+
* hands off to cellular — otherwise a download started on Wi-Fi keeps pulling
|
|
15
|
+
* over the metered link until some unrelated event reschedules. Reading the
|
|
16
|
+
* transport per reschedule instead would put a synchronous binder call on the
|
|
17
|
+
* app looper on every skip and track advance.
|
|
18
|
+
*
|
|
19
|
+
* A VPN carries its underlying network's transports alongside `TRANSPORT_VPN`,
|
|
20
|
+
* so a cellular-backed VPN still reads as cellular here.
|
|
21
|
+
*
|
|
22
|
+
* Unknown connectivity reads as not-cellular, so a missing service or a
|
|
23
|
+
* revoked callback never silently stops prefetch.
|
|
24
|
+
*/
|
|
25
|
+
internal class CellularTransportMonitor(private val context: Context) {
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Fired when [isOnCellular] flips, on the ConnectivityManager callback
|
|
29
|
+
* thread — a listener that touches main-confined state has to hop.
|
|
30
|
+
*/
|
|
31
|
+
var onTransportChanged: (() -> Unit)? = null
|
|
32
|
+
|
|
33
|
+
@Volatile
|
|
34
|
+
var isOnCellular: Boolean = false
|
|
35
|
+
private set
|
|
36
|
+
|
|
37
|
+
private var registered = false
|
|
38
|
+
|
|
39
|
+
private val callback = object : ConnectivityManager.NetworkCallback() {
|
|
40
|
+
override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
|
|
41
|
+
update(caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override fun onLost(network: Network) {
|
|
45
|
+
update(false)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fun start() {
|
|
50
|
+
if (registered) return
|
|
51
|
+
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
|
|
52
|
+
?: return
|
|
53
|
+
// The registration can throw (`TooManyRequestsException` once a process
|
|
54
|
+
// holds 100 callbacks); prefetch then runs without cellular awareness
|
|
55
|
+
// rather than `configure()` failing.
|
|
56
|
+
if (runCatching { cm.registerDefaultNetworkCallback(callback) }.isFailure) return
|
|
57
|
+
registered = true
|
|
58
|
+
// Seed from the active network: the first reschedule can land before the
|
|
59
|
+
// first callback does.
|
|
60
|
+
val caps = cm.activeNetwork?.let { cm.getNetworkCapabilities(it) }
|
|
61
|
+
isOnCellular = caps?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
fun stop() {
|
|
65
|
+
if (!registered) return
|
|
66
|
+
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
|
|
67
|
+
registered = false
|
|
68
|
+
isOnCellular = false
|
|
69
|
+
cm?.let { runCatching { it.unregisterNetworkCallback(callback) } }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private fun update(onCellular: Boolean) {
|
|
73
|
+
if (onCellular == isOnCellular) return
|
|
74
|
+
isOnCellular = onCellular
|
|
75
|
+
onTransportChanged?.invoke()
|
|
76
|
+
}
|
|
77
|
+
}
|