react-native-audio-browser 0.1.1 → 0.2.0-next.2
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 +85 -40
- 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 +31 -11
- package/ios/Player/NowPlayingUpdater.swift +119 -26
- package/ios/Player/PersistedPlaybackState.swift +11 -0
- package/ios/Player/PlaybackCoordinator.swift +285 -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 +72 -11
- 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 +32 -20
- package/ios/Tests/MediaResolveTests.swift +126 -0
- package/ios/Tests/OnceValueTests.swift +79 -0
- package/ios/Tests/PlaybackCoordinatorTests.swift +787 -13
- package/ios/Tests/PlaybackErrorHandlerTests.swift +380 -46
- package/ios/Tests/PlaybackStateMachineTests.swift +33 -8
- 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 +107 -0
- package/ios/Tests/Support/ManualSleepTimerScheduler.swift +47 -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 +11 -6
- 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 +365 -158
- 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
package/ios/TrackPlayer.swift
CHANGED
|
@@ -17,6 +17,12 @@ class TrackPlayer {
|
|
|
17
17
|
let nowPlayingInfoController: NowPlayingInfoController
|
|
18
18
|
let remoteCommandController: RemoteCommandController
|
|
19
19
|
private let retryManager = RetryManager()
|
|
20
|
+
private let playbackStateStore = PlaybackStateStore()
|
|
21
|
+
|
|
22
|
+
// MARK: - Periodic Persist
|
|
23
|
+
|
|
24
|
+
/// Cancelled when playback stops; recreated when it starts.
|
|
25
|
+
private var periodicSaveTask: Task<Void, Never>?
|
|
20
26
|
|
|
21
27
|
/// Retry configuration for load errors (network failures, timeouts, etc.)
|
|
22
28
|
var retryConfig: Variant_Bool_RetryConfig? {
|
|
@@ -52,23 +58,27 @@ class TrackPlayer {
|
|
|
52
58
|
)
|
|
53
59
|
|
|
54
60
|
private lazy var playerTimeObserver: PlayerTimeObserver = .init(
|
|
55
|
-
periodicObserverTimeInterval: CMTime(seconds: 1, preferredTimescale: 1000),
|
|
56
61
|
onAudioDidStart: { [weak self] in
|
|
62
|
+
// Audio rendered: this load has proven itself — retries from here on get
|
|
63
|
+
// the full recovery budget, not the short first-connect one.
|
|
64
|
+
self?.retryManager.hasPlayed = true
|
|
57
65
|
self?.coordinator.audioDidStart()
|
|
58
66
|
},
|
|
59
|
-
onSecondElapsed: { [weak self] seconds in
|
|
60
|
-
self?.nowPlayingUpdater.setCurrentTime(seconds: seconds)
|
|
61
|
-
},
|
|
62
67
|
)
|
|
63
68
|
|
|
64
69
|
private lazy var playerItemNotificationObserver: PlayerItemNotificationObserver = .init(
|
|
65
|
-
onDidPlayToEndTime: { [weak self] in
|
|
66
|
-
self?.coordinator.handleTrackDidPlayToEndTime()
|
|
67
|
-
},
|
|
70
|
+
onDidPlayToEndTime: { [weak self] in self?.handleDidPlayToEndTime() },
|
|
68
71
|
onFailedToPlayToEndTime: { [weak self] error in
|
|
69
72
|
let effectiveError = error ?? self?.avPlayer.currentItem?.error
|
|
70
|
-
self?.coordinator.errorHandler.handleError(
|
|
73
|
+
self?.coordinator.errorHandler.handleError(
|
|
74
|
+
effectiveError,
|
|
75
|
+
context: .playback,
|
|
76
|
+
httpStatusCode: self?.currentItemHttpStatusCode,
|
|
77
|
+
)
|
|
71
78
|
},
|
|
79
|
+
// Buffer emptied mid-playback: nudge the player, but don't reconnect — a
|
|
80
|
+
// genuine drop is recovered by the retry / network-restore paths.
|
|
81
|
+
onPlaybackStalled: { [weak self] in self?.recoverFromStall(reconnectIfLive: false) },
|
|
72
82
|
)
|
|
73
83
|
|
|
74
84
|
private lazy var playerItemObserver: PlayerItemPropertyObserver = .init(
|
|
@@ -86,6 +96,12 @@ class TrackPlayer {
|
|
|
86
96
|
},
|
|
87
97
|
)
|
|
88
98
|
|
|
99
|
+
// MARK: - Now-Playing Election
|
|
100
|
+
|
|
101
|
+
private let silentAudioPrimer = SilentAudioPrimer()
|
|
102
|
+
/// Latched on the first failure of each load; reset when a new track loads.
|
|
103
|
+
private var didPrimeNowPlayingElection = false
|
|
104
|
+
|
|
89
105
|
// MARK: - Callbacks
|
|
90
106
|
|
|
91
107
|
weak var callbacks: TrackPlayerCallbacks? {
|
|
@@ -101,14 +117,17 @@ class TrackPlayer {
|
|
|
101
117
|
get { coordinator.playbackError }
|
|
102
118
|
set { coordinator.playbackError = newValue }
|
|
103
119
|
}
|
|
120
|
+
|
|
104
121
|
var lastIndex: Int {
|
|
105
122
|
get { coordinator.lastIndex }
|
|
106
123
|
set { coordinator.lastIndex = newValue }
|
|
107
124
|
}
|
|
125
|
+
|
|
108
126
|
var lastTrack: Track? {
|
|
109
127
|
get { coordinator.lastTrack }
|
|
110
128
|
set { coordinator.lastTrack = newValue }
|
|
111
129
|
}
|
|
130
|
+
|
|
112
131
|
var tracks: [Track] { coordinator.tracks }
|
|
113
132
|
var currentIndex: Int { coordinator.currentIndex }
|
|
114
133
|
var currentTrack: Track? { coordinator.currentTrack }
|
|
@@ -138,6 +157,19 @@ class TrackPlayer {
|
|
|
138
157
|
set { coordinator.playWhenReady = newValue }
|
|
139
158
|
}
|
|
140
159
|
|
|
160
|
+
/// Time playback must have progressed before a buffer dip counts as a stall, so the initial
|
|
161
|
+
/// connect / a seek doesn't read as one. iOS has no native rebuffer-vs-initial signal.
|
|
162
|
+
private static let stallGraceSeconds: TimeInterval = 0.5
|
|
163
|
+
|
|
164
|
+
/// True while ongoing playback has stalled waiting for data. Approximated from
|
|
165
|
+
/// `isPlaybackLikelyToKeepUp`, gated on having actually started and the play intent (so an
|
|
166
|
+
/// initial connect / seek doesn't read as a stall). Mirrors the Android `stalled` signal, which
|
|
167
|
+
/// the load control distinguishes natively.
|
|
168
|
+
var isStalled: Bool {
|
|
169
|
+
guard let item = avPlayer.currentItem else { return false }
|
|
170
|
+
return currentTime > Self.stallGraceSeconds && playWhenReady && !item.isPlaybackLikelyToKeepUp
|
|
171
|
+
}
|
|
172
|
+
|
|
141
173
|
/**
|
|
142
174
|
Controls the time pitch algorithm applied to each track loaded into the player.
|
|
143
175
|
*/
|
|
@@ -222,7 +254,6 @@ class TrackPlayer {
|
|
|
222
254
|
set {
|
|
223
255
|
coordinator.rate = newValue
|
|
224
256
|
avPlayer.rate = newValue
|
|
225
|
-
nowPlayingUpdater.updatePlaybackValues(duration: duration, rate: newValue, currentTime: currentTime)
|
|
226
257
|
}
|
|
227
258
|
}
|
|
228
259
|
|
|
@@ -249,7 +280,9 @@ class TrackPlayer {
|
|
|
249
280
|
self?.playWhenReady ?? false
|
|
250
281
|
}
|
|
251
282
|
retryManager.onRetry = { [weak self] startFromCurrentTime in
|
|
252
|
-
|
|
283
|
+
// Re-resolve rather than replay the cached URL: a retry may be recovering
|
|
284
|
+
// from an expired short-lived URL/token that only a fresh resolve fixes.
|
|
285
|
+
self?.reloadResolving(startFromCurrentTime: startFromCurrentTime)
|
|
253
286
|
}
|
|
254
287
|
|
|
255
288
|
// Handle command center changes when MPNowPlayingSession is created/destroyed (iOS 16+)
|
|
@@ -270,6 +303,7 @@ class TrackPlayer {
|
|
|
270
303
|
func handlePlayWhenReady(_ playWhenReady: Bool?, action: () throws -> Void) rethrows {
|
|
271
304
|
try coordinator.handlePlayWhenReady(playWhenReady, action: action)
|
|
272
305
|
}
|
|
306
|
+
|
|
273
307
|
func transition(_ event: PlaybackEvent) { coordinator.transition(event) }
|
|
274
308
|
|
|
275
309
|
// MARK: - Player Actions
|
|
@@ -293,6 +327,13 @@ class TrackPlayer {
|
|
|
293
327
|
func pause() { coordinator.pause() }
|
|
294
328
|
func togglePlayback() { coordinator.togglePlayback() }
|
|
295
329
|
|
|
330
|
+
func handleInterruptionBegan() { coordinator.handleInterruptionBegan() }
|
|
331
|
+
func handleRouteDisconnected() { coordinator.handleRouteDisconnected() }
|
|
332
|
+
var willResumeAfterInterruption: Bool { coordinator.willResumeAfterInterruption }
|
|
333
|
+
func handleInterruptionEnded(shouldResume: Bool) {
|
|
334
|
+
coordinator.handleInterruptionEnded(shouldResume: shouldResume)
|
|
335
|
+
}
|
|
336
|
+
|
|
296
337
|
func stop() {
|
|
297
338
|
coordinator.stop()
|
|
298
339
|
if currentTrack?.live != true {
|
|
@@ -301,20 +342,62 @@ class TrackPlayer {
|
|
|
301
342
|
}
|
|
302
343
|
|
|
303
344
|
func reload(startFromCurrentTime: Bool) {
|
|
304
|
-
|
|
305
|
-
if startFromCurrentTime {
|
|
306
|
-
if let currentItem = avPlayer.currentItem {
|
|
307
|
-
if !currentItem.duration.isIndefinite {
|
|
308
|
-
time = currentItem.currentTime().seconds
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
345
|
+
let time = startFromCurrentTime ? resumeTime() : nil
|
|
312
346
|
loadAVPlayer()
|
|
313
347
|
if let time {
|
|
314
348
|
seekTo(time)
|
|
315
349
|
}
|
|
316
350
|
}
|
|
317
351
|
|
|
352
|
+
/// Playback position to resume from on reload, or nil when there is nothing
|
|
353
|
+
/// seekable to resume (no item, or an indefinite/live duration).
|
|
354
|
+
private func resumeTime() -> Double? {
|
|
355
|
+
guard let currentItem = avPlayer.currentItem, !currentItem.duration.isIndefinite else {
|
|
356
|
+
return nil
|
|
357
|
+
}
|
|
358
|
+
return currentItem.currentTime().seconds
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/// Re-establish a stalled stream when connectivity is restored.
|
|
362
|
+
///
|
|
363
|
+
/// AVPlayer doesn't reliably surface a mid-stream connectivity loss on a live stream as an item
|
|
364
|
+
/// failure — it sits in `.waitingToPlayAtSpecifiedRate` (a buffering stall) with no error, so the
|
|
365
|
+
/// error-driven `RetryManager` never engages. Without this, the stream stays "reconnecting"
|
|
366
|
+
/// indefinitely after the network returns. Mirrors Android, where ExoPlayer surfaces the drop as a
|
|
367
|
+
/// retryable load error and re-prepares on restore.
|
|
368
|
+
///
|
|
369
|
+
/// Guards: reload only while actually stalled (`.buffering`) with play intent — so a user-initiated
|
|
370
|
+
/// pause, or a retry that already gave up (`.error`, past the max retry duration) isn't surprisingly
|
|
371
|
+
/// resumed. Skipped when `RetryManager` is already parked waiting for the network: an error *did*
|
|
372
|
+
/// schedule a retry that owns its own reload, so we'd otherwise load twice.
|
|
373
|
+
func handleNetworkRestored() {
|
|
374
|
+
guard playWhenReady,
|
|
375
|
+
coordinator.state == .buffering,
|
|
376
|
+
!retryManager.isWaitingForNetwork
|
|
377
|
+
else { return }
|
|
378
|
+
logger.info("Connectivity restored while stalled — re-resolving to reconnect")
|
|
379
|
+
// Re-resolve rather than replay the cached URL: a resolver that mints a short-lived URL/token
|
|
380
|
+
// may have had it expire during the offline gap, so reconnecting with the stale URL would just
|
|
381
|
+
// fail (then recover only via the error path). Matches the error-retry path here, and Android,
|
|
382
|
+
// which re-resolves on its network-error reconnect. `reloadResolving` falls back to a plain
|
|
383
|
+
// reload when there's no track `src` to resolve.
|
|
384
|
+
reloadResolving(startFromCurrentTime: true)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/// Jump to the live edge. No-op for non-live tracks. Live with a seekable
|
|
388
|
+
/// window (HLS) seeks to the window end; live without one (non-seekable, e.g.
|
|
389
|
+
/// ICY) has no window to seek within, so reconnect to rejoin live.
|
|
390
|
+
func seekToLiveEdge() {
|
|
391
|
+
guard currentTrack?.live == true, let item = avPlayer.currentItem else { return }
|
|
392
|
+
if let range = item.seekableTimeRanges.last?.timeRangeValue, range.duration.seconds > 0 {
|
|
393
|
+
avPlayer.seek(to: range.end, toleranceBefore: .zero, toleranceAfter: .zero)
|
|
394
|
+
} else {
|
|
395
|
+
// Re-resolve on reconnect: this is the stall-recovery path for non-seekable live
|
|
396
|
+
// streams, where a short-lived stream URL may have expired during the outage.
|
|
397
|
+
reloadResolving(startFromCurrentTime: false)
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
318
401
|
func seekTo(_ seconds: TimeInterval) {
|
|
319
402
|
seekTo(seconds, completion: { _ in })
|
|
320
403
|
}
|
|
@@ -326,10 +409,22 @@ class TrackPlayer {
|
|
|
326
409
|
} else if avPlayer.currentItem != nil {
|
|
327
410
|
let time = CMTime(seconds: seconds, preferredTimescale: 1000)
|
|
328
411
|
let seekSeconds = seconds
|
|
412
|
+
let generation = loadSeekCoordinator.generation
|
|
329
413
|
avPlayer
|
|
330
414
|
.seek(to: time, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) { [weak self] finished in
|
|
331
415
|
Task { @MainActor in
|
|
332
|
-
self
|
|
416
|
+
guard let self else {
|
|
417
|
+
completion(false)
|
|
418
|
+
return
|
|
419
|
+
}
|
|
420
|
+
// A completion from before a track change (reset() bumped the
|
|
421
|
+
// generation) belongs to the old item — delivering it would emit a
|
|
422
|
+
// bogus seek-completed and consume the new track's pending start seek.
|
|
423
|
+
guard self.loadSeekCoordinator.isCurrentGeneration(generation) else {
|
|
424
|
+
completion(false)
|
|
425
|
+
return
|
|
426
|
+
}
|
|
427
|
+
self.handleSeekCompleted(to: Double(seekSeconds), didFinish: finished)
|
|
333
428
|
completion(finished)
|
|
334
429
|
}
|
|
335
430
|
}
|
|
@@ -354,6 +449,11 @@ class TrackPlayer {
|
|
|
354
449
|
|
|
355
450
|
func enableRemoteCommands(_ commands: [RemoteCommand]) {
|
|
356
451
|
remoteCommandController.enable(commands: commands)
|
|
452
|
+
// Apply current next/previous availability so re-/late-configured commands
|
|
453
|
+
// start in the correct enabled state (not unconditionally enabled).
|
|
454
|
+
remoteCommandController.setSkipAvailability(
|
|
455
|
+
canNext: coordinator.canNext, canPrevious: coordinator.canPrevious,
|
|
456
|
+
)
|
|
357
457
|
}
|
|
358
458
|
|
|
359
459
|
func clear() {
|
|
@@ -372,6 +472,10 @@ class TrackPlayer {
|
|
|
372
472
|
coordinator.setProgressUpdateInterval(interval)
|
|
373
473
|
}
|
|
374
474
|
|
|
475
|
+
func setPlaybackIntervalEnabled(_ enabled: Bool) {
|
|
476
|
+
coordinator.setPlaybackIntervalEnabled(enabled)
|
|
477
|
+
}
|
|
478
|
+
|
|
375
479
|
// MARK: - AVPlayer Management
|
|
376
480
|
|
|
377
481
|
func setTimePitchingAlgorithmForCurrentItem() {
|
|
@@ -409,7 +513,6 @@ class TrackPlayer {
|
|
|
409
513
|
private func recreateAVPlayer() {
|
|
410
514
|
coordinator.playbackError = nil
|
|
411
515
|
playerTimeObserver.unregisterForBoundaryTimeEvents()
|
|
412
|
-
playerTimeObserver.unregisterForPeriodicEvents()
|
|
413
516
|
playerObserver.stopObserving()
|
|
414
517
|
stopObservingAVPlayerItem()
|
|
415
518
|
clearCurrentAVItem()
|
|
@@ -420,6 +523,17 @@ class TrackPlayer {
|
|
|
420
523
|
setupAVPlayer()
|
|
421
524
|
}
|
|
422
525
|
|
|
526
|
+
/// Recover from a media-services reset (`mediaserverd` crashed/reset): every
|
|
527
|
+
/// AVPlayer/session handle is invalid, so recreate the player and reload the
|
|
528
|
+
/// current track, preserving play intent, so a live stream reconnects instead
|
|
529
|
+
/// of going permanently silent. No-op when nothing is loaded.
|
|
530
|
+
func handleMediaServicesReset() {
|
|
531
|
+
guard currentTrack != nil else { return }
|
|
532
|
+
logger.info("Media services were reset — recreating player and reloading current track")
|
|
533
|
+
recreateAVPlayer()
|
|
534
|
+
reloadResolving(startFromCurrentTime: false)
|
|
535
|
+
}
|
|
536
|
+
|
|
423
537
|
private func setupAVPlayer() {
|
|
424
538
|
avPlayer.allowsExternalPlayback = false
|
|
425
539
|
|
|
@@ -428,21 +542,31 @@ class TrackPlayer {
|
|
|
428
542
|
|
|
429
543
|
playerTimeObserver.avPlayer = avPlayer
|
|
430
544
|
playerTimeObserver.registerForBoundaryTimeEvents()
|
|
431
|
-
playerTimeObserver.registerForPeriodicTimeEvents()
|
|
432
545
|
|
|
433
546
|
nowPlayingInfoController.linkPlayer(avPlayer)
|
|
434
547
|
|
|
435
548
|
if playWhenReady {
|
|
436
549
|
startPlayback()
|
|
437
550
|
} else {
|
|
438
|
-
|
|
439
|
-
avPlayer.defaultRate = rate
|
|
440
|
-
}
|
|
551
|
+
avPlayer.defaultRate = rate
|
|
441
552
|
}
|
|
442
553
|
}
|
|
443
554
|
|
|
444
555
|
func loadAVPlayer() {
|
|
556
|
+
prepareForReload()
|
|
557
|
+
mediaLoader.loadAsset()
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/// Teardown shared by the two reload paths: recreate the player after a
|
|
561
|
+
/// terminal error, otherwise cancel in-flight loading and drop the current
|
|
562
|
+
/// asset, then enter the loading state.
|
|
563
|
+
private func prepareForReload() {
|
|
445
564
|
if state == .error {
|
|
565
|
+
// A restart from terminal error begins a new load of the same track:
|
|
566
|
+
// fresh budgets, unproven playback (see resetForNewLoad). Automatic
|
|
567
|
+
// retries never enter this branch — the retry loop keeps the state
|
|
568
|
+
// non-terminal — so only retry() / play-from-error land here.
|
|
569
|
+
coordinator.errorHandler.resetForNewLoad()
|
|
446
570
|
recreateAVPlayer()
|
|
447
571
|
} else {
|
|
448
572
|
mediaLoader.cancelAll()
|
|
@@ -451,7 +575,25 @@ class TrackPlayer {
|
|
|
451
575
|
mediaLoader.clearAsset()
|
|
452
576
|
}
|
|
453
577
|
transition(.trackLoading)
|
|
454
|
-
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/// Reload by re-running the resolver (fresh URL / headers / user-agent)
|
|
581
|
+
/// instead of recreating the asset from the already-resolved URL. Used by the
|
|
582
|
+
/// retry path so consumers whose resolver mints short-lived URLs or auth
|
|
583
|
+
/// tokens recover once those expire — a plain `reload()` would replay the
|
|
584
|
+
/// stale URL and keep failing. Falls back to `reload()` when there's no track
|
|
585
|
+
/// `src` to resolve.
|
|
586
|
+
func reloadResolving(startFromCurrentTime: Bool) {
|
|
587
|
+
guard let track = currentTrack, let src = track.src else {
|
|
588
|
+
reload(startFromCurrentTime: startFromCurrentTime)
|
|
589
|
+
return
|
|
590
|
+
}
|
|
591
|
+
let time = startFromCurrentTime ? resumeTime() : nil
|
|
592
|
+
prepareForReload()
|
|
593
|
+
mediaLoader.resolveAndLoad(src: src, track: track)
|
|
594
|
+
if let time {
|
|
595
|
+
seekTo(time)
|
|
596
|
+
}
|
|
455
597
|
}
|
|
456
598
|
|
|
457
599
|
func unloadAVPlayer() {
|
|
@@ -461,6 +603,47 @@ class TrackPlayer {
|
|
|
461
603
|
|
|
462
604
|
// MARK: - Observer Callbacks (map AVFoundation → coordinator)
|
|
463
605
|
|
|
606
|
+
/// Resolve an end-of-item notification: a genuine end advances the queue; a
|
|
607
|
+
/// dropped live stream or a mid-stream underrun reported as EOF is recovered
|
|
608
|
+
/// instead of advancing/stopping (see `EndOfTrackJudgement`).
|
|
609
|
+
private func handleDidPlayToEndTime() {
|
|
610
|
+
let judgement = EndOfTrackJudgement(
|
|
611
|
+
isLive: currentTrack?.live == true,
|
|
612
|
+
currentTime: currentTime,
|
|
613
|
+
duration: duration,
|
|
614
|
+
)
|
|
615
|
+
switch judgement.outcome {
|
|
616
|
+
case .ended:
|
|
617
|
+
coordinator.handleTrackDidPlayToEndTime()
|
|
618
|
+
case .stalled:
|
|
619
|
+
recoverFromStall(reconnectIfLive: true)
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/// Recover from a stall while the play intent still holds. A live stream that
|
|
624
|
+
/// ran out of data (`reconnectIfLive`) rejoins the edge — reloading when there
|
|
625
|
+
/// is no seekable window; otherwise just re-issue play() to un-park AVPlayer
|
|
626
|
+
/// from `.waitingToPlayAtSpecifiedRate` (data may resume on the same
|
|
627
|
+
/// connection; a genuine drop is handled by the retry / network-restore paths).
|
|
628
|
+
private func recoverFromStall(reconnectIfLive: Bool) {
|
|
629
|
+
guard playWhenReady else { return }
|
|
630
|
+
if reconnectIfLive, currentTrack?.live == true {
|
|
631
|
+
seekToLiveEdge()
|
|
632
|
+
} else {
|
|
633
|
+
startPlayback()
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/// Previous time-control transition + whether its wait reason was
|
|
638
|
+
/// `.noItemToPlay`, retained to detect the AirPlay waiting→paused stall.
|
|
639
|
+
private var previousTimeControlStatus: PlayerTimeControlStatus?
|
|
640
|
+
private var previousWaitingReasonWasNoItemToPlay = false
|
|
641
|
+
|
|
642
|
+
/// True when the active audio route is AirPlay.
|
|
643
|
+
private var isAirPlayRoute: Bool {
|
|
644
|
+
AVAudioSession.sharedInstance().currentRoute.outputs.contains { $0.portType == .airPlay }
|
|
645
|
+
}
|
|
646
|
+
|
|
464
647
|
private func avPlayerDidChangeTimeControlStatus(_ status: AVPlayer.TimeControlStatus) {
|
|
465
648
|
let mapped: PlayerTimeControlStatus
|
|
466
649
|
switch status {
|
|
@@ -469,12 +652,36 @@ class TrackPlayer {
|
|
|
469
652
|
case .playing: mapped = .playing
|
|
470
653
|
@unknown default: return
|
|
471
654
|
}
|
|
655
|
+
recoverIfAirPlayStalled(transitioningTo: mapped)
|
|
472
656
|
coordinator.avPlayerDidChangeTimeControlStatus(mapped)
|
|
473
657
|
}
|
|
474
658
|
|
|
659
|
+
/// AVPlayer can silently strand us in .paused after a `.noItemToPlay` wait
|
|
660
|
+
/// over AirPlay while we still intend to play — re-issue play() on exactly
|
|
661
|
+
/// that transition. Also records this transition for the next comparison.
|
|
662
|
+
private func recoverIfAirPlayStalled(transitioningTo current: PlayerTimeControlStatus) {
|
|
663
|
+
let stalled = AirPlayStallJudgement(
|
|
664
|
+
previous: previousTimeControlStatus,
|
|
665
|
+
current: current,
|
|
666
|
+
previousWaitingReasonWasNoItemToPlay: previousWaitingReasonWasNoItemToPlay,
|
|
667
|
+
isAirPlay: isAirPlayRoute,
|
|
668
|
+
playWhenReady: playWhenReady,
|
|
669
|
+
).shouldNudge
|
|
670
|
+
previousTimeControlStatus = current
|
|
671
|
+
previousWaitingReasonWasNoItemToPlay =
|
|
672
|
+
current == .waitingToPlayAtSpecifiedRate && avPlayer.reasonForWaitingToPlay == .noItemToPlay
|
|
673
|
+
if stalled {
|
|
674
|
+
logger.info("AirPlay waiting→paused stall detected — nudging play()")
|
|
675
|
+
startPlayback()
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
475
679
|
private func avPlayerStatusDidChange(_ status: AVPlayer.Status) {
|
|
476
680
|
if status == .failed {
|
|
477
|
-
coordinator.avPlayerStatusDidFail(
|
|
681
|
+
coordinator.avPlayerStatusDidFail(
|
|
682
|
+
error: avPlayer.currentItem?.error,
|
|
683
|
+
httpStatusCode: currentItemHttpStatusCode,
|
|
684
|
+
)
|
|
478
685
|
}
|
|
479
686
|
}
|
|
480
687
|
|
|
@@ -486,7 +693,25 @@ class TrackPlayer {
|
|
|
486
693
|
case .failed: mapped = .failed
|
|
487
694
|
@unknown default: return
|
|
488
695
|
}
|
|
489
|
-
coordinator.avItemStatusDidChange(
|
|
696
|
+
coordinator.avItemStatusDidChange(
|
|
697
|
+
mapped,
|
|
698
|
+
error: error ?? avPlayer.currentItem?.error,
|
|
699
|
+
httpStatusCode: currentItemHttpStatusCode,
|
|
700
|
+
)
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/// The HTTP status the server last answered the current item with, if any.
|
|
704
|
+
///
|
|
705
|
+
/// `AVPlayerItem.error` never carries it — a 404 arrives as an opaque
|
|
706
|
+
/// CoreMedia error — so the error log is the only place it surfaces. The log
|
|
707
|
+
/// is per-item, so its entries belong to the track that just failed; picking
|
|
708
|
+
/// among them is `PlaybackErrorHandler`'s job, where it is testable
|
|
709
|
+
/// (`AVPlayerItemErrorLogEvent` cannot be constructed).
|
|
710
|
+
private var currentItemHttpStatusCode: Int? {
|
|
711
|
+
guard let events = avPlayer.currentItem?.errorLog()?.events else { return nil }
|
|
712
|
+
return PlaybackErrorHandler.httpStatusCode(
|
|
713
|
+
fromErrorStatusCodes: events.map(\.errorStatusCode),
|
|
714
|
+
)
|
|
490
715
|
}
|
|
491
716
|
|
|
492
717
|
private func avItemDidUpdatePlaybackLikelyToKeepUp(_ playbackLikelyToKeepUp: Bool) {
|
|
@@ -504,14 +729,64 @@ class TrackPlayer {
|
|
|
504
729
|
func handleSeekCompleted(to seconds: Double, didFinish: Bool) {
|
|
505
730
|
if loadSeekCoordinator.seekDidComplete(on: avPlayer, delegate: self), state == .loading {
|
|
506
731
|
coordinator.handleSeekCompleted(to: seconds, didFinish: didFinish)
|
|
507
|
-
} else {
|
|
508
|
-
// Not a load-seek, just update now playing
|
|
509
|
-
nowPlayingUpdater.setCurrentTime(seconds: seconds)
|
|
510
732
|
}
|
|
511
733
|
callbacks?.playerDidCompleteSeek(position: seconds, didFinish: didFinish)
|
|
512
734
|
}
|
|
513
735
|
}
|
|
514
736
|
|
|
737
|
+
// MARK: - Playback State Persistence
|
|
738
|
+
|
|
739
|
+
extension TrackPlayer {
|
|
740
|
+
/// Snapshot the current player state to UserDefaults so a cold-start resume
|
|
741
|
+
/// can restore it without the JS runtime. Live streams persist `positionMs = nil`.
|
|
742
|
+
private func persistPlaybackState() {
|
|
743
|
+
guard let track = currentTrack else { return }
|
|
744
|
+
// At .ended the position equals the duration — persisting it would make a
|
|
745
|
+
// cold-start resume seek to the end and instantly re-end (Android twin:
|
|
746
|
+
// savePositionZero).
|
|
747
|
+
let positionMs: Double? =
|
|
748
|
+
(track.live == true) ? nil : (state == .ended ? 0 : currentTime * 1000)
|
|
749
|
+
playbackStateStore.save(
|
|
750
|
+
PersistedPlaybackState(
|
|
751
|
+
track: JsonTrack(from: track),
|
|
752
|
+
positionMs: positionMs,
|
|
753
|
+
repeatMode: repeatMode.persistedString,
|
|
754
|
+
shuffleEnabled: shuffleEnabled,
|
|
755
|
+
playbackSpeed: rate,
|
|
756
|
+
)
|
|
757
|
+
)
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/// Start a 5 s repeating save while playback is active. A previous task is
|
|
761
|
+
/// cancelled first so there is never more than one running at a time.
|
|
762
|
+
private func startPeriodicSave() {
|
|
763
|
+
periodicSaveTask?.cancel()
|
|
764
|
+
periodicSaveTask = Task { @MainActor [weak self] in
|
|
765
|
+
while !Task.isCancelled {
|
|
766
|
+
try? await Task.sleep(nanoseconds: 5_000_000_000)
|
|
767
|
+
guard !Task.isCancelled else { return }
|
|
768
|
+
self?.persistPlaybackState()
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
private func stopPeriodicSave() {
|
|
774
|
+
periodicSaveTask?.cancel()
|
|
775
|
+
periodicSaveTask = nil
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
private extension RepeatMode {
|
|
780
|
+
/// String representation stored in `PersistedPlaybackState.repeatMode`.
|
|
781
|
+
var persistedString: String {
|
|
782
|
+
switch self {
|
|
783
|
+
case .off: "off"
|
|
784
|
+
case .track: "track"
|
|
785
|
+
case .queue: "queue"
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
515
790
|
// MARK: - PlaybackEffectHandler
|
|
516
791
|
|
|
517
792
|
extension TrackPlayer: PlaybackEffectHandler {
|
|
@@ -527,12 +802,20 @@ extension TrackPlayer: PlaybackEffectHandler {
|
|
|
527
802
|
stopObservingAVPlayerItem()
|
|
528
803
|
}
|
|
529
804
|
|
|
530
|
-
func loadTrack(src: String) {
|
|
531
|
-
|
|
805
|
+
func loadTrack(src: String, track: Track) {
|
|
806
|
+
didPrimeNowPlayingElection = false
|
|
807
|
+
// A new track starts unproven: its failures get the short first-connect
|
|
808
|
+
// budget until it renders audio. Reloads of the current track (retry,
|
|
809
|
+
// play-from-error) deliberately keep the flag.
|
|
810
|
+
retryManager.hasPlayed = false
|
|
811
|
+
mediaLoader.resolveAndLoad(src: src, track: track)
|
|
532
812
|
}
|
|
533
813
|
|
|
534
814
|
func reloadTrack(startFromCurrentTime: Bool) {
|
|
535
|
-
|
|
815
|
+
// Re-resolve rather than replay the cached URL: play-from-.error typically happens long
|
|
816
|
+
// after the failure (an expired signed URL would just re-fail, often non-retryably),
|
|
817
|
+
// matching every other retry path (retry, network restore, media-services reset).
|
|
818
|
+
reloadResolving(startFromCurrentTime: startFromCurrentTime)
|
|
536
819
|
}
|
|
537
820
|
|
|
538
821
|
func unloadTrack() {
|
|
@@ -553,37 +836,25 @@ extension TrackPlayer: PlaybackEffectHandler {
|
|
|
553
836
|
}
|
|
554
837
|
}
|
|
555
838
|
|
|
556
|
-
func updateNowPlayingValues(duration: Double, rate: Float, currentTime: Double) {
|
|
557
|
-
nowPlayingUpdater.updatePlaybackValues(duration: duration, rate: rate, currentTime: currentTime)
|
|
558
|
-
}
|
|
559
|
-
|
|
560
839
|
func updateNowPlayingState(playWhenReady: Bool) {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
MediaItemProperty.duration(nil),
|
|
569
|
-
NowPlayingInfoProperty.playbackRate(nil),
|
|
570
|
-
NowPlayingInfoProperty.elapsedPlaybackTime(nil),
|
|
571
|
-
])
|
|
572
|
-
nowPlayingUpdater.loadMetaValues(for: track, rate: rate)
|
|
840
|
+
nowPlayingInfoController.setPlaybackState(playing: playWhenReady)
|
|
841
|
+
if playWhenReady {
|
|
842
|
+
startPeriodicSave()
|
|
843
|
+
} else {
|
|
844
|
+
stopPeriodicSave()
|
|
845
|
+
persistPlaybackState()
|
|
846
|
+
}
|
|
573
847
|
}
|
|
574
848
|
|
|
575
|
-
func
|
|
576
|
-
|
|
849
|
+
func loadNowPlayingMetadata(for track: Track) {
|
|
850
|
+
nowPlayingUpdater.loadMetaValues(for: track)
|
|
851
|
+
persistPlaybackState()
|
|
577
852
|
}
|
|
578
853
|
|
|
579
854
|
func clearNowPlaying() {
|
|
580
855
|
nowPlayingInfoController.clear()
|
|
581
856
|
}
|
|
582
857
|
|
|
583
|
-
func setNowPlayingCurrentTime(seconds: Double) {
|
|
584
|
-
nowPlayingUpdater.setCurrentTime(seconds: seconds)
|
|
585
|
-
}
|
|
586
|
-
|
|
587
858
|
func updateRemoteRepeatMode(_ mode: RepeatMode) {
|
|
588
859
|
remoteCommandController.updateRepeatMode(mode)
|
|
589
860
|
}
|
|
@@ -591,6 +862,10 @@ extension TrackPlayer: PlaybackEffectHandler {
|
|
|
591
862
|
func updateRemoteShuffleMode(_ enabled: Bool) {
|
|
592
863
|
remoteCommandController.updateShuffleMode(enabled)
|
|
593
864
|
}
|
|
865
|
+
|
|
866
|
+
func updateSkipAvailability(canNext: Bool, canPrevious: Bool) {
|
|
867
|
+
remoteCommandController.setSkipAvailability(canNext: canNext, canPrevious: canPrevious)
|
|
868
|
+
}
|
|
594
869
|
}
|
|
595
870
|
|
|
596
871
|
// MARK: - SeekCompletionHandler
|
|
@@ -608,8 +883,20 @@ extension TrackPlayer {
|
|
|
608
883
|
coordinator.replace(index, track)
|
|
609
884
|
}
|
|
610
885
|
|
|
611
|
-
func setQueue(
|
|
612
|
-
|
|
886
|
+
func setQueue(
|
|
887
|
+
_ newTracks: [Track],
|
|
888
|
+
initialIndex: Int = 0,
|
|
889
|
+
startPositionMs: Double? = nil,
|
|
890
|
+
playWhenReady: Bool? = nil,
|
|
891
|
+
sourcePath: String? = nil,
|
|
892
|
+
) {
|
|
893
|
+
coordinator.setQueue(
|
|
894
|
+
newTracks,
|
|
895
|
+
initialIndex: initialIndex,
|
|
896
|
+
startPositionMs: startPositionMs,
|
|
897
|
+
playWhenReady: playWhenReady,
|
|
898
|
+
sourcePath: sourcePath,
|
|
899
|
+
)
|
|
613
900
|
}
|
|
614
901
|
|
|
615
902
|
func add(_ tracks: [Track], initialIndex: Int? = nil, playWhenReady: Bool? = nil) {
|
|
@@ -666,14 +953,50 @@ extension TrackPlayer: MediaLoaderDelegate {
|
|
|
666
953
|
}
|
|
667
954
|
|
|
668
955
|
func mediaLoaderDidFailWithRetryableError(_ error: Error) {
|
|
956
|
+
attachPublishingCarrierItemIfNeeded()
|
|
957
|
+
primeNowPlayingElectionIfNeeded()
|
|
669
958
|
coordinator.errorHandler.handleError(error, context: .mediaLoad)
|
|
670
959
|
}
|
|
671
960
|
|
|
672
961
|
func mediaLoaderDidFailWithUnplayableTrack() {
|
|
962
|
+
attachPublishingCarrierItemIfNeeded()
|
|
963
|
+
primeNowPlayingElectionIfNeeded()
|
|
673
964
|
transition(.errorOccurred(.trackWasUnplayable))
|
|
674
965
|
}
|
|
675
966
|
|
|
967
|
+
/// `MPNowPlayingSession` publishes only through the linked player's current item, so
|
|
968
|
+
/// a load that fails before item creation (a dead host on a cold start) leaves the
|
|
969
|
+
/// player item-less: the system never surfaces the app on the lock screen / CarPlay
|
|
970
|
+
/// — no metadata, no transport buttons — and the failure line has nowhere to appear.
|
|
971
|
+
/// Attach the failed asset's item purely as a publishing carrier. Deliberately not
|
|
972
|
+
/// observed: its `.failed` status must not re-report the error the loader already
|
|
973
|
+
/// delivered. A successful load (retry, or the next track) replaces it with the
|
|
974
|
+
/// real, observed item via `mediaLoaderDidPrepareItem`; retry reloads leave it in
|
|
975
|
+
/// place (`prepareForReload` drops only the asset), so the surface doesn't flicker.
|
|
976
|
+
private func attachPublishingCarrierItemIfNeeded() {
|
|
977
|
+
guard avPlayer.currentItem == nil, let asset = mediaLoader.asset else { return }
|
|
978
|
+
logger.notice("Attaching publishing-carrier item for failed load")
|
|
979
|
+
let item = AVPlayerItem(asset: asset)
|
|
980
|
+
nowPlayingInfoController.prepareItem(item)
|
|
981
|
+
avPlayer.replaceCurrentItem(with: item)
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/// A failed load renders no audio, and without rendered audio iOS never elects the
|
|
985
|
+
/// app onto the system now-playing surfaces — the published failure metadata and
|
|
986
|
+
/// transport controls stay invisible (see `SilentAudioPrimer`). On the first
|
|
987
|
+
/// failure of a play-intended load, render a silence burst to claim the surface.
|
|
988
|
+
/// Once per load: the retry loop re-fails every few seconds, and one burst either
|
|
989
|
+
/// elected us or never will. Does not touch the retry loop itself.
|
|
990
|
+
private func primeNowPlayingElectionIfNeeded() {
|
|
991
|
+
guard playWhenReady, !didPrimeNowPlayingElection else { return }
|
|
992
|
+
didPrimeNowPlayingElection = true
|
|
993
|
+
silentAudioPrimer.prime()
|
|
994
|
+
}
|
|
995
|
+
|
|
676
996
|
func mediaLoaderDidFailWithError(_ error: TrackPlayerError.PlaybackError) {
|
|
997
|
+
// No carrier here: an invalid/missing src never produced an asset. The
|
|
998
|
+
// direct-center publish still carries the metadata once elected.
|
|
999
|
+
primeNowPlayingElectionIfNeeded()
|
|
677
1000
|
transition(.errorOccurred(error))
|
|
678
1001
|
}
|
|
679
1002
|
|
|
@@ -689,4 +1012,3 @@ extension TrackPlayer: MediaLoaderDelegate {
|
|
|
689
1012
|
callbacks?.playerDidReceiveTimedMetadata(groups)
|
|
690
1013
|
}
|
|
691
1014
|
}
|
|
692
|
-
|