react-native-audio-browser 0.1.0 → 0.2.0-next.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/AudioBrowser.podspec +1 -1
- package/README.md +180 -2
- package/android/build.gradle +10 -0
- package/android/gradle.properties +1 -1
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +401 -141
- package/android/src/main/java/com/audiobrowser/Callbacks.kt +4 -6
- package/android/src/main/java/com/audiobrowser/Service.kt +67 -18
- package/android/src/main/java/com/audiobrowser/browser/ArtworkResolutionRegistry.kt +37 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowseArtworkRegistry.kt +34 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +443 -178
- package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +300 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonArtwork.kt +79 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +41 -4
- package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +43 -0
- package/android/src/main/java/com/audiobrowser/browser/TrackLoadHandler.kt +4 -4
- package/android/src/main/java/com/audiobrowser/extension/ResolvedTrackExt.kt +35 -0
- package/android/src/main/java/com/audiobrowser/http/RequestConfigBuilder.kt +109 -97
- package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +6 -10
- package/android/src/main/java/com/audiobrowser/model/PlayerSetupOptions.kt +40 -8
- package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +31 -37
- package/android/src/main/java/com/audiobrowser/player/AutomaticBufferManager.kt +4 -1
- package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +119 -0
- package/android/src/main/java/com/audiobrowser/player/DynamicLoadControl.kt +18 -1
- package/android/src/main/java/com/audiobrowser/player/EqualizerController.kt +153 -0
- package/android/src/main/java/com/audiobrowser/player/InterceptingPlayer.kt +141 -0
- package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +15 -3
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +415 -131
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +154 -276
- package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +348 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackErrorClassifier.kt +129 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateMachine.kt +85 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +27 -5
- package/android/src/main/java/com/audiobrowser/player/PlaybackTimer.kt +56 -0
- package/android/src/main/java/com/audiobrowser/player/Player.kt +452 -576
- package/android/src/main/java/com/audiobrowser/player/PlayerCapabilitiesExt.kt +20 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerEngineFactory.kt +130 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +190 -67
- package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +117 -53
- package/android/src/main/java/com/audiobrowser/player/SleepTimer.kt +37 -3
- package/android/src/main/java/com/audiobrowser/player/SleepTimerManager.kt +80 -0
- package/android/src/main/java/com/audiobrowser/player/StuckRecoveryPolicy.kt +50 -0
- package/android/src/main/java/com/audiobrowser/player/TransformingDataSource.kt +84 -34
- package/android/src/main/java/com/audiobrowser/player/VolumeFader.kt +81 -0
- package/android/src/main/java/com/audiobrowser/tls/AiaCertChaser.kt +141 -0
- package/android/src/main/java/com/audiobrowser/tls/AiaChasingTrustManager.kt +37 -0
- package/android/src/main/java/com/audiobrowser/tls/AiaTls.kt +41 -0
- package/android/src/main/java/com/audiobrowser/tls/CachingCertificateFetcher.kt +209 -0
- package/android/src/main/java/com/audiobrowser/util/ArtworkContentProvider.kt +161 -0
- package/android/src/main/java/com/audiobrowser/util/ArtworkUris.kt +28 -0
- package/android/src/main/java/com/audiobrowser/util/ArtworkVariant.kt +26 -0
- package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +24 -0
- package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoader.kt +49 -0
- package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoaderHolder.kt +36 -0
- package/android/src/main/java/com/audiobrowser/util/CoilBitmapLoader.kt +23 -300
- package/android/src/main/java/com/audiobrowser/util/EqualizerManager.kt +13 -23
- package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +2 -2
- package/android/src/main/java/com/audiobrowser/util/MetadataAdapter.kt +4 -3
- package/android/src/main/java/com/audiobrowser/util/OutputMonitor.kt +211 -0
- package/android/src/main/java/com/audiobrowser/util/OutputSwitcher.kt +58 -0
- package/android/src/main/java/com/audiobrowser/util/PlayingStateFactory.kt +2 -1
- package/android/src/main/java/com/audiobrowser/util/RatingFavorites.kt +14 -0
- package/android/src/main/java/com/audiobrowser/util/SvgArtworkRenderer.kt +6 -111
- package/android/src/main/java/com/audiobrowser/util/SystemVolumeMonitor.kt +22 -8
- package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +111 -80
- package/android/src/main/res/values/strings.xml +4 -0
- package/android/src/test/java/com/audiobrowser/TestFixtures.kt +166 -0
- package/android/src/test/java/com/audiobrowser/browser/ArtworkResolutionRegistryTest.kt +46 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowseArtworkRegistryTest.kt +39 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerBuildApiRequestTest.kt +114 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerLayerResolutionTest.kt +141 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +4 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserUrlResolutionTest.kt +177 -0
- package/android/src/test/java/com/audiobrowser/browser/JsonArtworkTest.kt +54 -0
- package/android/src/test/java/com/audiobrowser/browser/SectionScopeTest.kt +96 -0
- package/android/src/test/java/com/audiobrowser/browser/SimpleRouterTest.kt +1 -2
- package/android/src/test/java/com/audiobrowser/http/RequestConfigBuilderTest.kt +72 -0
- package/android/src/test/java/com/audiobrowser/player/CapabilityControlsTest.kt +159 -0
- package/android/src/test/java/com/audiobrowser/player/DynamicLoadControlTest.kt +56 -0
- package/android/src/test/java/com/audiobrowser/player/EqualizerControllerTest.kt +216 -0
- package/android/src/test/java/com/audiobrowser/player/NowPlayingUpdaterTest.kt +442 -0
- package/android/src/test/java/com/audiobrowser/player/PlaybackErrorClassifierTest.kt +191 -0
- package/android/src/test/java/com/audiobrowser/player/PlaybackStateMachineTest.kt +198 -0
- package/android/src/test/java/com/audiobrowser/player/PlaybackTimerTest.kt +137 -0
- package/android/src/test/java/com/audiobrowser/player/PlayerEngineFactoryTest.kt +36 -0
- package/android/src/test/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicyTest.kt +268 -0
- package/android/src/test/java/com/audiobrowser/player/SessionErrorMaskTest.kt +68 -0
- package/android/src/test/java/com/audiobrowser/player/StuckRecoveryPolicyTest.kt +40 -0
- package/android/src/test/java/com/audiobrowser/player/TransformingDataSourceTest.kt +193 -0
- package/android/src/test/java/com/audiobrowser/tls/AiaCertChaserTest.kt +107 -0
- package/android/src/test/java/com/audiobrowser/tls/AiaChasingTrustManagerTest.kt +73 -0
- package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherTest.kt +75 -0
- package/android/src/test/java/com/audiobrowser/tls/CertFixtures.kt +18 -0
- package/android/src/test/java/com/audiobrowser/util/ArtworkContentProviderTest.kt +163 -0
- package/android/src/test/java/com/audiobrowser/util/ArtworkUrisTest.kt +34 -0
- package/android/src/test/java/com/audiobrowser/util/BrowserPathHelperTest.kt +28 -0
- package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderHolderTest.kt +53 -0
- package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderTest.kt +58 -0
- package/android/src/test/java/com/audiobrowser/util/FakeImageLoader.kt +57 -0
- package/android/src/test/java/com/audiobrowser/util/PlayingStateFactoryTest.kt +40 -0
- package/android/src/test/java/com/audiobrowser/util/RatingFavoritesTest.kt +34 -0
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryBrowseTest.kt +50 -0
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryMediaIdTest.kt +63 -0
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryRatingTest.kt +35 -0
- package/android/src/test/resources/certs/isrg-root-x1.pem +31 -0
- package/android/src/test/resources/certs/letsencrypt-r13.der +0 -0
- package/android/src/test/resources/certs/letsencrypt-r13.pem +29 -0
- package/android/src/test/resources/certs/stationplaylist-leaf.pem +34 -0
- package/ios/Browser/BrowserConfig.swift +41 -11
- package/ios/Browser/BrowserManager+URLResolution.swift +213 -93
- package/ios/Browser/BrowserManager.swift +303 -110
- package/ios/Browser/BrowserPathHelper.swift +32 -3
- package/ios/Browser/JsonModels.swift +287 -66
- package/ios/Browser/MediaResolveComposer.swift +114 -0
- package/ios/Browser/SearchDrillIn.swift +44 -0
- package/ios/Browser/SectionScope.swift +35 -0
- package/ios/Browser/TabBarEntries.swift +15 -0
- package/ios/CarPlay/CPInterfaceController+Safe.swift +126 -0
- package/ios/CarPlay/CarPlayArtworkResolver.swift +6 -6
- package/ios/CarPlay/CarPlayController.swift +739 -149
- package/ios/CarPlay/CarPlayImageLoader.swift +57 -8
- package/ios/CarPlay/CarPlayListItemFactory.swift +44 -35
- package/ios/CarPlay/CarPlayNowPlayingManager.swift +180 -36
- package/ios/CarPlay/ImageRowItem+CarPlay.swift +19 -0
- package/ios/CarPlay/RNABAudioBrowser.h +15 -10
- package/ios/CarPlay/RNABAudioBrowser.m +15 -14
- package/ios/CarPlay/RNABCarPlaySceneDelegate.m +2 -0
- package/ios/CarPlay/RNABMediaAddHandler.swift +75 -0
- package/ios/CarPlay/RNABMediaAffinityHandler.swift +69 -0
- package/ios/CarPlay/RNABMediaIntentHandler.swift +53 -43
- package/ios/Extension/Capability+RemoteCommand.swift +7 -9
- package/ios/Extension/ChapterMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/NavigationError+Conversion.swift +8 -1
- package/ios/Extension/PlayerCapabilities+Favorite.swift +20 -0
- package/ios/Extension/RequestConfig+Copying.swift +31 -0
- package/ios/Extension/ResolvedTrack+Copying.swift +10 -4
- package/ios/Extension/TimedMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/Track+AVPlayer.swift +4 -4
- package/ios/Extension/Track+Copying.swift +9 -3
- package/ios/Extension/TrackMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/Variant+Artwork.swift +49 -0
- package/ios/HybridAudioBrowser.swift +750 -173
- package/ios/Model/NitroTypeStubs.swift +299 -224
- package/ios/Model/PlayerUpdateOptions.swift +23 -23
- package/ios/Model/RemoteCommand.swift +6 -6
- package/ios/Model/TrackPlayerError.swift +82 -18
- package/ios/NowPlayingInfo/NowPlayingInfoController.swift +99 -121
- package/ios/NowPlayingInfo/SilentAudioPrimer.swift +73 -0
- package/ios/Observer/PlayerItemNotificationObserver.swift +45 -5
- package/ios/Observer/PlayerItemPropertyObserver.swift +27 -4
- package/ios/Observer/PlayerTimeObserver.swift +3 -53
- package/ios/Option/SessionCategories.swift +33 -11
- package/ios/Player/AirPlayStallJudgement.swift +25 -0
- package/ios/Player/EndOfTrackJudgement.swift +32 -0
- package/ios/Player/LoadSeekCoordinator.swift +16 -1
- package/ios/Player/MediaIntentCriteria.swift +139 -0
- package/ios/Player/MediaLoader.swift +28 -10
- package/ios/Player/NowPlayingUpdater.swift +119 -26
- package/ios/Player/PersistedPlaybackState.swift +11 -0
- package/ios/Player/PlaybackCoordinator.swift +282 -51
- package/ios/Player/PlaybackCoordinatorCallbacks.swift +6 -1
- package/ios/Player/PlaybackEffectHandler.swift +19 -9
- package/ios/Player/PlaybackErrorHandler.swift +97 -13
- package/ios/Player/PlaybackStateMachine.swift +18 -13
- package/ios/Player/PlaybackStateStore.swift +27 -0
- package/ios/Player/PlaybackTimer.swift +61 -0
- package/ios/Player/PlayingStateManager.swift +3 -2
- package/ios/Player/QueueManager.swift +67 -61
- package/ios/Player/RetryManager.swift +97 -21
- package/ios/Player/SleepTimerHandling.swift +8 -0
- package/ios/Player/SleepTimerManager.swift +38 -5
- package/ios/Player/VolumeFader.swift +77 -0
- package/ios/RemoteCommand/RemoteCommandController.swift +31 -15
- package/ios/Tests/AirPlayStallJudgementTests.swift +52 -0
- package/ios/Tests/BrowserPathHelperTests.swift +28 -0
- package/ios/Tests/CarPlayArtworkResolverTests.swift +39 -39
- package/ios/Tests/ChapterMetadataAVFoundationTests.swift +2 -2
- package/ios/Tests/EndOfTrackJudgementTests.swift +35 -0
- package/ios/Tests/JsonModelsTests.swift +58 -0
- package/ios/Tests/LoadSeekCoordinatorTests.swift +38 -7
- package/ios/Tests/MediaIntentCriteriaTests.swift +170 -0
- package/ios/Tests/MediaLoaderAssetOptionsTests.swift +46 -0
- package/ios/Tests/MediaLoaderTests.swift +23 -8
- package/ios/Tests/MediaResolveTests.swift +126 -0
- package/ios/Tests/OnceValueTests.swift +79 -0
- package/ios/Tests/PlaybackCoordinatorTests.swift +784 -13
- package/ios/Tests/PlaybackErrorHandlerTests.swift +380 -46
- package/ios/Tests/PlaybackStateMachineTests.swift +42 -10
- package/ios/Tests/PlaybackStateStoreTests.swift +48 -0
- package/ios/Tests/PlaybackTimerTests.swift +55 -0
- package/ios/Tests/PlayingStateManagerTests.swift +57 -0
- package/ios/Tests/QueueManagerTests.swift +149 -18
- package/ios/Tests/ResolvedTrackCopyingTests.swift +15 -8
- package/ios/Tests/RetryManagerTests.swift +89 -0
- package/ios/Tests/SearchDrillInTests.swift +63 -0
- package/ios/Tests/SectionScopeTests.swift +82 -0
- package/ios/Tests/SleepTimerManagerTests.swift +104 -0
- package/ios/Tests/Support/TestTypes.swift +61 -20
- package/ios/Tests/TabBarEntriesTests.swift +71 -0
- package/ios/Tests/TrackSelectorTests.swift +15 -15
- package/ios/TrackPlayer.swift +380 -58
- package/ios/TrackPlayerCallbacks.swift +0 -6
- package/ios/TrackSelector.swift +5 -5
- package/ios/Util/ArtworkImageFetcher.swift +4 -2
- package/ios/Util/NetworkMonitor.swift +7 -3
- package/ios/Util/OnceValue.swift +34 -0
- package/lib/commonjs/features/browser-config.js +227 -0
- package/lib/commonjs/features/browser-config.js.map +1 -0
- package/lib/commonjs/features/browser.js +59 -158
- package/lib/commonjs/features/browser.js.map +1 -1
- package/lib/commonjs/features/carConnection.js +42 -0
- package/lib/commonjs/features/carConnection.js.map +1 -0
- package/lib/commonjs/features/errors.js +34 -2
- package/lib/commonjs/features/errors.js.map +1 -1
- package/lib/commonjs/features/gate.js +149 -0
- package/lib/commonjs/features/gate.js.map +1 -0
- package/lib/commonjs/features/index.js +22 -0
- package/lib/commonjs/features/index.js.map +1 -1
- package/lib/commonjs/features/metadata.js.map +1 -1
- package/lib/commonjs/features/nowPlaying.js +35 -0
- package/lib/commonjs/features/nowPlaying.js.map +1 -1
- package/lib/commonjs/features/output.js +37 -23
- package/lib/commonjs/features/output.js.map +1 -1
- package/lib/commonjs/features/playback/controls.js +9 -0
- package/lib/commonjs/features/playback/controls.js.map +1 -1
- package/lib/commonjs/features/playback/index.js +11 -0
- package/lib/commonjs/features/playback/index.js.map +1 -1
- package/lib/commonjs/features/playback/progress.js +28 -12
- package/lib/commonjs/features/playback/progress.js.map +1 -1
- package/lib/commonjs/features/playback/trackPlaybackTime.js +92 -0
- package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -0
- package/lib/commonjs/features/playback/volume.js +1 -1
- package/lib/commonjs/features/player/options.js +49 -13
- package/lib/commonjs/features/player/options.js.map +1 -1
- package/lib/commonjs/features/player/setup.js +249 -3
- package/lib/commonjs/features/player/setup.js.map +1 -1
- package/lib/commonjs/features/queue/queue.js +10 -3
- package/lib/commonjs/features/queue/queue.js.map +1 -1
- package/lib/commonjs/features/remoteControls.js +1 -12
- package/lib/commonjs/features/remoteControls.js.map +1 -1
- package/lib/commonjs/features/sleepTimer.js +9 -4
- package/lib/commonjs/features/sleepTimer.js.map +1 -1
- package/lib/commonjs/native.js +5 -0
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/native.web.js +4 -1
- package/lib/commonjs/native.web.js.map +1 -1
- package/lib/commonjs/utils/LazyNativeEmitter.js +0 -3
- package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/commonjs/utils/NativeUpdatedValue.js +0 -3
- package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/commonjs/utils/artwork.js +31 -0
- package/lib/commonjs/utils/artwork.js.map +1 -0
- package/lib/commonjs/web/NativeAudioBrowser.js +301 -124
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +71 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js +34 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Player.js +90 -26
- package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +21 -0
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/QueueManager.js +273 -0
- package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +158 -0
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js +34 -3
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js +75 -0
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/index.js +13 -5
- package/lib/commonjs/web/TrackPlayer/index.js.map +1 -1
- package/lib/commonjs/web/browser/BrowserManager.js +176 -50
- package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js +3 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/commonjs/web/browser/SearchManager.js +11 -9
- package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
- package/lib/commonjs/web/browser/assertBrowsePageShape.js +22 -0
- package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +1 -0
- package/lib/commonjs/web/browser/classifyTrackNavigation.js +41 -0
- package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +1 -0
- package/lib/commonjs/web/browser/parseSearchResponse.js +20 -0
- package/lib/commonjs/web/browser/parseSearchResponse.js.map +1 -0
- package/lib/commonjs/web/http/HttpClient.js +4 -23
- package/lib/commonjs/web/http/HttpClient.js.map +1 -1
- package/lib/commonjs/web/http/RequestConfigBuilder.js +107 -58
- package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/commonjs/web/playbackErrorKind.js +57 -0
- package/lib/commonjs/web/playbackErrorKind.js.map +1 -0
- package/lib/commonjs/web/player/MediaSessionManager.js +121 -0
- package/lib/commonjs/web/player/MediaSessionManager.js.map +1 -0
- package/lib/commonjs/web/player/NowPlayingManager.js +6 -5
- package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
- package/lib/commonjs/web/player/OptionsManager.js +9 -17
- package/lib/commonjs/web/player/OptionsManager.js.map +1 -1
- package/lib/commonjs/web/player/RemoteCommandController.js +96 -0
- package/lib/commonjs/web/player/RemoteCommandController.js.map +1 -0
- package/lib/module/features/browser-config.js +221 -0
- package/lib/module/features/browser-config.js.map +1 -0
- package/lib/module/features/browser.js +53 -156
- package/lib/module/features/browser.js.map +1 -1
- package/lib/module/features/carConnection.js +37 -0
- package/lib/module/features/carConnection.js.map +1 -0
- package/lib/module/features/errors.js +34 -2
- package/lib/module/features/errors.js.map +1 -1
- package/lib/module/features/gate.js +144 -0
- package/lib/module/features/gate.js.map +1 -0
- package/lib/module/features/index.js +2 -0
- package/lib/module/features/index.js.map +1 -1
- package/lib/module/features/metadata.js.map +1 -1
- package/lib/module/features/nowPlaying.js +33 -0
- package/lib/module/features/nowPlaying.js.map +1 -1
- package/lib/module/features/output.js +32 -19
- package/lib/module/features/output.js.map +1 -1
- package/lib/module/features/playback/controls.js +8 -0
- package/lib/module/features/playback/controls.js.map +1 -1
- package/lib/module/features/playback/index.js +1 -0
- package/lib/module/features/playback/index.js.map +1 -1
- package/lib/module/features/playback/progress.js +28 -12
- package/lib/module/features/playback/progress.js.map +1 -1
- package/lib/module/features/playback/trackPlaybackTime.js +88 -0
- package/lib/module/features/playback/trackPlaybackTime.js.map +1 -0
- package/lib/module/features/playback/volume.js +1 -1
- package/lib/module/features/player/options.js +48 -13
- package/lib/module/features/player/options.js.map +1 -1
- package/lib/module/features/player/setup.js +249 -3
- package/lib/module/features/player/setup.js.map +1 -1
- package/lib/module/features/queue/queue.js +10 -3
- package/lib/module/features/queue/queue.js.map +1 -1
- package/lib/module/features/remoteControls.js +0 -11
- package/lib/module/features/remoteControls.js.map +1 -1
- package/lib/module/features/sleepTimer.js +9 -4
- package/lib/module/features/sleepTimer.js.map +1 -1
- package/lib/module/native.js +5 -0
- package/lib/module/native.js.map +1 -1
- package/lib/module/native.web.js +4 -1
- package/lib/module/native.web.js.map +1 -1
- package/lib/module/utils/LazyNativeEmitter.js +0 -3
- package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/module/utils/NativeUpdatedValue.js +0 -3
- package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/module/utils/artwork.js +26 -0
- package/lib/module/utils/artwork.js.map +1 -0
- package/lib/module/web/NativeAudioBrowser.js +302 -125
- package/lib/module/web/NativeAudioBrowser.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +67 -0
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
- package/lib/module/web/TrackPlayer/PlaybackTimer.js +29 -0
- package/lib/module/web/TrackPlayer/PlaybackTimer.js.map +1 -0
- package/lib/module/web/TrackPlayer/Player.js +90 -26
- package/lib/module/web/TrackPlayer/Player.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js +17 -0
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
- package/lib/module/web/TrackPlayer/QueueManager.js +269 -0
- package/lib/module/web/TrackPlayer/QueueManager.js.map +1 -0
- package/lib/module/web/TrackPlayer/QueuePlayer.js +154 -0
- package/lib/module/web/TrackPlayer/QueuePlayer.js.map +1 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/module/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/module/web/TrackPlayer/SleepTimer.js +34 -3
- package/lib/module/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/module/web/TrackPlayer/VolumeFader.js +70 -0
- package/lib/module/web/TrackPlayer/VolumeFader.js.map +1 -0
- package/lib/module/web/TrackPlayer/index.js +2 -1
- package/lib/module/web/TrackPlayer/index.js.map +1 -1
- package/lib/module/web/browser/BrowserManager.js +176 -50
- package/lib/module/web/browser/BrowserManager.js.map +1 -1
- package/lib/module/web/browser/NavigationErrorManager.js +3 -1
- package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/module/web/browser/SearchManager.js +11 -9
- package/lib/module/web/browser/SearchManager.js.map +1 -1
- package/lib/module/web/browser/assertBrowsePageShape.js +18 -0
- package/lib/module/web/browser/assertBrowsePageShape.js.map +1 -0
- package/lib/module/web/browser/classifyTrackNavigation.js +38 -0
- package/lib/module/web/browser/classifyTrackNavigation.js.map +1 -0
- package/lib/module/web/browser/parseSearchResponse.js +16 -0
- package/lib/module/web/browser/parseSearchResponse.js.map +1 -0
- package/lib/module/web/http/HttpClient.js +4 -23
- package/lib/module/web/http/HttpClient.js.map +1 -1
- package/lib/module/web/http/RequestConfigBuilder.js +107 -58
- package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/module/web/playbackErrorKind.js +52 -0
- package/lib/module/web/playbackErrorKind.js.map +1 -0
- package/lib/module/web/player/MediaSessionManager.js +116 -0
- package/lib/module/web/player/MediaSessionManager.js.map +1 -0
- package/lib/module/web/player/NowPlayingManager.js +7 -5
- package/lib/module/web/player/NowPlayingManager.js.map +1 -1
- package/lib/module/web/player/OptionsManager.js +9 -17
- package/lib/module/web/player/OptionsManager.js.map +1 -1
- package/lib/module/web/player/RemoteCommandController.js +92 -0
- package/lib/module/web/player/RemoteCommandController.js.map +1 -0
- package/lib/typescript/src/features/browser-config.d.ts +12 -0
- package/lib/typescript/src/features/browser-config.d.ts.map +1 -0
- package/lib/typescript/src/features/browser.d.ts +40 -1
- package/lib/typescript/src/features/browser.d.ts.map +1 -1
- package/lib/typescript/src/features/carConnection.d.ts +20 -0
- package/lib/typescript/src/features/carConnection.d.ts.map +1 -0
- package/lib/typescript/src/features/errors.d.ts +58 -3
- package/lib/typescript/src/features/errors.d.ts.map +1 -1
- package/lib/typescript/src/features/gate.d.ts +77 -0
- package/lib/typescript/src/features/gate.d.ts.map +1 -0
- package/lib/typescript/src/features/index.d.ts +2 -0
- package/lib/typescript/src/features/index.d.ts.map +1 -1
- package/lib/typescript/src/features/metadata.d.ts +6 -4
- package/lib/typescript/src/features/metadata.d.ts.map +1 -1
- package/lib/typescript/src/features/nowPlaying.d.ts +27 -0
- package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -1
- package/lib/typescript/src/features/output.d.ts +28 -18
- package/lib/typescript/src/features/output.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/controls.d.ts +5 -0
- package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/index.d.ts +1 -0
- package/lib/typescript/src/features/playback/index.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/progress.d.ts +3 -0
- package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +34 -0
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/volume.d.ts +1 -1
- package/lib/typescript/src/features/player/options.d.ts +92 -93
- package/lib/typescript/src/features/player/options.d.ts.map +1 -1
- package/lib/typescript/src/features/player/setup.d.ts +206 -167
- package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
- package/lib/typescript/src/features/queue/queue.d.ts +9 -2
- package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
- package/lib/typescript/src/features/remoteControls.d.ts +0 -13
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
- package/lib/typescript/src/features/sleepTimer.d.ts +18 -3
- package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native.d.ts +1 -2
- package/lib/typescript/src/native.d.ts.map +1 -1
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts +17 -225
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-native.d.ts +9 -3
- package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-nodes.d.ts +145 -13
- package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
- package/lib/typescript/src/types/browser.d.ts +349 -85
- package/lib/typescript/src/types/browser.d.ts.map +1 -1
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +0 -2
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +0 -2
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
- package/lib/typescript/src/utils/artwork.d.ts +19 -0
- package/lib/typescript/src/utils/artwork.d.ts.map +1 -0
- package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -1
- package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +3 -1
- package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +24 -10
- package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +6 -6
- package/nitrogen/generated/android/c++/JAndroidOptions.hpp +1 -11
- package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +33 -1
- package/nitrogen/generated/android/c++/JArtworkVariants.hpp +61 -0
- package/nitrogen/generated/android/c++/JBrowseResult.hpp +5 -0
- package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +3 -3
- package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +58 -0
- package/nitrogen/generated/android/c++/JFavoritesMatchMode.hpp +58 -0
- package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +100 -0
- package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +3 -2
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.hpp +112 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +121 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +123 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +133 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +121 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.hpp +139 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.hpp +134 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +8 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +131 -0
- package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_GateEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +0 -10
- package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +9 -4
- package/nitrogen/generated/android/c++/JFunc_void_Output.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +10 -10
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +6 -0
- package/nitrogen/generated/android/c++/JGate.hpp +62 -0
- package/nitrogen/generated/android/c++/JGateDecision.hpp +64 -0
- package/nitrogen/generated/android/c++/{JThumbsRating.hpp → JGateEvent.hpp} +16 -15
- package/nitrogen/generated/android/c++/JGateReason.hpp +58 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +236 -212
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +25 -22
- package/nitrogen/generated/android/c++/JIOSOptions.hpp +95 -0
- package/nitrogen/generated/android/c++/JImageRowItem.hpp +33 -3
- package/nitrogen/generated/android/c++/JMediaReference.hpp +58 -0
- package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +33 -1
- package/nitrogen/generated/android/c++/{JPartialAndroidSetupPlayerOptions.hpp → JNativeAndroidSetupOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +61 -28
- package/nitrogen/generated/android/c++/JNativeGateRequest.hpp +74 -0
- package/nitrogen/generated/android/c++/{JPartialIOSSetupPlayerOptions.hpp → JNativeIOSSetupOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +20 -9
- package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +182 -0
- package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +16 -19
- package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +6 -0
- package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +1 -11
- package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +96 -0
- package/nitrogen/generated/android/c++/JNotificationButton.hpp +3 -3
- package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +3 -17
- package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +7 -3
- package/nitrogen/generated/android/c++/JOptions.hpp +14 -9
- package/nitrogen/generated/android/c++/{JIosOutput.hpp → JOutput.hpp} +15 -15
- package/nitrogen/generated/android/c++/JOutputType.hpp +82 -0
- package/nitrogen/generated/android/c++/JPlayback.hpp +2 -0
- package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JPlaybackError.hpp +18 -3
- package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +2 -0
- package/nitrogen/generated/android/c++/JPlaybackErrorKind.hpp +76 -0
- package/nitrogen/generated/android/c++/JPlaybackState.hpp +3 -3
- package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +11 -5
- package/nitrogen/generated/android/c++/JResolvedTrack.hpp +23 -5
- package/nitrogen/generated/android/c++/JRetryConfig.hpp +11 -7
- package/nitrogen/generated/android/c++/JSearchMode.hpp +27 -9
- package/nitrogen/generated/android/c++/JSearchParams.hpp +9 -3
- package/nitrogen/generated/android/c++/JStallReason.hpp +58 -0
- package/nitrogen/generated/android/c++/JTrack.hpp +23 -5
- package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JTrackRequest.hpp +93 -0
- package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +14 -1
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +71 -0
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.cpp +41 -0
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +121 -0
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.hpp +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioContentType.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +2 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +10 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkVariants.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayNowPlayingButton.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{ThumbsRating.kt → FavoriteConfig.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RatingType.kt → FavoritesMatchMode.kt} +5 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNowPlayingParams.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___Track.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_std__string____Track.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.kt → Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_RemoteSetRatingEvent.kt → Func_void_GateEvent.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_IosOutput.kt → Func_void_Output.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{HeartRating.kt → Gate.kt} +9 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PercentageRating.kt → GateDecision.kt} +9 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{StarRating.kt → GateEvent.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateReason.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +103 -109
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +24 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaReference.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +10 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialAndroidSetupPlayerOptions.kt → NativeAndroidSetupOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +18 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RemoteSetRatingEvent.kt → NativeGateRequest.kt} +12 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialIOSSetupPlayerOptions.kt → NativeIOSSetupOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeSetupPlayerOptions.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorType.kt +3 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +2 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButton.kt +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +3 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{IosOutput.kt → Output.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/OutputType.kt +31 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorKind.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackState.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +7 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchMode.kt +12 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StallReason.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackRequest.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +7 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_String_ArtworkVariants.kt +53 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +139 -28
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +1098 -447
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +60 -39
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +170 -112
- package/nitrogen/generated/ios/swift/AndroidAudioContentType.swift +8 -8
- package/nitrogen/generated/ios/swift/AndroidOptions.swift +2 -12
- package/nitrogen/generated/ios/swift/ArtworkRequestConfig.swift +95 -1
- package/nitrogen/generated/ios/swift/ArtworkVariants.swift +34 -0
- package/nitrogen/generated/ios/swift/CarPlayNowPlayingButton.swift +4 -4
- package/nitrogen/generated/ios/swift/FavoriteConfig.swift +29 -0
- package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +40 -0
- package/nitrogen/generated/ios/swift/FormatNowPlayingParams.swift +67 -0
- package/nitrogen/generated/ios/swift/FormattedNavigationError.swift +17 -4
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.swift +69 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___Track.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.swift +60 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_std__string____Track.swift +60 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.swift +77 -0
- package/nitrogen/generated/ios/swift/Func_void_GateDecision.swift +46 -0
- package/nitrogen/generated/ios/swift/{Func_void_RemoteSetRatingEvent.swift → Func_void_GateEvent.swift} +10 -10
- package/nitrogen/generated/ios/swift/{Func_void_IosOutput.swift → Func_void_Output.swift} +10 -10
- package/nitrogen/generated/ios/swift/Func_void_TransformableRequestConfig.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +5 -5
- package/nitrogen/generated/ios/swift/Func_void_std__optional_NowPlayingUpdate_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +53 -0
- package/nitrogen/generated/ios/swift/{Func_void_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError___.swift → Func_void_std__shared_ptr_Promise_GateDecision__.swift} +17 -17
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_TransformableRequestConfig__.swift +66 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError____.swift +81 -0
- package/nitrogen/generated/ios/swift/Gate.swift +47 -0
- package/nitrogen/generated/ios/swift/GateDecision.swift +40 -0
- package/nitrogen/generated/ios/swift/GateEvent.swift +29 -0
- package/nitrogen/generated/ios/swift/GateReason.swift +40 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +20 -14
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +230 -197
- package/nitrogen/generated/ios/swift/IOSOptions.swift +51 -0
- package/nitrogen/generated/ios/swift/ImageRowItem.swift +121 -2
- package/nitrogen/generated/ios/swift/MediaReference.swift +40 -0
- package/nitrogen/generated/ios/swift/MediaRequestConfig.swift +107 -1
- package/nitrogen/generated/ios/swift/{PartialAndroidSetupPlayerOptions.swift → NativeAndroidSetupOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +161 -22
- package/nitrogen/generated/ios/swift/NativeGateRequest.swift +58 -0
- package/nitrogen/generated/ios/swift/{PartialIOSSetupPlayerOptions.swift → NativeIOSSetupOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/NativeRouteEntry.swift +19 -19
- package/nitrogen/generated/ios/swift/NativeSetupPlayerOptions.swift +206 -0
- package/nitrogen/generated/ios/swift/NativeUpdateOptions.swift +12 -25
- package/nitrogen/generated/ios/swift/NavigationErrorType.swift +8 -0
- package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +1 -30
- package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +90 -0
- package/nitrogen/generated/ios/swift/NotificationButton.swift +4 -4
- package/nitrogen/generated/ios/swift/NowPlayingMetadata.swift +1 -48
- package/nitrogen/generated/ios/swift/NowPlayingUpdate.swift +19 -1
- package/nitrogen/generated/ios/swift/Options.swift +10 -4
- package/nitrogen/generated/ios/swift/{IosOutput.swift → Output.swift} +7 -7
- package/nitrogen/generated/ios/swift/OutputType.swift +72 -0
- package/nitrogen/generated/ios/swift/PlaybackError.swift +43 -2
- package/nitrogen/generated/ios/swift/PlaybackErrorKind.swift +64 -0
- package/nitrogen/generated/ios/swift/PlaybackState.swift +4 -4
- package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +27 -8
- package/nitrogen/generated/ios/swift/ResolvedTrack.swift +74 -8
- package/nitrogen/generated/ios/swift/RetryConfig.swift +35 -4
- package/nitrogen/generated/ios/swift/SearchMode.swift +36 -12
- package/nitrogen/generated/ios/swift/SearchParams.swift +7 -2
- package/nitrogen/generated/ios/swift/StallReason.swift +40 -0
- package/nitrogen/generated/ios/swift/Track.swift +74 -8
- package/nitrogen/generated/ios/swift/TrackRequest.swift +106 -0
- package/nitrogen/generated/ios/swift/TransformableRequestConfig.swift +60 -1
- package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.swift +19 -0
- package/nitrogen/generated/ios/swift/Variant_String_ArtworkVariants.swift +18 -0
- package/nitrogen/generated/shared/c++/AndroidAudioContentType.hpp +10 -10
- package/nitrogen/generated/shared/c++/AndroidOptions.hpp +1 -12
- package/nitrogen/generated/shared/c++/ArtworkRequestConfig.hpp +10 -2
- package/nitrogen/generated/shared/c++/ArtworkVariants.hpp +87 -0
- package/nitrogen/generated/shared/c++/CarPlayNowPlayingButton.hpp +6 -6
- package/nitrogen/generated/shared/c++/EqualizerSettings.hpp +0 -2
- package/nitrogen/generated/shared/c++/{StarRating.hpp → FavoriteConfig.hpp} +18 -17
- package/nitrogen/generated/shared/c++/FavoritesMatchMode.hpp +76 -0
- package/nitrogen/generated/shared/c++/FormatNowPlayingParams.hpp +110 -0
- package/nitrogen/generated/shared/c++/FormattedNavigationError.hpp +6 -5
- package/nitrogen/generated/shared/c++/{HeartRating.hpp → Gate.hpp} +21 -16
- package/nitrogen/generated/shared/c++/{ThumbsRating.hpp → GateDecision.hpp} +23 -17
- package/nitrogen/generated/shared/c++/{PercentageRating.hpp → GateEvent.hpp} +18 -17
- package/nitrogen/generated/shared/c++/GateReason.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +21 -18
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +44 -35
- package/nitrogen/generated/shared/c++/IOSOptions.hpp +91 -0
- package/nitrogen/generated/shared/c++/ImageRowItem.hpp +33 -2
- package/nitrogen/generated/shared/c++/MediaReference.hpp +76 -0
- package/nitrogen/generated/shared/c++/MediaRequestConfig.hpp +10 -2
- package/nitrogen/generated/shared/c++/{PartialAndroidSetupPlayerOptions.hpp → NativeAndroidSetupOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +31 -15
- package/nitrogen/generated/shared/c++/NativeGateRequest.hpp +97 -0
- package/nitrogen/generated/shared/c++/{PartialIOSSetupPlayerOptions.hpp → NativeIOSSetupOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/NativeRouteEntry.hpp +5 -5
- package/nitrogen/generated/shared/c++/NativeSetupPlayerOptions.hpp +138 -0
- package/nitrogen/generated/shared/c++/NativeUpdateOptions.hpp +9 -7
- package/nitrogen/generated/shared/c++/NavigationErrorType.hpp +8 -0
- package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +1 -12
- package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +92 -0
- package/nitrogen/generated/shared/c++/NotificationButton.hpp +8 -8
- package/nitrogen/generated/shared/c++/NowPlayingMetadata.hpp +3 -19
- package/nitrogen/generated/shared/c++/NowPlayingUpdate.hpp +6 -2
- package/nitrogen/generated/shared/c++/Options.hpp +8 -8
- package/nitrogen/generated/shared/c++/{IosOutput.hpp → Output.hpp} +18 -18
- package/nitrogen/generated/shared/c++/OutputType.hpp +108 -0
- package/nitrogen/generated/shared/c++/PlaybackError.hpp +18 -3
- package/nitrogen/generated/shared/c++/PlaybackErrorKind.hpp +100 -0
- package/nitrogen/generated/shared/c++/PlaybackState.hpp +9 -9
- package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +9 -6
- package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +24 -5
- package/nitrogen/generated/shared/c++/RetryConfig.hpp +10 -6
- package/nitrogen/generated/shared/c++/SearchMode.hpp +39 -15
- package/nitrogen/generated/shared/c++/SearchParams.hpp +9 -2
- package/nitrogen/generated/shared/c++/StallReason.hpp +76 -0
- package/nitrogen/generated/shared/c++/Track.hpp +24 -5
- package/nitrogen/generated/shared/c++/TrackRequest.hpp +93 -0
- package/nitrogen/generated/shared/c++/TransformableRequestConfig.hpp +6 -2
- package/package.json +16 -16
- package/src/codegen-no-config-variant.test.ts +70 -0
- package/src/features/browser-config.test.ts +110 -0
- package/src/features/browser-config.ts +293 -0
- package/src/features/browser.test.ts +19 -0
- package/src/features/browser.ts +58 -201
- package/src/features/carConnection.ts +36 -0
- package/src/features/errors.ts +68 -2
- package/src/features/gate.test.ts +72 -0
- package/src/features/gate.ts +155 -0
- package/src/features/index.ts +2 -0
- package/src/features/metadata.ts +6 -12
- package/src/features/nowPlaying.ts +36 -0
- package/src/features/output.ts +35 -22
- package/src/features/playback/controls.ts +8 -0
- package/src/features/playback/index.ts +1 -0
- package/src/features/playback/progress.ts +31 -12
- package/src/features/playback/trackPlaybackTime.test.ts +66 -0
- package/src/features/playback/trackPlaybackTime.ts +106 -0
- package/src/features/playback/volume.ts +1 -1
- package/src/features/player/options.test.ts +38 -0
- package/src/features/player/options.ts +140 -75
- package/src/features/player/setup.test.ts +117 -0
- package/src/features/player/setup.ts +390 -175
- package/src/features/queue/queue.test.ts +36 -0
- package/src/features/queue/queue.ts +15 -4
- package/src/features/remoteControls.ts +0 -23
- package/src/features/sleepTimer.ts +23 -4
- package/src/native.ts +5 -0
- package/src/native.web.ts +4 -1
- package/src/specs/audio-browser.nitro.ts +131 -41
- package/src/types/browser-native.ts +19 -6
- package/src/types/browser-nodes.ts +160 -13
- package/src/types/browser.ts +377 -89
- package/src/utils/LazyNativeEmitter.ts +0 -2
- package/src/utils/NativeUpdatedValue.ts +0 -2
- package/src/utils/artwork.ts +30 -0
- package/src/web/NativeAudioBrowser.playWhenReady.test.ts +301 -0
- package/src/web/NativeAudioBrowser.ts +368 -157
- package/src/web/SimpleRouter.test.ts +9 -9
- package/src/web/TrackPlayer/PlaybackStateMachine.test.ts +139 -0
- package/src/web/TrackPlayer/PlaybackStateMachine.ts +82 -0
- package/src/web/TrackPlayer/PlaybackTimer.test.ts +67 -0
- package/src/web/TrackPlayer/PlaybackTimer.ts +33 -0
- package/src/web/TrackPlayer/Player.dispatch.test.ts +229 -0
- package/src/web/TrackPlayer/Player.load.test.ts +86 -0
- package/src/web/TrackPlayer/Player.ts +113 -39
- package/src/web/TrackPlayer/PlayingStateFactory.test.ts +51 -0
- package/src/web/TrackPlayer/PlayingStateFactory.ts +24 -0
- package/src/web/TrackPlayer/QueueManager.test.ts +289 -0
- package/src/web/TrackPlayer/QueueManager.ts +302 -0
- package/src/web/TrackPlayer/QueuePlayer.ts +188 -0
- package/src/web/TrackPlayer/RepeatMode.ts +1 -1
- package/src/web/TrackPlayer/SleepTimer.ts +38 -3
- package/src/web/TrackPlayer/VolumeFader.ts +74 -0
- package/src/web/TrackPlayer/index.ts +2 -1
- package/src/web/browser/BrowserManager.ts +231 -62
- package/src/web/browser/NavigationErrorManager.ts +3 -1
- package/src/web/browser/SearchManager.ts +11 -15
- package/src/web/browser/__tests__/layer-resolver.test.ts +69 -0
- package/src/web/browser/assertBrowsePageShape.test.ts +27 -0
- package/src/web/browser/assertBrowsePageShape.ts +27 -0
- package/src/web/browser/classifyTrackNavigation.test.ts +41 -0
- package/src/web/browser/classifyTrackNavigation.ts +35 -0
- package/src/web/browser/parseSearchResponse.test.ts +25 -0
- package/src/web/browser/parseSearchResponse.ts +15 -0
- package/src/web/http/HttpClient.ts +5 -35
- package/src/web/http/RequestConfigBuilder.test.ts +59 -0
- package/src/web/http/RequestConfigBuilder.ts +120 -63
- package/src/web/playbackErrorKind.test.ts +55 -0
- package/src/web/playbackErrorKind.ts +56 -0
- package/src/web/player/MediaSessionManager.test.ts +220 -0
- package/src/web/player/MediaSessionManager.ts +151 -0
- package/src/web/player/NowPlayingManager.test.ts +46 -0
- package/src/web/player/NowPlayingManager.ts +6 -5
- package/src/web/player/OptionsManager.ts +12 -18
- package/src/web/player/RemoteCommandController.test.ts +171 -0
- package/src/web/player/RemoteCommandController.ts +166 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackProgressUpdateManager.kt +0 -59
- package/android/src/main/java/com/audiobrowser/util/RatingFactory.kt +0 -72
- package/android/src/main/java/com/audiobrowser/util/ResolvedTrackFactory.kt +0 -36
- package/android/src/test/java/com/audiobrowser/player/PlaybackProgressUpdateManagerTest.kt +0 -146
- package/ios/CarPlay/Track+CarPlay.swift +0 -63
- package/ios/NowPlayingInfo/NowPlayingInfoCenter.swift +0 -9
- package/ios/Player/PlaybackProgressUpdateManager.swift +0 -68
- package/ios/Tests/PlaybackProgressUpdateManagerTests.swift +0 -166
- package/lib/commonjs/features/rating.js +0 -2
- package/lib/commonjs/features/rating.js.map +0 -1
- package/lib/commonjs/types/player.js +0 -2
- package/lib/commonjs/types/player.js.map +0 -1
- package/lib/commonjs/web/SimpleRouter.test.js +0 -174
- package/lib/commonjs/web/SimpleRouter.test.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js +0 -293
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js.map +0 -1
- package/lib/module/features/rating.js +0 -2
- package/lib/module/features/rating.js.map +0 -1
- package/lib/module/types/player.js +0 -2
- package/lib/module/types/player.js.map +0 -1
- package/lib/module/web/SimpleRouter.test.js +0 -174
- package/lib/module/web/SimpleRouter.test.js.map +0 -1
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js +0 -288
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js.map +0 -1
- package/lib/typescript/src/features/rating.d.ts +0 -14
- package/lib/typescript/src/features/rating.d.ts.map +0 -1
- package/lib/typescript/src/native.web.d.ts +0 -3
- package/lib/typescript/src/native.web.d.ts.map +0 -1
- package/lib/typescript/src/types/player.d.ts +0 -64
- package/lib/typescript/src/types/player.d.ts.map +0 -1
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts +0 -188
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts.map +0 -1
- package/lib/typescript/src/web/SimpleRouter.d.ts +0 -40
- package/lib/typescript/src/web/SimpleRouter.d.ts.map +0 -1
- package/lib/typescript/src/web/SimpleRouter.test.d.ts +0 -2
- package/lib/typescript/src/web/SimpleRouter.test.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts +0 -11
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts +0 -59
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts +0 -39
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts +0 -6
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts +0 -4
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts +0 -34
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/State.d.ts +0 -13
- package/lib/typescript/src/web/TrackPlayer/State.d.ts.map +0 -1
- package/lib/typescript/src/web/TrackPlayer/index.d.ts +0 -5
- package/lib/typescript/src/web/TrackPlayer/index.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/BrowserManager.d.ts +0 -154
- package/lib/typescript/src/web/browser/BrowserManager.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts +0 -42
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts +0 -40
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts.map +0 -1
- package/lib/typescript/src/web/browser/SearchManager.d.ts +0 -22
- package/lib/typescript/src/web/browser/SearchManager.d.ts.map +0 -1
- package/lib/typescript/src/web/http/HttpClient.d.ts +0 -25
- package/lib/typescript/src/web/http/HttpClient.d.ts.map +0 -1
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts +0 -98
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts.map +0 -1
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts +0 -34
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts.map +0 -1
- package/lib/typescript/src/web/player/OptionsManager.d.ts +0 -32
- package/lib/typescript/src/web/player/OptionsManager.d.ts.map +0 -1
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts +0 -69
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts.map +0 -1
- package/lib/typescript/src/web/util/shuffle.d.ts +0 -8
- package/lib/typescript/src/web/util/shuffle.d.ts.map +0 -1
- package/nitrogen/generated/android/c++/JAndroidUpdateOptions.hpp +0 -86
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.hpp +0 -147
- package/nitrogen/generated/android/c++/JFunc_void_IosOutput.hpp +0 -80
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSetRatingEvent.hpp +0 -87
- package/nitrogen/generated/android/c++/JHeartRating.hpp +0 -57
- package/nitrogen/generated/android/c++/JIosOutputType.hpp +0 -85
- package/nitrogen/generated/android/c++/JPartialSetupPlayerOptions.hpp +0 -96
- package/nitrogen/generated/android/c++/JPercentageRating.hpp +0 -57
- package/nitrogen/generated/android/c++/JRatingType.hpp +0 -73
- package/nitrogen/generated/android/c++/JRemoteSetRatingEvent.hpp +0 -66
- package/nitrogen/generated/android/c++/JStarRating.hpp +0 -57
- package/nitrogen/generated/android/c++/JUpdateOptions.hpp +0 -105
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.cpp +0 -34
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.hpp +0 -105
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidUpdateOptions.kt +0 -50
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutputType.kt +0 -32
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialSetupPlayerOptions.kt +0 -47
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/UpdateOptions.kt +0 -53
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.kt +0 -77
- package/nitrogen/generated/ios/swift/AndroidUpdateOptions.swift +0 -119
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.swift +0 -68
- package/nitrogen/generated/ios/swift/HeartRating.swift +0 -29
- package/nitrogen/generated/ios/swift/IosOutputType.swift +0 -76
- package/nitrogen/generated/ios/swift/PartialSetupPlayerOptions.swift +0 -101
- package/nitrogen/generated/ios/swift/PercentageRating.swift +0 -29
- package/nitrogen/generated/ios/swift/RatingType.swift +0 -60
- package/nitrogen/generated/ios/swift/RemoteSetRatingEvent.swift +0 -58
- package/nitrogen/generated/ios/swift/StarRating.swift +0 -29
- package/nitrogen/generated/ios/swift/ThumbsRating.swift +0 -29
- package/nitrogen/generated/ios/swift/UpdateOptions.swift +0 -143
- package/nitrogen/generated/ios/swift/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.swift +0 -20
- package/nitrogen/generated/shared/c++/AndroidUpdateOptions.hpp +0 -109
- package/nitrogen/generated/shared/c++/IosOutputType.hpp +0 -112
- package/nitrogen/generated/shared/c++/PartialSetupPlayerOptions.hpp +0 -104
- package/nitrogen/generated/shared/c++/RatingType.hpp +0 -96
- package/nitrogen/generated/shared/c++/RemoteSetRatingEvent.hpp +0 -94
- package/nitrogen/generated/shared/c++/UpdateOptions.hpp +0 -111
- package/src/features/rating.ts +0 -17
- package/src/types/player.ts +0 -69
- package/src/web/TrackPlayer/PlaylistPlayer.ts +0 -346
|
@@ -2,7 +2,7 @@ import Foundation
|
|
|
2
2
|
import os.log
|
|
3
3
|
|
|
4
4
|
#if canImport(NitroModules)
|
|
5
|
-
import NitroModules
|
|
5
|
+
import NitroModules
|
|
6
6
|
#endif
|
|
7
7
|
|
|
8
8
|
/// Owns the playback state machine, side effect dispatch, observer context guards,
|
|
@@ -22,26 +22,61 @@ class PlaybackCoordinator {
|
|
|
22
22
|
let sleepTimerManager: any SleepTimerHandling
|
|
23
23
|
let loadSeekCoordinator = LoadSeekCoordinator()
|
|
24
24
|
|
|
25
|
+
lazy var volumeFader = VolumeFader(
|
|
26
|
+
getVolume: { [weak self] in self?.effectHandler?.volume ?? 1 },
|
|
27
|
+
setVolume: { [weak self] level in self?.effectHandler?.volume = level },
|
|
28
|
+
)
|
|
29
|
+
|
|
25
30
|
lazy var playingStateManager: PlayingStateManager = PlayingStateManager { [weak self] state in
|
|
26
31
|
self?.callbacks?.playerDidChangePlayingState(state)
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
private lazy var
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
private lazy var progressTimer = PlaybackTimer(
|
|
35
|
+
isActive: { $0 == .loading || $0 == .buffering || $0 == .playing },
|
|
36
|
+
) { [weak self] in
|
|
37
|
+
guard let self, currentIndex >= 0, let effectHandler else { return }
|
|
38
|
+
let progressEvent = PlaybackProgressUpdatedEvent(
|
|
39
|
+
track: Double(currentIndex),
|
|
40
|
+
position: effectHandler.currentTime,
|
|
41
|
+
duration: effectHandler.duration,
|
|
42
|
+
buffered: effectHandler.bufferedPosition,
|
|
43
|
+
)
|
|
44
|
+
callbacks?.playerDidUpdateProgress(progressEvent)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private lazy var intervalTimer = PlaybackTimer(
|
|
48
|
+
isActive: { $0 == .playing },
|
|
49
|
+
) { [weak self] in
|
|
50
|
+
self?.callbacks?.playerDidFirePlaybackInterval()
|
|
51
|
+
}
|
|
40
52
|
|
|
41
53
|
// MARK: - State
|
|
42
54
|
|
|
43
55
|
private(set) var state: PlaybackState = .none
|
|
44
56
|
var playbackError: TrackPlayerError.PlaybackError?
|
|
57
|
+
/// True while `playbackError` is advisory — the retry loop is still working
|
|
58
|
+
/// on it and the state stays non-terminal. Terminal errors (state == .error)
|
|
59
|
+
/// always carry false.
|
|
60
|
+
private(set) var isRetryingError = false
|
|
61
|
+
|
|
62
|
+
/// The JS-facing form of `playbackError`, carrying the retrying flag.
|
|
63
|
+
func nitroPlaybackError() -> PlaybackError? {
|
|
64
|
+
playbackError?.toNitroError(retrying: isRetryingError)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/// Whether playback should resume when the current audio-session interruption
|
|
68
|
+
/// ends — set to the play intent captured at interruption start, so we only
|
|
69
|
+
/// auto-resume if we were actually playing when interrupted.
|
|
70
|
+
private var shouldResumeAfterInterruption = false
|
|
71
|
+
|
|
72
|
+
/// Seconds of continuous audible playback after which the retry budget is
|
|
73
|
+
/// refilled — proof the stream actually delivered audio, not a brief blip
|
|
74
|
+
/// (mirrors Android's HEALTHY_PLAYBACK_MS). Without the refill a long-lived
|
|
75
|
+
/// stream permanently loses retry after its first recovered error, because
|
|
76
|
+
/// the window/attempt counters otherwise reset only on track change.
|
|
77
|
+
/// Overridable in tests.
|
|
78
|
+
var healthyPlaybackDuration: TimeInterval = 20
|
|
79
|
+
private var healthyPlaybackTask: Task<Void, Never>?
|
|
45
80
|
|
|
46
81
|
/// Playback rate (1.0 = normal speed).
|
|
47
82
|
var rate: Float = 1.0
|
|
@@ -63,6 +98,8 @@ class PlaybackCoordinator {
|
|
|
63
98
|
var nextTracks: [Track] { queue.nextTracks }
|
|
64
99
|
var previousTracks: [Track] { queue.previousTracks }
|
|
65
100
|
var isLastInPlaybackOrder: Bool { queue.isLastInPlaybackOrder }
|
|
101
|
+
var canNext: Bool { queue.canNext }
|
|
102
|
+
var canPrevious: Bool { queue.canPrevious }
|
|
66
103
|
|
|
67
104
|
/// The repeat mode for the queue player.
|
|
68
105
|
var repeatMode: RepeatMode {
|
|
@@ -71,8 +108,9 @@ class PlaybackCoordinator {
|
|
|
71
108
|
guard queue.repeatMode != newValue else { return }
|
|
72
109
|
queue.repeatMode = newValue
|
|
73
110
|
effectHandler?.updateRemoteRepeatMode(newValue)
|
|
111
|
+
pushSkipAvailability() // repeat-all wrap changes next/previous availability
|
|
74
112
|
callbacks?.playerDidChangeRepeatMode(
|
|
75
|
-
RepeatModeChangedEvent(repeatMode: newValue)
|
|
113
|
+
RepeatModeChangedEvent(repeatMode: newValue),
|
|
76
114
|
)
|
|
77
115
|
}
|
|
78
116
|
}
|
|
@@ -84,15 +122,30 @@ class PlaybackCoordinator {
|
|
|
84
122
|
guard queue.shuffleEnabled != newValue else { return }
|
|
85
123
|
queue.shuffleEnabled = newValue
|
|
86
124
|
effectHandler?.updateRemoteShuffleMode(newValue)
|
|
125
|
+
pushSkipAvailability() // shuffle reorders playback → boundary changes
|
|
87
126
|
callbacks?.playerDidChangeShuffleEnabled(newValue)
|
|
88
127
|
}
|
|
89
128
|
}
|
|
90
129
|
|
|
130
|
+
/// Pushes current next/previous availability to the remote command center so
|
|
131
|
+
/// CarPlay / lock-screen grey out the buttons when there's nowhere to skip.
|
|
132
|
+
private func pushSkipAvailability() {
|
|
133
|
+
effectHandler?.updateSkipAvailability(canNext: queue.canNext, canPrevious: queue.canPrevious)
|
|
134
|
+
}
|
|
135
|
+
|
|
91
136
|
// MARK: - playWhenReady
|
|
92
137
|
|
|
93
138
|
var playWhenReady: Bool = false {
|
|
94
139
|
didSet {
|
|
95
|
-
|
|
140
|
+
// A play during an interruption takes ownership of the intent — the
|
|
141
|
+
// user's subsequent pause must not be overridden by auto-resume.
|
|
142
|
+
// (handleInterruptionEnded consumes its flag before its own play().)
|
|
143
|
+
if playWhenReady { shouldResumeAfterInterruption = false }
|
|
144
|
+
|
|
145
|
+
// Terminal states need a reload, not a bare play(): the item is gone
|
|
146
|
+
// (.stopped/.error) or parked at its end (.ended), where startPlayback()
|
|
147
|
+
// is a silent no-op. Only .error resumes from the last position.
|
|
148
|
+
if playWhenReady == true, state == .error || state == .stopped || state == .ended {
|
|
96
149
|
effectHandler?.reloadTrack(startFromCurrentTime: state == .error)
|
|
97
150
|
}
|
|
98
151
|
if state != .loading {
|
|
@@ -104,8 +157,22 @@ class PlaybackCoordinator {
|
|
|
104
157
|
}
|
|
105
158
|
|
|
106
159
|
if oldValue != playWhenReady {
|
|
160
|
+
// An explicit pause during the sleep fade is the timer's goal arriving
|
|
161
|
+
// early: clear the timer (restores the pre-fade volume via onFadeCancel).
|
|
162
|
+
if !playWhenReady, volumeFader.isActive {
|
|
163
|
+
sleepTimerManager.clear()
|
|
164
|
+
}
|
|
107
165
|
callbacks?.playerDidChangePlayWhenReady(playWhenReady)
|
|
108
166
|
playingStateManager.update(playWhenReady: playWhenReady, state: state)
|
|
167
|
+
// Reflect play/pause intent immediately — even while the new item is
|
|
168
|
+
// still loading. Auto-publishing doesn't set the explicit now-playing
|
|
169
|
+
// playback state, and the player's timeControlStatus can't report
|
|
170
|
+
// "playing" yet during loading. Guarded to active states so a play()
|
|
171
|
+
// from a terminal state doesn't leave a phantom "playing" button.
|
|
172
|
+
if playbackActive {
|
|
173
|
+
effectHandler?.updateNowPlayingState(playWhenReady: playWhenReady)
|
|
174
|
+
}
|
|
175
|
+
evaluateSessionRelease()
|
|
109
176
|
}
|
|
110
177
|
}
|
|
111
178
|
}
|
|
@@ -128,13 +195,42 @@ class PlaybackCoordinator {
|
|
|
128
195
|
|
|
129
196
|
// Configure sleep timer
|
|
130
197
|
sleepTimerManager.onComplete = { [weak self] in
|
|
131
|
-
self
|
|
198
|
+
guard let self else { return }
|
|
199
|
+
self.volumeFader.resolve { self.pause() }
|
|
200
|
+
}
|
|
201
|
+
sleepTimerManager.onFadeStart = { [weak self] duration in
|
|
202
|
+
self?.volumeFader.start(duration: duration)
|
|
203
|
+
}
|
|
204
|
+
sleepTimerManager.onFadeCancel = { [weak self] in
|
|
205
|
+
self?.volumeFader.cancel(restoringVolume: true)
|
|
132
206
|
}
|
|
133
207
|
|
|
134
208
|
// Wire error handler to state machine
|
|
135
209
|
errorHandler.onError = { [weak self] error in
|
|
136
210
|
self?.transition(.errorOccurred(error))
|
|
137
211
|
}
|
|
212
|
+
errorHandler.onRetryingError = { [weak self] error in
|
|
213
|
+
self?.reportRetryingError(error)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/// Surfaces a failure the retry loop is still working on: attached to the
|
|
218
|
+
/// current (non-terminal) state so UIs can show the cause over the spinner.
|
|
219
|
+
/// Not a state transition — the state machine never sees it — and not a
|
|
220
|
+
/// `playerDidError`, which stays reserved for terminal errors.
|
|
221
|
+
private func reportRetryingError(_ error: TrackPlayerError.PlaybackError) {
|
|
222
|
+
// Only attach while the failure is what the listener is looking at (matches
|
|
223
|
+
// Android). During .playing buffered audio is still audibly fine — the
|
|
224
|
+
// advisory would replace the song line over working sound — and a
|
|
225
|
+
// terminal/stopped state must not regain an advisory error.
|
|
226
|
+
guard state == .loading || state == .buffering || state == .paused else { return }
|
|
227
|
+
// Each failed attempt re-reports; identical repeats add nothing.
|
|
228
|
+
if isRetryingError, playbackError == error { return }
|
|
229
|
+
playbackError = error
|
|
230
|
+
isRetryingError = true
|
|
231
|
+
callbacks?.playerDidChangePlayback(
|
|
232
|
+
Playback(state: state, error: nitroPlaybackError()),
|
|
233
|
+
)
|
|
138
234
|
}
|
|
139
235
|
|
|
140
236
|
// MARK: - Playback State Machine
|
|
@@ -144,13 +240,14 @@ class PlaybackCoordinator {
|
|
|
144
240
|
|
|
145
241
|
// Allow error-to-error transitions to update the error and emit callbacks,
|
|
146
242
|
// even though the state enum value doesn't change.
|
|
147
|
-
if newState == state, case .errorOccurred(
|
|
243
|
+
if newState == state, case let .errorOccurred(error) = event {
|
|
148
244
|
playbackError = error
|
|
245
|
+
isRetryingError = false
|
|
149
246
|
callbacks?.playerDidChangePlayback(
|
|
150
|
-
Playback(state: state, error:
|
|
247
|
+
Playback(state: state, error: nitroPlaybackError()),
|
|
151
248
|
)
|
|
152
249
|
callbacks?.playerDidError(
|
|
153
|
-
PlaybackErrorEvent(error:
|
|
250
|
+
PlaybackErrorEvent(error: nitroPlaybackError()),
|
|
154
251
|
)
|
|
155
252
|
return
|
|
156
253
|
}
|
|
@@ -167,8 +264,36 @@ class PlaybackCoordinator {
|
|
|
167
264
|
if old == .error, new != .error {
|
|
168
265
|
playbackError = nil
|
|
169
266
|
}
|
|
170
|
-
|
|
267
|
+
// A retrying error rides along through loading/buffering, but any state
|
|
268
|
+
// that proves recovery (.ready/.playing — data flowed) or abandons the
|
|
269
|
+
// attempt (.stopped/.none/.ended) clears it. Runs before emitStateChange,
|
|
270
|
+
// so the emitted Playback is already clean.
|
|
271
|
+
if isRetryingError, new != .loading, new != .buffering, new != .paused {
|
|
272
|
+
playbackError = nil
|
|
273
|
+
isRetryingError = false
|
|
274
|
+
}
|
|
275
|
+
if case let .errorOccurred(error) = event {
|
|
171
276
|
playbackError = error
|
|
277
|
+
isRetryingError = false
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Retry-budget refill: sustained audible playback proves the stream
|
|
281
|
+
// recovered, so the next error starts a fresh retry window. Leaving
|
|
282
|
+
// .playing before the threshold cancels the pending refill.
|
|
283
|
+
if new == .playing {
|
|
284
|
+
healthyPlaybackTask?.cancel()
|
|
285
|
+
healthyPlaybackTask = Task { [weak self] in
|
|
286
|
+
guard let self else { return }
|
|
287
|
+
try? await Task.sleep(nanoseconds: UInt64(healthyPlaybackDuration * 1_000_000_000))
|
|
288
|
+
guard !Task.isCancelled else { return }
|
|
289
|
+
// Refill only between episodes: resetRetry() cancels a pending retry,
|
|
290
|
+
// which would silently kill an in-flight reconnect.
|
|
291
|
+
guard errorHandler.pendingRetryTask == nil else { return }
|
|
292
|
+
errorHandler.resetRetry()
|
|
293
|
+
}
|
|
294
|
+
} else if old == .playing {
|
|
295
|
+
healthyPlaybackTask?.cancel()
|
|
296
|
+
healthyPlaybackTask = nil
|
|
172
297
|
}
|
|
173
298
|
|
|
174
299
|
// State-specific effects
|
|
@@ -178,40 +303,46 @@ class PlaybackCoordinator {
|
|
|
178
303
|
if playWhenReady { effectHandler?.startPlayback() }
|
|
179
304
|
case .loading:
|
|
180
305
|
effectHandler?.setTimePitchingAlgorithmForCurrentItem()
|
|
306
|
+
case .ended:
|
|
307
|
+
// A natural end exhausts the play intent — nothing is left to play.
|
|
308
|
+
// Keeping playWhenReady true would invert the play/pause toggle, hold
|
|
309
|
+
// the audio session forever (release is intent-gated), and arm
|
|
310
|
+
// interruption auto-resume into silence. The setter also requests the
|
|
311
|
+
// session release.
|
|
312
|
+
playWhenReady = false
|
|
181
313
|
default: break
|
|
182
314
|
}
|
|
183
315
|
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
)
|
|
191
|
-
effectHandler.updateNowPlayingState(playWhenReady: playWhenReady)
|
|
192
|
-
default: break
|
|
193
|
-
}
|
|
194
|
-
}
|
|
316
|
+
// Reflect play/pause (auto-publishing doesn't set the explicit now-playing
|
|
317
|
+
// playback state). Active states show the user's intent — incl. .loading, so
|
|
318
|
+
// the button flips to "playing" the moment a play-intent load begins; terminal
|
|
319
|
+
// states (error/stopped/ended) resolve to paused so the button never sticks on
|
|
320
|
+
// "playing" after playback fails or stops.
|
|
321
|
+
effectHandler?.updateNowPlayingState(playWhenReady: playbackActive && playWhenReady)
|
|
195
322
|
|
|
196
|
-
|
|
323
|
+
progressTimer.onPlaybackStateChanged(new)
|
|
324
|
+
intervalTimer.onPlaybackStateChanged(new)
|
|
197
325
|
playingStateManager.update(playWhenReady: playWhenReady, state: new)
|
|
198
326
|
}
|
|
199
327
|
|
|
200
328
|
private func emitStateChange(old: PlaybackState, new: PlaybackState) {
|
|
201
329
|
// Playback state change — always emitted
|
|
202
330
|
callbacks?.playerDidChangePlayback(
|
|
203
|
-
Playback(state: new, error:
|
|
331
|
+
Playback(state: new, error: nitroPlaybackError()),
|
|
204
332
|
)
|
|
205
333
|
|
|
206
334
|
// Error callback — emitted when entering or leaving error state
|
|
207
335
|
if new == .error || (old == .error && new != .error) {
|
|
208
336
|
callbacks?.playerDidError(
|
|
209
|
-
PlaybackErrorEvent(error:
|
|
337
|
+
PlaybackErrorEvent(error: nitroPlaybackError()),
|
|
210
338
|
)
|
|
211
339
|
}
|
|
212
340
|
|
|
213
|
-
// Queue ended — when playback ends on the last track
|
|
214
|
-
|
|
341
|
+
// Queue ended — when playback ends on the last track. Repeat modes never
|
|
342
|
+
// conceptually end the queue (matches web's endsQueue()): a repeat-track
|
|
343
|
+
// pause at the track boundary (e.g. the end-of-track sleep timer) must not
|
|
344
|
+
// read as "playlist over".
|
|
345
|
+
if new == .ended, isLastInPlaybackOrder, repeatMode == .off, let effectHandler {
|
|
215
346
|
callbacks?.playerDidEndQueue(
|
|
216
347
|
PlaybackQueueEndedEvent(track: Double(currentIndex), position: effectHandler.currentTime),
|
|
217
348
|
)
|
|
@@ -251,13 +382,13 @@ class PlaybackCoordinator {
|
|
|
251
382
|
}
|
|
252
383
|
}
|
|
253
384
|
|
|
254
|
-
func avPlayerStatusDidFail(error: Error?) {
|
|
255
|
-
errorHandler.handleError(error, context: .playback)
|
|
385
|
+
func avPlayerStatusDidFail(error: Error?, httpStatusCode: Int? = nil) {
|
|
386
|
+
errorHandler.handleError(error, context: .playback, httpStatusCode: httpStatusCode)
|
|
256
387
|
}
|
|
257
388
|
|
|
258
|
-
func avItemStatusDidChange(_ status: PlayerItemStatus, error: Error?) {
|
|
389
|
+
func avItemStatusDidChange(_ status: PlayerItemStatus, error: Error?, httpStatusCode: Int? = nil) {
|
|
259
390
|
if status == .failed {
|
|
260
|
-
errorHandler.handleError(error, context: .playback)
|
|
391
|
+
errorHandler.handleError(error, context: .playback, httpStatusCode: httpStatusCode)
|
|
261
392
|
}
|
|
262
393
|
}
|
|
263
394
|
|
|
@@ -292,12 +423,75 @@ class PlaybackCoordinator {
|
|
|
292
423
|
}
|
|
293
424
|
|
|
294
425
|
func stop() {
|
|
426
|
+
// Cancel before the intent drop: a surviving retry would surface .error
|
|
427
|
+
// over the stop, and a pending task blocks the session release below.
|
|
428
|
+
errorHandler.cancelPendingRetry()
|
|
429
|
+
// A stop is terminal — interruption-end must not resume over it.
|
|
430
|
+
shouldResumeAfterInterruption = false
|
|
295
431
|
transition(.stopped)
|
|
296
432
|
playWhenReady = false
|
|
297
433
|
}
|
|
298
434
|
|
|
435
|
+
// MARK: - Audio Session Interruptions
|
|
436
|
+
|
|
437
|
+
/// The active output route disappeared (headphones unplugged, Bluetooth
|
|
438
|
+
/// speaker off). A deliberate output loss: drop the intent and any pending
|
|
439
|
+
/// interruption auto-resume, so a call ending can't blast the built-in
|
|
440
|
+
/// speaker.
|
|
441
|
+
func handleRouteDisconnected() {
|
|
442
|
+
shouldResumeAfterInterruption = false
|
|
443
|
+
pause()
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/// An audio-session interruption began (a phone call, or another app such as
|
|
447
|
+
/// Music/Spotify taking over playback). iOS has already paused our AVPlayer,
|
|
448
|
+
/// but that pause arrives as a `timeControlStatus` change that's swallowed
|
|
449
|
+
/// while `playWhenReady` is still true — so the state would otherwise stay
|
|
450
|
+
/// `.playing` and any UI driven by it stays stuck. Drop the play intent and
|
|
451
|
+
/// force the paused state, independent of notification delivery order.
|
|
452
|
+
func handleInterruptionBegan() {
|
|
453
|
+
// OR: a nested interruption's second .began sees the already-paused
|
|
454
|
+
// intent and must not wipe the flag the first one captured.
|
|
455
|
+
shouldResumeAfterInterruption = shouldResumeAfterInterruption || playWhenReady
|
|
456
|
+
pause()
|
|
457
|
+
if playbackActive, state != .loading {
|
|
458
|
+
transition(.avPlayerPaused(hasAsset: effectHandler?.hasLoadedAsset ?? false))
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/// Whether an interruption-end will resume playback — the intent captured at
|
|
463
|
+
/// interruption start. Lets the host gate side effects that must precede the
|
|
464
|
+
/// resume (audio-session reactivation) on whether one will actually happen.
|
|
465
|
+
var willResumeAfterInterruption: Bool { shouldResumeAfterInterruption }
|
|
466
|
+
|
|
467
|
+
/// An audio-session interruption ended. Resume only if we were playing when it
|
|
468
|
+
/// began and the system indicates resumption is appropriate (`shouldResume`).
|
|
469
|
+
func handleInterruptionEnded(shouldResume: Bool) {
|
|
470
|
+
guard shouldResumeAfterInterruption else { return }
|
|
471
|
+
shouldResumeAfterInterruption = false
|
|
472
|
+
if shouldResume {
|
|
473
|
+
play()
|
|
474
|
+
} else {
|
|
475
|
+
// Interruption ended and we're staying paused: the session can be released now.
|
|
476
|
+
evaluateSessionRelease()
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/// Requests an audio-session release when playback is deliberately stopped: play intent is off,
|
|
481
|
+
/// it isn't an interruption-driven pause (those resume — `shouldResumeAfterInterruption` is set
|
|
482
|
+
/// before the interruption's `pause()`, so this skips it), and no retry is pending (a live-stream
|
|
483
|
+
/// reconnect keeps `playWhenReady` true and must keep the session). The host debounces and cancels
|
|
484
|
+
/// on the next activation, so a quick pause→resume never actually releases.
|
|
485
|
+
private func evaluateSessionRelease() {
|
|
486
|
+
guard !playWhenReady,
|
|
487
|
+
!shouldResumeAfterInterruption,
|
|
488
|
+
errorHandler.pendingRetryTask == nil
|
|
489
|
+
else { return }
|
|
490
|
+
callbacks?.playerShouldReleaseSession()
|
|
491
|
+
}
|
|
492
|
+
|
|
299
493
|
func getPlayback() -> Playback {
|
|
300
|
-
Playback(state: state, error:
|
|
494
|
+
Playback(state: state, error: nitroPlaybackError())
|
|
301
495
|
}
|
|
302
496
|
|
|
303
497
|
func getRepeatMode() -> RepeatMode {
|
|
@@ -339,7 +533,13 @@ class PlaybackCoordinator {
|
|
|
339
533
|
queue.replace(index, track)
|
|
340
534
|
}
|
|
341
535
|
|
|
342
|
-
func setQueue(
|
|
536
|
+
func setQueue(
|
|
537
|
+
_ newTracks: [Track],
|
|
538
|
+
initialIndex: Int = 0,
|
|
539
|
+
startPositionMs: Double? = nil,
|
|
540
|
+
playWhenReady: Bool? = nil,
|
|
541
|
+
sourcePath: String? = nil,
|
|
542
|
+
) {
|
|
343
543
|
guard !newTracks.isEmpty else {
|
|
344
544
|
clear()
|
|
345
545
|
return
|
|
@@ -347,6 +547,12 @@ class PlaybackCoordinator {
|
|
|
347
547
|
handlePlayWhenReady(playWhenReady) {
|
|
348
548
|
queue.setQueue(newTracks, initialIndex: initialIndex, sourcePath: sourcePath)
|
|
349
549
|
handleCurrentTrackChanged()
|
|
550
|
+
// Start position is applied as part of the load: captured as a pending
|
|
551
|
+
// seek that runs once the item is ready, deferring the ready/play
|
|
552
|
+
// transition until it lands (no start-at-0 flash).
|
|
553
|
+
if let ms = startPositionMs, ms > 0 {
|
|
554
|
+
loadSeekCoordinator.capture(position: ms / 1000)
|
|
555
|
+
}
|
|
350
556
|
}
|
|
351
557
|
}
|
|
352
558
|
|
|
@@ -360,29 +566,31 @@ class PlaybackCoordinator {
|
|
|
360
566
|
func add(_ tracks: [Track], at index: Int) throws {
|
|
361
567
|
let changed = try queue.addAt(tracks, at: index)
|
|
362
568
|
if changed { handleCurrentTrackChanged() }
|
|
569
|
+
pushSkipAvailability() // didSet pushed pre-settlement state
|
|
363
570
|
}
|
|
364
571
|
|
|
365
572
|
func next() {
|
|
366
573
|
let result = queue.next()
|
|
367
574
|
switch result {
|
|
368
|
-
case .trackChanged:
|
|
575
|
+
case .trackChanged: handleCurrentTrackChanged()
|
|
369
576
|
case .sameTrackReplay: if playWhenReady { replay() }
|
|
370
|
-
case .noChange:
|
|
577
|
+
case .noChange: break
|
|
371
578
|
}
|
|
372
579
|
}
|
|
373
580
|
|
|
374
581
|
func previous() {
|
|
375
582
|
let result = queue.previous()
|
|
376
583
|
switch result {
|
|
377
|
-
case .trackChanged:
|
|
584
|
+
case .trackChanged: handleCurrentTrackChanged()
|
|
378
585
|
case .sameTrackReplay: if playWhenReady { replay() }
|
|
379
|
-
case .noChange:
|
|
586
|
+
case .noChange: break
|
|
380
587
|
}
|
|
381
588
|
}
|
|
382
589
|
|
|
383
590
|
func remove(_ index: Int) throws {
|
|
384
591
|
let changed = try queue.remove(index)
|
|
385
592
|
if changed { handleCurrentTrackChanged() }
|
|
593
|
+
pushSkipAvailability() // didSet pushed pre-settlement state
|
|
386
594
|
}
|
|
387
595
|
|
|
388
596
|
func skipTo(_ index: Int, playWhenReady: Bool? = nil) throws {
|
|
@@ -399,10 +607,14 @@ class PlaybackCoordinator {
|
|
|
399
607
|
func move(fromIndex: Int, toIndex: Int) throws {
|
|
400
608
|
let changed = try queue.move(fromIndex: fromIndex, toIndex: toIndex)
|
|
401
609
|
if changed { handleCurrentTrackChanged() }
|
|
610
|
+
// tracks.didSet pushed availability mid-mutation, before the pointer and
|
|
611
|
+
// shuffle order settled — re-push the real post-mutation state.
|
|
612
|
+
pushSkipAvailability()
|
|
402
613
|
}
|
|
403
614
|
|
|
404
615
|
func removeUpcomingTracks() {
|
|
405
616
|
queue.removeUpcomingTracks()
|
|
617
|
+
pushSkipAvailability() // didSet pushed pre-settlement state
|
|
406
618
|
}
|
|
407
619
|
|
|
408
620
|
func replay() {
|
|
@@ -422,7 +634,14 @@ class PlaybackCoordinator {
|
|
|
422
634
|
sleepTimerManager.onTrackPlayedToEnd()
|
|
423
635
|
|
|
424
636
|
if repeatMode == .track {
|
|
425
|
-
|
|
637
|
+
// The end-of-track sleep pause lands just above and clears the intent;
|
|
638
|
+
// without it, settle in .ended (where play() reloads) instead of
|
|
639
|
+
// replaying past the sleep timer.
|
|
640
|
+
if playWhenReady {
|
|
641
|
+
replay()
|
|
642
|
+
} else {
|
|
643
|
+
transition(.trackEndedNaturally)
|
|
644
|
+
}
|
|
426
645
|
} else if repeatMode == .queue || !isLastInPlaybackOrder {
|
|
427
646
|
next()
|
|
428
647
|
} else {
|
|
@@ -440,6 +659,14 @@ class PlaybackCoordinator {
|
|
|
440
659
|
|
|
441
660
|
if playbackError != nil {
|
|
442
661
|
playbackError = nil
|
|
662
|
+
// A retrying error can be cleared while already .loading — the
|
|
663
|
+
// .trackLoading transition below then won't fire, so emit the clear
|
|
664
|
+
// here or the old track's error lingers over the new one's spinner.
|
|
665
|
+
if isRetryingError, state == .loading {
|
|
666
|
+
isRetryingError = false
|
|
667
|
+
callbacks?.playerDidChangePlayback(Playback(state: state, error: nil))
|
|
668
|
+
}
|
|
669
|
+
isRetryingError = false
|
|
443
670
|
}
|
|
444
671
|
|
|
445
672
|
let lastPosition = effectHandler?.currentTime ?? 0
|
|
@@ -455,8 +682,7 @@ class PlaybackCoordinator {
|
|
|
455
682
|
// Ensure playWhenReady is set before loading to preserve playback state
|
|
456
683
|
playWhenReady = shouldContinuePlayback
|
|
457
684
|
|
|
458
|
-
effectHandler?.
|
|
459
|
-
effectHandler?.loadNowPlayingMetadata(for: currentTrack, rate: rate)
|
|
685
|
+
effectHandler?.loadNowPlayingMetadata(for: currentTrack)
|
|
460
686
|
|
|
461
687
|
// Validate source URL before handing off to MediaLoader
|
|
462
688
|
guard let src = currentTrack.src else {
|
|
@@ -472,7 +698,7 @@ class PlaybackCoordinator {
|
|
|
472
698
|
logger.debug(" track.url: \(currentTrack.url ?? "nil")")
|
|
473
699
|
logger.debug(" track.src: \(src)")
|
|
474
700
|
|
|
475
|
-
effectHandler?.loadTrack(src: src)
|
|
701
|
+
effectHandler?.loadTrack(src: src, track: currentTrack)
|
|
476
702
|
} else {
|
|
477
703
|
effectHandler?.unloadTrack()
|
|
478
704
|
effectHandler?.clearNowPlaying()
|
|
@@ -488,6 +714,7 @@ class PlaybackCoordinator {
|
|
|
488
714
|
callbacks?.playerDidChangeActiveTrack(eventData)
|
|
489
715
|
lastTrack = currentTrack
|
|
490
716
|
lastIndex = currentIndex
|
|
717
|
+
pushSkipAvailability() // position moved → next/previous availability may change
|
|
491
718
|
}
|
|
492
719
|
|
|
493
720
|
// MARK: - Seek Completion (called by TrackPlayer after AVPlayer seek lands)
|
|
@@ -497,13 +724,16 @@ class PlaybackCoordinator {
|
|
|
497
724
|
logger.debug("[loadSeek] seek landed at \(seconds)s (finished=\(didFinish)) → .ready")
|
|
498
725
|
transition(.loadSeekCompleted)
|
|
499
726
|
}
|
|
500
|
-
effectHandler?.setNowPlayingCurrentTime(seconds: seconds)
|
|
501
727
|
}
|
|
502
728
|
|
|
503
729
|
// MARK: - Progress Updates
|
|
504
730
|
|
|
505
731
|
func setProgressUpdateInterval(_ interval: TimeInterval?) {
|
|
506
|
-
|
|
732
|
+
progressTimer.setInterval(interval)
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
func setPlaybackIntervalEnabled(_ enabled: Bool) {
|
|
736
|
+
intervalTimer.setInterval(enabled ? 1 : nil)
|
|
507
737
|
}
|
|
508
738
|
}
|
|
509
739
|
|
|
@@ -512,6 +742,7 @@ class PlaybackCoordinator {
|
|
|
512
742
|
extension PlaybackCoordinator: QueueManagerDelegate {
|
|
513
743
|
func queueDidChangeTracks(_ tracks: [Track]) {
|
|
514
744
|
callbacks?.playerDidChangeQueue(tracks)
|
|
745
|
+
pushSkipAvailability() // queue contents changed → boundaries moved
|
|
515
746
|
}
|
|
516
747
|
}
|
|
517
748
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#if canImport(NitroModules)
|
|
2
|
-
import NitroModules
|
|
2
|
+
import NitroModules
|
|
3
3
|
#endif
|
|
4
4
|
|
|
5
5
|
/// Subset of TrackPlayerCallbacks containing only the callbacks the coordinator fires.
|
|
@@ -9,6 +9,7 @@ import NitroModules
|
|
|
9
9
|
func playerDidChangePlayback(_ playback: Playback)
|
|
10
10
|
func playerDidChangeActiveTrack(_ event: PlaybackActiveTrackChangedEvent)
|
|
11
11
|
func playerDidUpdateProgress(_ event: PlaybackProgressUpdatedEvent)
|
|
12
|
+
func playerDidFirePlaybackInterval()
|
|
12
13
|
func playerDidChangePlayWhenReady(_ playWhenReady: Bool)
|
|
13
14
|
func playerDidChangePlayingState(_ state: PlayingState)
|
|
14
15
|
func playerDidEndQueue(_ event: PlaybackQueueEndedEvent)
|
|
@@ -16,4 +17,8 @@ import NitroModules
|
|
|
16
17
|
func playerDidChangeRepeatMode(_ event: RepeatModeChangedEvent)
|
|
17
18
|
func playerDidChangeShuffleEnabled(_ enabled: Bool)
|
|
18
19
|
func playerDidError(_ event: PlaybackErrorEvent)
|
|
20
|
+
/// Playback is deliberately stopped — play intent is off, it isn't an interruption-driven pause
|
|
21
|
+
/// (those resume), and no retry is pending (a live-stream reconnect must keep the session). The
|
|
22
|
+
/// host may release the audio session (debounced) so other apps' audio can resume.
|
|
23
|
+
func playerShouldReleaseSession()
|
|
19
24
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#if canImport(NitroModules)
|
|
2
|
-
import NitroModules
|
|
2
|
+
import NitroModules
|
|
3
3
|
#endif
|
|
4
4
|
|
|
5
5
|
/// Protocol through which PlaybackCoordinator triggers AVPlayer-specific operations.
|
|
@@ -10,6 +10,9 @@ import NitroModules
|
|
|
10
10
|
func pausePlayback()
|
|
11
11
|
func setTimePitchingAlgorithmForCurrentItem()
|
|
12
12
|
|
|
13
|
+
// Player volume (0-1); ramped by the sleep-timer fade
|
|
14
|
+
var volume: Float { get set }
|
|
15
|
+
|
|
13
16
|
// AVPlayer state queries
|
|
14
17
|
var currentTime: Double { get }
|
|
15
18
|
var duration: Double { get }
|
|
@@ -20,8 +23,11 @@ import NitroModules
|
|
|
20
23
|
func clearCurrentItem()
|
|
21
24
|
func stopObservingCurrentItem()
|
|
22
25
|
|
|
23
|
-
// Track loading
|
|
24
|
-
|
|
26
|
+
// Track loading. The full `track` is threaded alongside `src` so the
|
|
27
|
+
// media-URL resolver can invoke the consumer's `media.resolve(track)`.
|
|
28
|
+
func loadTrack(src: String, track: Track)
|
|
29
|
+
/// Reloads the current track, re-running the media-URL resolver so a
|
|
30
|
+
/// short-lived/expired URL is refreshed rather than replayed.
|
|
25
31
|
func reloadTrack(startFromCurrentTime: Bool)
|
|
26
32
|
func unloadTrack()
|
|
27
33
|
func cancelMediaLoading()
|
|
@@ -30,15 +36,19 @@ import NitroModules
|
|
|
30
36
|
func seekToStart()
|
|
31
37
|
func replayCurrentTrack()
|
|
32
38
|
|
|
33
|
-
// Now Playing (behind protocol to avoid MediaPlayer import)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
func loadNowPlayingMetadata(for track: Track
|
|
37
|
-
func resetNowPlayingValues()
|
|
39
|
+
// Now Playing (behind protocol to avoid MediaPlayer import).
|
|
40
|
+
// Elapsed/rate/duration are published automatically by MPNowPlayingSession;
|
|
41
|
+
// only metadata and the explicit play/pause state flow through here.
|
|
42
|
+
func loadNowPlayingMetadata(for track: Track)
|
|
38
43
|
func clearNowPlaying()
|
|
39
|
-
|
|
44
|
+
/// Reflects play/pause intent in the now-playing center. Auto-publishing fills
|
|
45
|
+
/// the info dict but not the explicit playback state CarPlay reads for its button.
|
|
46
|
+
func updateNowPlayingState(playWhenReady: Bool)
|
|
40
47
|
|
|
41
48
|
// Remote commands (behind protocol to avoid MediaPlayer import)
|
|
42
49
|
func updateRemoteRepeatMode(_ mode: RepeatMode)
|
|
43
50
|
func updateRemoteShuffleMode(_ enabled: Bool)
|
|
51
|
+
/// Greys out the remote/CarPlay next/previous buttons when the queue has no
|
|
52
|
+
/// next/previous track to skip to.
|
|
53
|
+
func updateSkipAvailability(canNext: Bool, canPrevious: Bool)
|
|
44
54
|
}
|