react-native-audio-browser 0.1.1 → 0.2.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AudioBrowser.podspec +1 -1
- package/README.md +180 -2
- package/android/build.gradle +10 -0
- package/android/gradle.properties +1 -1
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +401 -141
- package/android/src/main/java/com/audiobrowser/Callbacks.kt +4 -6
- package/android/src/main/java/com/audiobrowser/Service.kt +67 -18
- package/android/src/main/java/com/audiobrowser/browser/ArtworkResolutionRegistry.kt +37 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowseArtworkRegistry.kt +34 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +443 -178
- package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +300 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonArtwork.kt +79 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +41 -4
- package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +43 -0
- package/android/src/main/java/com/audiobrowser/browser/TrackLoadHandler.kt +4 -4
- package/android/src/main/java/com/audiobrowser/extension/ResolvedTrackExt.kt +35 -0
- package/android/src/main/java/com/audiobrowser/http/RequestConfigBuilder.kt +109 -97
- package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +6 -10
- package/android/src/main/java/com/audiobrowser/model/PlayerSetupOptions.kt +40 -8
- package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +31 -37
- package/android/src/main/java/com/audiobrowser/player/AutomaticBufferManager.kt +4 -1
- package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +119 -0
- package/android/src/main/java/com/audiobrowser/player/DynamicLoadControl.kt +18 -1
- package/android/src/main/java/com/audiobrowser/player/EqualizerController.kt +153 -0
- package/android/src/main/java/com/audiobrowser/player/InterceptingPlayer.kt +141 -0
- package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +15 -3
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +415 -131
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +154 -276
- package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +348 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackErrorClassifier.kt +129 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateMachine.kt +85 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +27 -5
- package/android/src/main/java/com/audiobrowser/player/PlaybackTimer.kt +56 -0
- package/android/src/main/java/com/audiobrowser/player/Player.kt +452 -576
- package/android/src/main/java/com/audiobrowser/player/PlayerCapabilitiesExt.kt +20 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerEngineFactory.kt +130 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +190 -67
- package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +117 -53
- package/android/src/main/java/com/audiobrowser/player/SleepTimer.kt +37 -3
- package/android/src/main/java/com/audiobrowser/player/SleepTimerManager.kt +80 -0
- package/android/src/main/java/com/audiobrowser/player/StuckRecoveryPolicy.kt +50 -0
- package/android/src/main/java/com/audiobrowser/player/TransformingDataSource.kt +84 -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 +28 -10
- package/ios/Player/NowPlayingUpdater.swift +119 -26
- package/ios/Player/PersistedPlaybackState.swift +11 -0
- package/ios/Player/PlaybackCoordinator.swift +282 -51
- package/ios/Player/PlaybackCoordinatorCallbacks.swift +6 -1
- package/ios/Player/PlaybackEffectHandler.swift +19 -9
- package/ios/Player/PlaybackErrorHandler.swift +97 -13
- package/ios/Player/PlaybackStateMachine.swift +18 -13
- package/ios/Player/PlaybackStateStore.swift +27 -0
- package/ios/Player/PlaybackTimer.swift +61 -0
- package/ios/Player/PlayingStateManager.swift +3 -2
- package/ios/Player/QueueManager.swift +67 -61
- package/ios/Player/RetryManager.swift +97 -21
- package/ios/Player/SleepTimerHandling.swift +8 -0
- package/ios/Player/SleepTimerManager.swift +38 -5
- package/ios/Player/VolumeFader.swift +77 -0
- package/ios/RemoteCommand/RemoteCommandController.swift +31 -15
- package/ios/Tests/AirPlayStallJudgementTests.swift +52 -0
- package/ios/Tests/BrowserPathHelperTests.swift +28 -0
- package/ios/Tests/CarPlayArtworkResolverTests.swift +39 -39
- package/ios/Tests/ChapterMetadataAVFoundationTests.swift +2 -2
- package/ios/Tests/EndOfTrackJudgementTests.swift +35 -0
- package/ios/Tests/JsonModelsTests.swift +58 -0
- package/ios/Tests/LoadSeekCoordinatorTests.swift +38 -7
- package/ios/Tests/MediaIntentCriteriaTests.swift +170 -0
- package/ios/Tests/MediaLoaderAssetOptionsTests.swift +46 -0
- package/ios/Tests/MediaLoaderTests.swift +23 -8
- package/ios/Tests/MediaResolveTests.swift +126 -0
- package/ios/Tests/OnceValueTests.swift +79 -0
- package/ios/Tests/PlaybackCoordinatorTests.swift +784 -13
- package/ios/Tests/PlaybackErrorHandlerTests.swift +380 -46
- package/ios/Tests/PlaybackStateMachineTests.swift +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 +104 -0
- package/ios/Tests/Support/TestTypes.swift +61 -20
- package/ios/Tests/TabBarEntriesTests.swift +71 -0
- package/ios/Tests/TrackSelectorTests.swift +15 -15
- package/ios/TrackPlayer.swift +380 -58
- package/ios/TrackPlayerCallbacks.swift +0 -6
- package/ios/TrackSelector.swift +5 -5
- package/ios/Util/ArtworkImageFetcher.swift +4 -2
- package/ios/Util/NetworkMonitor.swift +7 -3
- package/ios/Util/OnceValue.swift +34 -0
- package/lib/commonjs/features/browser-config.js +227 -0
- package/lib/commonjs/features/browser-config.js.map +1 -0
- package/lib/commonjs/features/browser.js +59 -158
- package/lib/commonjs/features/browser.js.map +1 -1
- package/lib/commonjs/features/carConnection.js +42 -0
- package/lib/commonjs/features/carConnection.js.map +1 -0
- package/lib/commonjs/features/errors.js +34 -2
- package/lib/commonjs/features/errors.js.map +1 -1
- package/lib/commonjs/features/gate.js +149 -0
- package/lib/commonjs/features/gate.js.map +1 -0
- package/lib/commonjs/features/index.js +22 -0
- package/lib/commonjs/features/index.js.map +1 -1
- package/lib/commonjs/features/metadata.js.map +1 -1
- package/lib/commonjs/features/nowPlaying.js +35 -0
- package/lib/commonjs/features/nowPlaying.js.map +1 -1
- package/lib/commonjs/features/output.js +37 -23
- package/lib/commonjs/features/output.js.map +1 -1
- package/lib/commonjs/features/playback/controls.js +9 -0
- package/lib/commonjs/features/playback/controls.js.map +1 -1
- package/lib/commonjs/features/playback/index.js +11 -0
- package/lib/commonjs/features/playback/index.js.map +1 -1
- package/lib/commonjs/features/playback/progress.js +28 -12
- package/lib/commonjs/features/playback/progress.js.map +1 -1
- package/lib/commonjs/features/playback/trackPlaybackTime.js +92 -0
- package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -0
- package/lib/commonjs/features/playback/volume.js +1 -1
- package/lib/commonjs/features/player/options.js +49 -13
- package/lib/commonjs/features/player/options.js.map +1 -1
- package/lib/commonjs/features/player/setup.js +249 -3
- package/lib/commonjs/features/player/setup.js.map +1 -1
- package/lib/commonjs/features/queue/queue.js +10 -3
- package/lib/commonjs/features/queue/queue.js.map +1 -1
- package/lib/commonjs/features/remoteControls.js +1 -12
- package/lib/commonjs/features/remoteControls.js.map +1 -1
- package/lib/commonjs/features/sleepTimer.js +9 -4
- package/lib/commonjs/features/sleepTimer.js.map +1 -1
- package/lib/commonjs/native.js +5 -0
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/native.web.js +4 -1
- package/lib/commonjs/native.web.js.map +1 -1
- package/lib/commonjs/utils/LazyNativeEmitter.js +0 -3
- package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/commonjs/utils/NativeUpdatedValue.js +0 -3
- package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/commonjs/utils/artwork.js +31 -0
- package/lib/commonjs/utils/artwork.js.map +1 -0
- package/lib/commonjs/web/NativeAudioBrowser.js +301 -124
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +71 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js +34 -0
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Player.js +90 -26
- package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +21 -0
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/QueueManager.js +273 -0
- package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +158 -0
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js +34 -3
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js +75 -0
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/index.js +13 -5
- package/lib/commonjs/web/TrackPlayer/index.js.map +1 -1
- package/lib/commonjs/web/browser/BrowserManager.js +176 -50
- package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js +3 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/commonjs/web/browser/SearchManager.js +11 -9
- package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
- package/lib/commonjs/web/browser/assertBrowsePageShape.js +22 -0
- package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +1 -0
- package/lib/commonjs/web/browser/classifyTrackNavigation.js +41 -0
- package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +1 -0
- package/lib/commonjs/web/browser/parseSearchResponse.js +20 -0
- package/lib/commonjs/web/browser/parseSearchResponse.js.map +1 -0
- package/lib/commonjs/web/http/HttpClient.js +4 -23
- package/lib/commonjs/web/http/HttpClient.js.map +1 -1
- package/lib/commonjs/web/http/RequestConfigBuilder.js +107 -58
- package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/commonjs/web/playbackErrorKind.js +57 -0
- package/lib/commonjs/web/playbackErrorKind.js.map +1 -0
- package/lib/commonjs/web/player/MediaSessionManager.js +121 -0
- package/lib/commonjs/web/player/MediaSessionManager.js.map +1 -0
- package/lib/commonjs/web/player/NowPlayingManager.js +6 -5
- package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
- package/lib/commonjs/web/player/OptionsManager.js +9 -17
- package/lib/commonjs/web/player/OptionsManager.js.map +1 -1
- package/lib/commonjs/web/player/RemoteCommandController.js +96 -0
- package/lib/commonjs/web/player/RemoteCommandController.js.map +1 -0
- package/lib/module/features/browser-config.js +221 -0
- package/lib/module/features/browser-config.js.map +1 -0
- package/lib/module/features/browser.js +53 -156
- package/lib/module/features/browser.js.map +1 -1
- package/lib/module/features/carConnection.js +37 -0
- package/lib/module/features/carConnection.js.map +1 -0
- package/lib/module/features/errors.js +34 -2
- package/lib/module/features/errors.js.map +1 -1
- package/lib/module/features/gate.js +144 -0
- package/lib/module/features/gate.js.map +1 -0
- package/lib/module/features/index.js +2 -0
- package/lib/module/features/index.js.map +1 -1
- package/lib/module/features/metadata.js.map +1 -1
- package/lib/module/features/nowPlaying.js +33 -0
- package/lib/module/features/nowPlaying.js.map +1 -1
- package/lib/module/features/output.js +32 -19
- package/lib/module/features/output.js.map +1 -1
- package/lib/module/features/playback/controls.js +8 -0
- package/lib/module/features/playback/controls.js.map +1 -1
- package/lib/module/features/playback/index.js +1 -0
- package/lib/module/features/playback/index.js.map +1 -1
- package/lib/module/features/playback/progress.js +28 -12
- package/lib/module/features/playback/progress.js.map +1 -1
- package/lib/module/features/playback/trackPlaybackTime.js +88 -0
- package/lib/module/features/playback/trackPlaybackTime.js.map +1 -0
- package/lib/module/features/playback/volume.js +1 -1
- package/lib/module/features/player/options.js +48 -13
- package/lib/module/features/player/options.js.map +1 -1
- package/lib/module/features/player/setup.js +249 -3
- package/lib/module/features/player/setup.js.map +1 -1
- package/lib/module/features/queue/queue.js +10 -3
- package/lib/module/features/queue/queue.js.map +1 -1
- package/lib/module/features/remoteControls.js +0 -11
- package/lib/module/features/remoteControls.js.map +1 -1
- package/lib/module/features/sleepTimer.js +9 -4
- package/lib/module/features/sleepTimer.js.map +1 -1
- package/lib/module/native.js +5 -0
- package/lib/module/native.js.map +1 -1
- package/lib/module/native.web.js +4 -1
- package/lib/module/native.web.js.map +1 -1
- package/lib/module/utils/LazyNativeEmitter.js +0 -3
- package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/module/utils/NativeUpdatedValue.js +0 -3
- package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/module/utils/artwork.js +26 -0
- package/lib/module/utils/artwork.js.map +1 -0
- package/lib/module/web/NativeAudioBrowser.js +302 -125
- package/lib/module/web/NativeAudioBrowser.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +67 -0
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
- package/lib/module/web/TrackPlayer/PlaybackTimer.js +29 -0
- package/lib/module/web/TrackPlayer/PlaybackTimer.js.map +1 -0
- package/lib/module/web/TrackPlayer/Player.js +90 -26
- package/lib/module/web/TrackPlayer/Player.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js +17 -0
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
- package/lib/module/web/TrackPlayer/QueueManager.js +269 -0
- package/lib/module/web/TrackPlayer/QueueManager.js.map +1 -0
- package/lib/module/web/TrackPlayer/QueuePlayer.js +154 -0
- package/lib/module/web/TrackPlayer/QueuePlayer.js.map +1 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/module/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/module/web/TrackPlayer/SleepTimer.js +34 -3
- package/lib/module/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/module/web/TrackPlayer/VolumeFader.js +70 -0
- package/lib/module/web/TrackPlayer/VolumeFader.js.map +1 -0
- package/lib/module/web/TrackPlayer/index.js +2 -1
- package/lib/module/web/TrackPlayer/index.js.map +1 -1
- package/lib/module/web/browser/BrowserManager.js +176 -50
- package/lib/module/web/browser/BrowserManager.js.map +1 -1
- package/lib/module/web/browser/NavigationErrorManager.js +3 -1
- package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/module/web/browser/SearchManager.js +11 -9
- package/lib/module/web/browser/SearchManager.js.map +1 -1
- package/lib/module/web/browser/assertBrowsePageShape.js +18 -0
- package/lib/module/web/browser/assertBrowsePageShape.js.map +1 -0
- package/lib/module/web/browser/classifyTrackNavigation.js +38 -0
- package/lib/module/web/browser/classifyTrackNavigation.js.map +1 -0
- package/lib/module/web/browser/parseSearchResponse.js +16 -0
- package/lib/module/web/browser/parseSearchResponse.js.map +1 -0
- package/lib/module/web/http/HttpClient.js +4 -23
- package/lib/module/web/http/HttpClient.js.map +1 -1
- package/lib/module/web/http/RequestConfigBuilder.js +107 -58
- package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/module/web/playbackErrorKind.js +52 -0
- package/lib/module/web/playbackErrorKind.js.map +1 -0
- package/lib/module/web/player/MediaSessionManager.js +116 -0
- package/lib/module/web/player/MediaSessionManager.js.map +1 -0
- package/lib/module/web/player/NowPlayingManager.js +7 -5
- package/lib/module/web/player/NowPlayingManager.js.map +1 -1
- package/lib/module/web/player/OptionsManager.js +9 -17
- package/lib/module/web/player/OptionsManager.js.map +1 -1
- package/lib/module/web/player/RemoteCommandController.js +92 -0
- package/lib/module/web/player/RemoteCommandController.js.map +1 -0
- package/lib/typescript/src/features/browser-config.d.ts +12 -0
- package/lib/typescript/src/features/browser-config.d.ts.map +1 -0
- package/lib/typescript/src/features/browser.d.ts +40 -1
- package/lib/typescript/src/features/browser.d.ts.map +1 -1
- package/lib/typescript/src/features/carConnection.d.ts +20 -0
- package/lib/typescript/src/features/carConnection.d.ts.map +1 -0
- package/lib/typescript/src/features/errors.d.ts +58 -3
- package/lib/typescript/src/features/errors.d.ts.map +1 -1
- package/lib/typescript/src/features/gate.d.ts +77 -0
- package/lib/typescript/src/features/gate.d.ts.map +1 -0
- package/lib/typescript/src/features/index.d.ts +2 -0
- package/lib/typescript/src/features/index.d.ts.map +1 -1
- package/lib/typescript/src/features/metadata.d.ts +6 -4
- package/lib/typescript/src/features/metadata.d.ts.map +1 -1
- package/lib/typescript/src/features/nowPlaying.d.ts +27 -0
- package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -1
- package/lib/typescript/src/features/output.d.ts +28 -18
- package/lib/typescript/src/features/output.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/controls.d.ts +5 -0
- package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/index.d.ts +1 -0
- package/lib/typescript/src/features/playback/index.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/progress.d.ts +3 -0
- package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +34 -0
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/volume.d.ts +1 -1
- package/lib/typescript/src/features/player/options.d.ts +92 -93
- package/lib/typescript/src/features/player/options.d.ts.map +1 -1
- package/lib/typescript/src/features/player/setup.d.ts +206 -167
- package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
- package/lib/typescript/src/features/queue/queue.d.ts +9 -2
- package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
- package/lib/typescript/src/features/remoteControls.d.ts +0 -13
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
- package/lib/typescript/src/features/sleepTimer.d.ts +18 -3
- package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native.d.ts +1 -2
- package/lib/typescript/src/native.d.ts.map +1 -1
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts +17 -225
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-native.d.ts +9 -3
- package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-nodes.d.ts +145 -13
- package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
- package/lib/typescript/src/types/browser.d.ts +349 -85
- package/lib/typescript/src/types/browser.d.ts.map +1 -1
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +0 -2
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +0 -2
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
- package/lib/typescript/src/utils/artwork.d.ts +19 -0
- package/lib/typescript/src/utils/artwork.d.ts.map +1 -0
- package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -1
- package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +3 -1
- package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +24 -10
- package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +6 -6
- package/nitrogen/generated/android/c++/JAndroidOptions.hpp +1 -11
- package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +33 -1
- package/nitrogen/generated/android/c++/JArtworkVariants.hpp +61 -0
- package/nitrogen/generated/android/c++/JBrowseResult.hpp +5 -0
- package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +3 -3
- package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +58 -0
- package/nitrogen/generated/android/c++/JFavoritesMatchMode.hpp +58 -0
- package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +100 -0
- package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +3 -2
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.hpp +112 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +121 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +123 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +133 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +121 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.hpp +139 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.hpp +134 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +8 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +131 -0
- package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_GateEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +0 -10
- package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +9 -4
- package/nitrogen/generated/android/c++/JFunc_void_Output.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +10 -10
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +6 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +6 -0
- package/nitrogen/generated/android/c++/JGate.hpp +62 -0
- package/nitrogen/generated/android/c++/JGateDecision.hpp +64 -0
- package/nitrogen/generated/android/c++/{JThumbsRating.hpp → JGateEvent.hpp} +16 -15
- package/nitrogen/generated/android/c++/JGateReason.hpp +58 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +236 -212
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +25 -22
- package/nitrogen/generated/android/c++/JIOSOptions.hpp +95 -0
- package/nitrogen/generated/android/c++/JImageRowItem.hpp +33 -3
- package/nitrogen/generated/android/c++/JMediaReference.hpp +58 -0
- package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +33 -1
- package/nitrogen/generated/android/c++/{JPartialAndroidSetupPlayerOptions.hpp → JNativeAndroidSetupOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +61 -28
- package/nitrogen/generated/android/c++/JNativeGateRequest.hpp +74 -0
- package/nitrogen/generated/android/c++/{JPartialIOSSetupPlayerOptions.hpp → JNativeIOSSetupOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +20 -9
- package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +182 -0
- package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +16 -19
- package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +6 -0
- package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +1 -11
- package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +96 -0
- package/nitrogen/generated/android/c++/JNotificationButton.hpp +3 -3
- package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +3 -17
- package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +7 -3
- package/nitrogen/generated/android/c++/JOptions.hpp +14 -9
- package/nitrogen/generated/android/c++/{JIosOutput.hpp → JOutput.hpp} +15 -15
- package/nitrogen/generated/android/c++/JOutputType.hpp +82 -0
- package/nitrogen/generated/android/c++/JPlayback.hpp +2 -0
- package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JPlaybackError.hpp +18 -3
- package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +2 -0
- package/nitrogen/generated/android/c++/JPlaybackErrorKind.hpp +76 -0
- package/nitrogen/generated/android/c++/JPlaybackState.hpp +3 -3
- package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +11 -5
- package/nitrogen/generated/android/c++/JResolvedTrack.hpp +23 -5
- package/nitrogen/generated/android/c++/JRetryConfig.hpp +11 -7
- package/nitrogen/generated/android/c++/JSearchMode.hpp +27 -9
- package/nitrogen/generated/android/c++/JSearchParams.hpp +9 -3
- package/nitrogen/generated/android/c++/JStallReason.hpp +58 -0
- package/nitrogen/generated/android/c++/JTrack.hpp +23 -5
- package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +6 -0
- package/nitrogen/generated/android/c++/JTrackRequest.hpp +93 -0
- package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +14 -1
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +71 -0
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.cpp +41 -0
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +121 -0
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.hpp +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioContentType.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +2 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +10 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkVariants.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayNowPlayingButton.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{ThumbsRating.kt → FavoriteConfig.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RatingType.kt → FavoritesMatchMode.kt} +5 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNowPlayingParams.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___Track.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_std__string____Track.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.kt → Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_RemoteSetRatingEvent.kt → Func_void_GateEvent.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_IosOutput.kt → Func_void_Output.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{HeartRating.kt → Gate.kt} +9 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PercentageRating.kt → GateDecision.kt} +9 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{StarRating.kt → GateEvent.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateReason.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +103 -109
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +24 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaReference.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +10 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialAndroidSetupPlayerOptions.kt → NativeAndroidSetupOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +18 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RemoteSetRatingEvent.kt → NativeGateRequest.kt} +12 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialIOSSetupPlayerOptions.kt → NativeIOSSetupOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeSetupPlayerOptions.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorType.kt +3 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +2 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButton.kt +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +3 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{IosOutput.kt → Output.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/OutputType.kt +31 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorKind.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackState.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +7 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchMode.kt +12 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StallReason.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackRequest.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +7 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_String_ArtworkVariants.kt +53 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +139 -28
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +1098 -447
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +60 -39
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +170 -112
- package/nitrogen/generated/ios/swift/AndroidAudioContentType.swift +8 -8
- package/nitrogen/generated/ios/swift/AndroidOptions.swift +2 -12
- package/nitrogen/generated/ios/swift/ArtworkRequestConfig.swift +95 -1
- package/nitrogen/generated/ios/swift/ArtworkVariants.swift +34 -0
- package/nitrogen/generated/ios/swift/CarPlayNowPlayingButton.swift +4 -4
- package/nitrogen/generated/ios/swift/FavoriteConfig.swift +29 -0
- package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +40 -0
- package/nitrogen/generated/ios/swift/FormatNowPlayingParams.swift +67 -0
- package/nitrogen/generated/ios/swift/FormattedNavigationError.swift +17 -4
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.swift +69 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___Track.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.swift +60 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_std__string____Track.swift +60 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.swift +77 -0
- package/nitrogen/generated/ios/swift/Func_void_GateDecision.swift +46 -0
- package/nitrogen/generated/ios/swift/{Func_void_RemoteSetRatingEvent.swift → Func_void_GateEvent.swift} +10 -10
- package/nitrogen/generated/ios/swift/{Func_void_IosOutput.swift → Func_void_Output.swift} +10 -10
- package/nitrogen/generated/ios/swift/Func_void_TransformableRequestConfig.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +5 -5
- package/nitrogen/generated/ios/swift/Func_void_std__optional_NowPlayingUpdate_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +53 -0
- package/nitrogen/generated/ios/swift/{Func_void_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError___.swift → Func_void_std__shared_ptr_Promise_GateDecision__.swift} +17 -17
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_TransformableRequestConfig__.swift +66 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError____.swift +81 -0
- package/nitrogen/generated/ios/swift/Gate.swift +47 -0
- package/nitrogen/generated/ios/swift/GateDecision.swift +40 -0
- package/nitrogen/generated/ios/swift/GateEvent.swift +29 -0
- package/nitrogen/generated/ios/swift/GateReason.swift +40 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +20 -14
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +230 -197
- package/nitrogen/generated/ios/swift/IOSOptions.swift +51 -0
- package/nitrogen/generated/ios/swift/ImageRowItem.swift +121 -2
- package/nitrogen/generated/ios/swift/MediaReference.swift +40 -0
- package/nitrogen/generated/ios/swift/MediaRequestConfig.swift +107 -1
- package/nitrogen/generated/ios/swift/{PartialAndroidSetupPlayerOptions.swift → NativeAndroidSetupOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +161 -22
- package/nitrogen/generated/ios/swift/NativeGateRequest.swift +58 -0
- package/nitrogen/generated/ios/swift/{PartialIOSSetupPlayerOptions.swift → NativeIOSSetupOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/NativeRouteEntry.swift +19 -19
- package/nitrogen/generated/ios/swift/NativeSetupPlayerOptions.swift +206 -0
- package/nitrogen/generated/ios/swift/NativeUpdateOptions.swift +12 -25
- package/nitrogen/generated/ios/swift/NavigationErrorType.swift +8 -0
- package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +1 -30
- package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +90 -0
- package/nitrogen/generated/ios/swift/NotificationButton.swift +4 -4
- package/nitrogen/generated/ios/swift/NowPlayingMetadata.swift +1 -48
- package/nitrogen/generated/ios/swift/NowPlayingUpdate.swift +19 -1
- package/nitrogen/generated/ios/swift/Options.swift +10 -4
- package/nitrogen/generated/ios/swift/{IosOutput.swift → Output.swift} +7 -7
- package/nitrogen/generated/ios/swift/OutputType.swift +72 -0
- package/nitrogen/generated/ios/swift/PlaybackError.swift +43 -2
- package/nitrogen/generated/ios/swift/PlaybackErrorKind.swift +64 -0
- package/nitrogen/generated/ios/swift/PlaybackState.swift +4 -4
- package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +27 -8
- package/nitrogen/generated/ios/swift/ResolvedTrack.swift +74 -8
- package/nitrogen/generated/ios/swift/RetryConfig.swift +35 -4
- package/nitrogen/generated/ios/swift/SearchMode.swift +36 -12
- package/nitrogen/generated/ios/swift/SearchParams.swift +7 -2
- package/nitrogen/generated/ios/swift/StallReason.swift +40 -0
- package/nitrogen/generated/ios/swift/Track.swift +74 -8
- package/nitrogen/generated/ios/swift/TrackRequest.swift +106 -0
- package/nitrogen/generated/ios/swift/TransformableRequestConfig.swift +60 -1
- package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.swift +19 -0
- package/nitrogen/generated/ios/swift/Variant_String_ArtworkVariants.swift +18 -0
- package/nitrogen/generated/shared/c++/AndroidAudioContentType.hpp +10 -10
- package/nitrogen/generated/shared/c++/AndroidOptions.hpp +1 -12
- package/nitrogen/generated/shared/c++/ArtworkRequestConfig.hpp +10 -2
- package/nitrogen/generated/shared/c++/ArtworkVariants.hpp +87 -0
- package/nitrogen/generated/shared/c++/CarPlayNowPlayingButton.hpp +6 -6
- package/nitrogen/generated/shared/c++/EqualizerSettings.hpp +0 -2
- package/nitrogen/generated/shared/c++/{StarRating.hpp → FavoriteConfig.hpp} +18 -17
- package/nitrogen/generated/shared/c++/FavoritesMatchMode.hpp +76 -0
- package/nitrogen/generated/shared/c++/FormatNowPlayingParams.hpp +110 -0
- package/nitrogen/generated/shared/c++/FormattedNavigationError.hpp +6 -5
- package/nitrogen/generated/shared/c++/{HeartRating.hpp → Gate.hpp} +21 -16
- package/nitrogen/generated/shared/c++/{ThumbsRating.hpp → GateDecision.hpp} +23 -17
- package/nitrogen/generated/shared/c++/{PercentageRating.hpp → GateEvent.hpp} +18 -17
- package/nitrogen/generated/shared/c++/GateReason.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +21 -18
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +44 -35
- package/nitrogen/generated/shared/c++/IOSOptions.hpp +91 -0
- package/nitrogen/generated/shared/c++/ImageRowItem.hpp +33 -2
- package/nitrogen/generated/shared/c++/MediaReference.hpp +76 -0
- package/nitrogen/generated/shared/c++/MediaRequestConfig.hpp +10 -2
- package/nitrogen/generated/shared/c++/{PartialAndroidSetupPlayerOptions.hpp → NativeAndroidSetupOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +31 -15
- package/nitrogen/generated/shared/c++/NativeGateRequest.hpp +97 -0
- package/nitrogen/generated/shared/c++/{PartialIOSSetupPlayerOptions.hpp → NativeIOSSetupOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/NativeRouteEntry.hpp +5 -5
- package/nitrogen/generated/shared/c++/NativeSetupPlayerOptions.hpp +138 -0
- package/nitrogen/generated/shared/c++/NativeUpdateOptions.hpp +9 -7
- package/nitrogen/generated/shared/c++/NavigationErrorType.hpp +8 -0
- package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +1 -12
- package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +92 -0
- package/nitrogen/generated/shared/c++/NotificationButton.hpp +8 -8
- package/nitrogen/generated/shared/c++/NowPlayingMetadata.hpp +3 -19
- package/nitrogen/generated/shared/c++/NowPlayingUpdate.hpp +6 -2
- package/nitrogen/generated/shared/c++/Options.hpp +8 -8
- package/nitrogen/generated/shared/c++/{IosOutput.hpp → Output.hpp} +18 -18
- package/nitrogen/generated/shared/c++/OutputType.hpp +108 -0
- package/nitrogen/generated/shared/c++/PlaybackError.hpp +18 -3
- package/nitrogen/generated/shared/c++/PlaybackErrorKind.hpp +100 -0
- package/nitrogen/generated/shared/c++/PlaybackState.hpp +9 -9
- package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +9 -6
- package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +24 -5
- package/nitrogen/generated/shared/c++/RetryConfig.hpp +10 -6
- package/nitrogen/generated/shared/c++/SearchMode.hpp +39 -15
- package/nitrogen/generated/shared/c++/SearchParams.hpp +9 -2
- package/nitrogen/generated/shared/c++/StallReason.hpp +76 -0
- package/nitrogen/generated/shared/c++/Track.hpp +24 -5
- package/nitrogen/generated/shared/c++/TrackRequest.hpp +93 -0
- package/nitrogen/generated/shared/c++/TransformableRequestConfig.hpp +6 -2
- package/package.json +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
|
@@ -2,48 +2,28 @@ import AVFoundation
|
|
|
2
2
|
import Foundation
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
Observes
|
|
5
|
+
Observes the player's audio-start boundary and invokes the callback passed at initialization.
|
|
6
6
|
*/
|
|
7
7
|
@MainActor class PlayerTimeObserver {
|
|
8
8
|
/// The time to use as start boundary time. Cannot be zero.
|
|
9
9
|
private static let startBoundaryTime: CMTime = .init(value: 1, timescale: 1000)
|
|
10
10
|
|
|
11
11
|
var boundaryTimeStartObserverToken: Any?
|
|
12
|
-
var periodicTimeObserverToken: Any?
|
|
13
12
|
|
|
14
13
|
weak var avPlayer: AVPlayer? {
|
|
15
14
|
willSet {
|
|
16
15
|
unregisterForBoundaryTimeEvents()
|
|
17
|
-
unregisterForPeriodicEvents()
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/// The frequency to receive periodic time events.
|
|
22
|
-
/// Setting this to a new value will trigger a re-registering to the periodic events of the
|
|
23
|
-
/// player.
|
|
24
|
-
var periodicObserverTimeInterval: CMTime {
|
|
25
|
-
didSet {
|
|
26
|
-
if oldValue != periodicObserverTimeInterval {
|
|
27
|
-
registerForPeriodicTimeEvents()
|
|
28
|
-
}
|
|
29
16
|
}
|
|
30
17
|
}
|
|
31
18
|
|
|
32
19
|
private let onAudioDidStart: @MainActor () -> Void
|
|
33
|
-
private let onSecondElapsed: @MainActor (Double) -> Void
|
|
34
20
|
|
|
35
|
-
init(
|
|
36
|
-
periodicObserverTimeInterval: CMTime,
|
|
37
|
-
onAudioDidStart: @escaping @MainActor () -> Void,
|
|
38
|
-
onSecondElapsed: @escaping @MainActor (Double) -> Void,
|
|
39
|
-
) {
|
|
40
|
-
self.periodicObserverTimeInterval = periodicObserverTimeInterval
|
|
21
|
+
init(onAudioDidStart: @escaping @MainActor () -> Void) {
|
|
41
22
|
self.onAudioDidStart = onAudioDidStart
|
|
42
|
-
self.onSecondElapsed = onSecondElapsed
|
|
43
23
|
}
|
|
44
24
|
|
|
45
25
|
/**
|
|
46
|
-
Will register for the AVPlayer BoundaryTimeEvents, to trigger start
|
|
26
|
+
Will register for the AVPlayer BoundaryTimeEvents, to trigger the audio-start event.
|
|
47
27
|
*/
|
|
48
28
|
func registerForBoundaryTimeEvents() {
|
|
49
29
|
guard let avPlayer else {
|
|
@@ -72,34 +52,4 @@ import Foundation
|
|
|
72
52
|
avPlayer.removeTimeObserver(boundaryTimeStartObserverToken)
|
|
73
53
|
self.boundaryTimeStartObserverToken = nil
|
|
74
54
|
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
Start observing periodic time events.
|
|
78
|
-
Will trigger unregisterForPeriodicEvents() first to avoid multiple subscriptions.
|
|
79
|
-
*/
|
|
80
|
-
func registerForPeriodicTimeEvents() {
|
|
81
|
-
guard let avPlayer else {
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
unregisterForPeriodicEvents()
|
|
85
|
-
periodicTimeObserverToken = avPlayer.addPeriodicTimeObserver(
|
|
86
|
-
forInterval: periodicObserverTimeInterval,
|
|
87
|
-
queue: nil,
|
|
88
|
-
using: { [weak self] time in
|
|
89
|
-
let seconds = time.seconds
|
|
90
|
-
Task { @MainActor in self?.onSecondElapsed(seconds) }
|
|
91
|
-
},
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
Unregister for periodic events.
|
|
97
|
-
*/
|
|
98
|
-
func unregisterForPeriodicEvents() {
|
|
99
|
-
guard let avPlayer, let periodicTimeObserverToken else {
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
avPlayer.removeTimeObserver(periodicTimeObserverToken)
|
|
103
|
-
self.periodicTimeObserverToken = nil
|
|
104
|
-
}
|
|
105
55
|
}
|
|
@@ -31,11 +31,7 @@ enum SessionCategoryPolicy: String {
|
|
|
31
31
|
case .longFormAudio:
|
|
32
32
|
.longFormAudio
|
|
33
33
|
case .longFormVideo:
|
|
34
|
-
|
|
35
|
-
.longFormVideo
|
|
36
|
-
} else {
|
|
37
|
-
.longFormAudio
|
|
38
|
-
}
|
|
34
|
+
.longFormVideo
|
|
39
35
|
}
|
|
40
36
|
}
|
|
41
37
|
}
|
|
@@ -63,12 +59,7 @@ enum SessionCategoryMode: String {
|
|
|
63
59
|
case .voiceChat:
|
|
64
60
|
.voiceChat
|
|
65
61
|
case .voicePrompt:
|
|
66
|
-
|
|
67
|
-
.voicePrompt
|
|
68
|
-
} else {
|
|
69
|
-
// Do Nothing
|
|
70
|
-
.default
|
|
71
|
-
}
|
|
62
|
+
.voicePrompt
|
|
72
63
|
}
|
|
73
64
|
}
|
|
74
65
|
}
|
|
@@ -98,3 +89,34 @@ enum SessionCategoryOptions: String {
|
|
|
98
89
|
}
|
|
99
90
|
}
|
|
100
91
|
}
|
|
92
|
+
|
|
93
|
+
extension NativeIOSSetupOptions {
|
|
94
|
+
/// The resolved `AVAudioSession` category configuration from the iOS setup options. Each field
|
|
95
|
+
/// falls back to a playback default when it's absent or unrecognised, so a consumer's
|
|
96
|
+
/// `categoryOptions` (e.g. `allowBluetooth` / `allowAirPlay`), `mode`, and route `policy` are
|
|
97
|
+
/// actually honoured at setup instead of being dropped.
|
|
98
|
+
func resolveAudioSessionConfig() -> (
|
|
99
|
+
category: AVAudioSession.Category,
|
|
100
|
+
mode: AVAudioSession.Mode,
|
|
101
|
+
policy: AVAudioSession.RouteSharingPolicy,
|
|
102
|
+
options: AVAudioSession.CategoryOptions
|
|
103
|
+
) {
|
|
104
|
+
let category = self.category
|
|
105
|
+
.flatMap { SessionCategory(rawValue: $0.stringValue) }?
|
|
106
|
+
.mapConfigToAVAudioSessionCategory() ?? .playback
|
|
107
|
+
let mode = self.categoryMode
|
|
108
|
+
.flatMap { SessionCategoryMode(rawValue: $0.stringValue) }?
|
|
109
|
+
.mapConfigToAVAudioSessionCategoryMode() ?? .default
|
|
110
|
+
let policy = self.categoryPolicy
|
|
111
|
+
.flatMap { SessionCategoryPolicy(rawValue: $0.stringValue) }?
|
|
112
|
+
.toRouteSharingPolicy() ?? .default
|
|
113
|
+
let options = (self.categoryOptions ?? [])
|
|
114
|
+
.reduce(into: AVAudioSession.CategoryOptions()) { acc, option in
|
|
115
|
+
if let mapped = SessionCategoryOptions(rawValue: option.stringValue)?
|
|
116
|
+
.mapConfigToAVAudioSessionCategoryOptions() {
|
|
117
|
+
acc.insert(mapped)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return (category, mode, policy, options)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// Pure decision for the AirPlay "silently stuck" recovery, kept free of
|
|
2
|
+
/// AVFoundation so it can be unit-tested off-device.
|
|
3
|
+
///
|
|
4
|
+
/// Over AirPlay, AVPlayer can drop `.waitingToPlayAtSpecifiedRate` (reason
|
|
5
|
+
/// `.noItemToPlay`) → `.paused` while the app still intends to play, leaving
|
|
6
|
+
/// playback stuck/silent with no error. Re-issuing `play()` on exactly that
|
|
7
|
+
/// transition recovers it. Scoped narrowly to AirPlay so it never nudges a
|
|
8
|
+
/// legitimate pause on the local route.
|
|
9
|
+
struct AirPlayStallJudgement {
|
|
10
|
+
let previous: PlayerTimeControlStatus?
|
|
11
|
+
let current: PlayerTimeControlStatus
|
|
12
|
+
/// Whether the previous waiting state's reason was specifically
|
|
13
|
+
/// `.noItemToPlay` (the AirPlay-stall signature, not a normal rebuffer).
|
|
14
|
+
let previousWaitingReasonWasNoItemToPlay: Bool
|
|
15
|
+
let isAirPlay: Bool
|
|
16
|
+
let playWhenReady: Bool
|
|
17
|
+
|
|
18
|
+
var shouldNudge: Bool {
|
|
19
|
+
isAirPlay
|
|
20
|
+
&& playWhenReady
|
|
21
|
+
&& current == .paused
|
|
22
|
+
&& previous == .waitingToPlayAtSpecifiedRate
|
|
23
|
+
&& previousWaitingReasonWasNoItemToPlay
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// Whether an `AVPlayerItemDidPlayToEndTime` notification represents a genuine
|
|
4
|
+
/// end of the track, or a stall masquerading as one.
|
|
5
|
+
enum EndOfTrackOutcome: Equatable {
|
|
6
|
+
/// Genuine end — advance the queue / complete.
|
|
7
|
+
case ended
|
|
8
|
+
/// Not a real end (a dropped live stream, or a mid-stream buffer exhaustion
|
|
9
|
+
/// reported as EOF) — recover instead of advancing.
|
|
10
|
+
case stalled
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/// Pure decision for how to treat an end-of-item notification, kept free of
|
|
14
|
+
/// AVFoundation so it can be unit-tested off-device. iOS surfaces a dropped
|
|
15
|
+
/// connection on a live stream — and sometimes a mid-stream buffer underrun —
|
|
16
|
+
/// as a "played to end", which would otherwise stop the station or skip the
|
|
17
|
+
/// track.
|
|
18
|
+
struct EndOfTrackJudgement {
|
|
19
|
+
let isLive: Bool
|
|
20
|
+
let currentTime: Double
|
|
21
|
+
let duration: Double
|
|
22
|
+
|
|
23
|
+
var outcome: EndOfTrackOutcome {
|
|
24
|
+
// Live streams are infinite; an end-of-item here is a dropped connection.
|
|
25
|
+
if isLive { return .stalled }
|
|
26
|
+
// Indefinite/unknown duration — can't validate the position, trust iOS.
|
|
27
|
+
guard duration.isFinite, duration > 0 else { return .ended }
|
|
28
|
+
// More than 5% short of the end → a stall reported as EOF, not a real finish.
|
|
29
|
+
if currentTime + duration * 0.05 < duration { return .stalled }
|
|
30
|
+
return .ended
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -17,6 +17,17 @@ final class LoadSeekCoordinator {
|
|
|
17
17
|
private let logger = Logger(subsystem: "com.audiobrowser", category: "LoadSeekCoordinator")
|
|
18
18
|
private(set) var state: State = .idle
|
|
19
19
|
|
|
20
|
+
/// Identifies the item epoch a seek was issued against. `reset()` (called on
|
|
21
|
+
/// track/queue changes) bumps it, so the completion of a seek issued against
|
|
22
|
+
/// the previous item can recognize itself as stale and be dropped — a
|
|
23
|
+
/// cancelled cross-item completion arriving after the new track's start
|
|
24
|
+
/// position was captured would otherwise consume or prematurely resolve it.
|
|
25
|
+
private(set) var generation = 0
|
|
26
|
+
|
|
27
|
+
func isCurrentGeneration(_ generation: Int) -> Bool {
|
|
28
|
+
generation == self.generation
|
|
29
|
+
}
|
|
30
|
+
|
|
20
31
|
/// Used by `seekBy()` to offset from the deferred position.
|
|
21
32
|
var pendingTime: TimeInterval? {
|
|
22
33
|
switch state {
|
|
@@ -49,9 +60,12 @@ final class LoadSeekCoordinator {
|
|
|
49
60
|
state = .seekInFlight(time: time)
|
|
50
61
|
|
|
51
62
|
let cmTime = CMTime(seconds: time, preferredTimescale: 1000)
|
|
63
|
+
let generation = generation
|
|
52
64
|
player
|
|
53
|
-
.seek(to: cmTime, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) {
|
|
65
|
+
.seek(to: cmTime, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) {
|
|
66
|
+
[weak self] finished in
|
|
54
67
|
Task { @MainActor in
|
|
68
|
+
guard let self, self.isCurrentGeneration(generation) else { return }
|
|
55
69
|
delegate?.handleSeekCompleted(to: time, didFinish: finished)
|
|
56
70
|
}
|
|
57
71
|
}
|
|
@@ -80,5 +94,6 @@ final class LoadSeekCoordinator {
|
|
|
80
94
|
|
|
81
95
|
func reset() {
|
|
82
96
|
state = .idle
|
|
97
|
+
generation += 1
|
|
83
98
|
}
|
|
84
99
|
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// Normalized "what did the user ask to play", derived from a media intent.
|
|
4
|
+
/// Deliberately free of `Intents` types so the core (`HybridAudioBrowser`)
|
|
5
|
+
/// never imports the Intents framework — the mapping lives in the
|
|
6
|
+
/// `Intents`-aware `RNABMediaIntentHandler`.
|
|
7
|
+
public struct MediaIntentCriteria: Sendable {
|
|
8
|
+
/// Media-reference axis (mirrors `INMediaReference`). `currentlyPlaying`
|
|
9
|
+
/// routes to native resume and never reaches the consumer; `my` routes to
|
|
10
|
+
/// the search source; `unknown` is the default.
|
|
11
|
+
public enum Reference: Sendable { case my, currentlyPlaying, unknown }
|
|
12
|
+
|
|
13
|
+
let query: String
|
|
14
|
+
let reference: Reference
|
|
15
|
+
let hasGenres: Bool
|
|
16
|
+
let hasMediaType: Bool
|
|
17
|
+
/// True when `query` is effectively the host app's own name. Siri turns
|
|
18
|
+
/// "Play «app»" into a search for a word in the app name — e.g. "Play Radio
|
|
19
|
+
/// Garden" arrives as mediaName "Garden" (+ radio mediaType). That's an
|
|
20
|
+
/// app-open/resume, not a station search.
|
|
21
|
+
let matchesAppName: Bool
|
|
22
|
+
|
|
23
|
+
// Structured search payload, mirroring the shared `SearchParams`. Plain
|
|
24
|
+
// Sendable strings so this type stays in the unit-testable target; the Nitro
|
|
25
|
+
// `SearchParams` is assembled in the funnel.
|
|
26
|
+
/// The container-vertical `SearchMode` name, or nil. Comes ONLY from the
|
|
27
|
+
/// intent's media type — never derived from which filter field is set.
|
|
28
|
+
let searchMode: String?
|
|
29
|
+
let genre: String?
|
|
30
|
+
let artist: String?
|
|
31
|
+
let album: String?
|
|
32
|
+
let title: String?
|
|
33
|
+
let playlist: String?
|
|
34
|
+
|
|
35
|
+
init(
|
|
36
|
+
query: String,
|
|
37
|
+
reference: Reference,
|
|
38
|
+
hasGenres: Bool,
|
|
39
|
+
hasMediaType: Bool,
|
|
40
|
+
matchesAppName: Bool,
|
|
41
|
+
searchMode: String? = nil,
|
|
42
|
+
genre: String? = nil,
|
|
43
|
+
artist: String? = nil,
|
|
44
|
+
album: String? = nil,
|
|
45
|
+
title: String? = nil,
|
|
46
|
+
playlist: String? = nil
|
|
47
|
+
) {
|
|
48
|
+
self.query = query
|
|
49
|
+
self.reference = reference
|
|
50
|
+
self.hasGenres = hasGenres
|
|
51
|
+
self.hasMediaType = hasMediaType
|
|
52
|
+
self.matchesAppName = matchesAppName
|
|
53
|
+
self.searchMode = searchMode
|
|
54
|
+
self.genre = genre
|
|
55
|
+
self.artist = artist
|
|
56
|
+
self.album = album
|
|
57
|
+
self.title = title
|
|
58
|
+
self.playlist = playlist
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/// Resume vs search, by reference:
|
|
62
|
+
/// - `currentlyPlaying` → always resume ("play this" plays the active track)
|
|
63
|
+
/// - `my` → always search ("play my favorites" goes to the consumer)
|
|
64
|
+
/// - `unknown` → the no-criteria / app-name heuristic
|
|
65
|
+
var isResume: Bool {
|
|
66
|
+
switch reference {
|
|
67
|
+
case .currentlyPlaying: return true
|
|
68
|
+
case .my: return false
|
|
69
|
+
case .unknown:
|
|
70
|
+
let q = query.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
71
|
+
// "Play «app»": no search term and no other filter → resume.
|
|
72
|
+
if q.isEmpty { return !hasGenres && !hasMediaType }
|
|
73
|
+
// "Play «app-name»": resume — unless a real filter signals a search.
|
|
74
|
+
return matchesAppName && !hasGenres
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// Builds criteria from the raw fields of a media-search intent. Pure (no
|
|
79
|
+
/// `Intents`/`Bundle` dependency) so the whole Siri-phrase → search decision
|
|
80
|
+
/// is unit-testable.
|
|
81
|
+
///
|
|
82
|
+
/// `mediaTypeMode` is the already-collapsed `SearchMode` string for the
|
|
83
|
+
/// intent's container vertical (e.g. "station"/"podcast"/"song"), or nil for
|
|
84
|
+
/// a filter-only / unclassified type. `reference` is the mapped axis.
|
|
85
|
+
static func from(
|
|
86
|
+
mediaName: String?,
|
|
87
|
+
genreNames: [String],
|
|
88
|
+
artistName: String?,
|
|
89
|
+
albumName: String?,
|
|
90
|
+
mediaTypeMode: String?,
|
|
91
|
+
reference: Reference,
|
|
92
|
+
hasMediaType: Bool,
|
|
93
|
+
appName: String?
|
|
94
|
+
) -> MediaIntentCriteria {
|
|
95
|
+
let name = (mediaName ?? "").trimmingCharacters(in: .whitespacesAndNewlines)
|
|
96
|
+
let trimmedNonEmpty: (String?) -> String? = {
|
|
97
|
+
let t = ($0 ?? "").trimmingCharacters(in: .whitespacesAndNewlines)
|
|
98
|
+
return t.isEmpty ? nil : t
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let genre = genreNames.isEmpty ? nil : genreNames.joined(separator: " ")
|
|
102
|
+
let artist = trimmedNonEmpty(artistName)
|
|
103
|
+
let album = trimmedNonEmpty(albumName)
|
|
104
|
+
// song/playlist carry their spoken name into a dedicated field.
|
|
105
|
+
let title = mediaTypeMode == "song" ? (name.isEmpty ? nil : name) : nil
|
|
106
|
+
let playlist = mediaTypeMode == "playlist" ? (name.isEmpty ? nil : name) : nil
|
|
107
|
+
|
|
108
|
+
// `query` is always populated so search works even before the API honours
|
|
109
|
+
// `mode`: prefer the spoken name, else fall back to a structured value.
|
|
110
|
+
let query = name.isEmpty ? (genre ?? artist ?? album ?? title ?? playlist ?? "") : name
|
|
111
|
+
|
|
112
|
+
return MediaIntentCriteria(
|
|
113
|
+
query: query,
|
|
114
|
+
reference: reference,
|
|
115
|
+
hasGenres: !genreNames.isEmpty,
|
|
116
|
+
hasMediaType: hasMediaType,
|
|
117
|
+
matchesAppName: queryMatchesAppName(query, appName: appName),
|
|
118
|
+
searchMode: mediaTypeMode, // mode is the vertical, verbatim — no derivation
|
|
119
|
+
genre: genre,
|
|
120
|
+
artist: artist,
|
|
121
|
+
album: album,
|
|
122
|
+
title: title,
|
|
123
|
+
playlist: playlist
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// Whether `query` is effectively the host app's own name. Case- and
|
|
128
|
+
/// diacritic-insensitive.
|
|
129
|
+
private static func queryMatchesAppName(_ query: String, appName: String?) -> Bool {
|
|
130
|
+
guard let appName else { return false }
|
|
131
|
+
let normalize: (String) -> String = {
|
|
132
|
+
$0.folding(options: [.diacriticInsensitive, .caseInsensitive], locale: nil)
|
|
133
|
+
.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
134
|
+
}
|
|
135
|
+
let q = normalize(query), a = normalize(appName)
|
|
136
|
+
guard !q.isEmpty, !a.isEmpty else { return false }
|
|
137
|
+
return a.contains(q) || q.contains(a)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -12,7 +12,10 @@ struct MediaResolvedUrl {
|
|
|
12
12
|
final class MediaLoader {
|
|
13
13
|
private let logger = Logger(subsystem: "com.audiobrowser", category: "MediaLoader")
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
/// Resolves a playback src into a concrete URL + headers/user-agent.
|
|
16
|
+
/// The `Track` is threaded through so the resolver can invoke the
|
|
17
|
+
/// consumer-supplied `media.resolve(track)` as the final media layer.
|
|
18
|
+
var mediaUrlResolver: ((String, Track?) async -> MediaResolvedUrl)?
|
|
16
19
|
|
|
17
20
|
/// Internal access so TrackPlayer can read it for observer guards.
|
|
18
21
|
private(set) var asset: AVURLAsset?
|
|
@@ -30,7 +33,7 @@ final class MediaLoader {
|
|
|
30
33
|
|
|
31
34
|
// MARK: - Public API
|
|
32
35
|
|
|
33
|
-
func resolveAndLoad(src: String) {
|
|
36
|
+
func resolveAndLoad(src: String, track: Track? = nil) {
|
|
34
37
|
if let resolver = mediaUrlResolver {
|
|
35
38
|
mediaResolverTask?.cancel()
|
|
36
39
|
mediaResolverTask = Task {
|
|
@@ -42,7 +45,7 @@ final class MediaLoader {
|
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
self.logger.debug("resolveAndLoad: calling resolver...")
|
|
45
|
-
let resolved = await resolver(src)
|
|
48
|
+
let resolved = await resolver(src, track)
|
|
46
49
|
|
|
47
50
|
guard !Task.isCancelled else {
|
|
48
51
|
self.logger.debug("resolveAndLoad: cancelled after resolver returned")
|
|
@@ -72,7 +75,12 @@ final class MediaLoader {
|
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
func loadAsset() {
|
|
75
|
-
guard let url else {
|
|
78
|
+
guard let url else {
|
|
79
|
+
// Callers (reload-from-terminal) have already transitioned to .loading;
|
|
80
|
+
// a silent return would strand that state with no load in flight.
|
|
81
|
+
delegate?.mediaLoaderDidFailWithError(.invalidSourceUrl("nil"))
|
|
82
|
+
return
|
|
83
|
+
}
|
|
76
84
|
let pendingAsset = AVURLAsset(url: url, options: urlOptions)
|
|
77
85
|
asset = pendingAsset
|
|
78
86
|
|
|
@@ -171,6 +179,21 @@ final class MediaLoader {
|
|
|
171
179
|
asset = nil
|
|
172
180
|
}
|
|
173
181
|
|
|
182
|
+
/// Builds AVURLAsset options, merging any explicit headers with a resolved
|
|
183
|
+
/// User-Agent. An explicit `User-Agent` in `headers` wins (mirrors the artwork
|
|
184
|
+
/// path in BrowserManager+URLResolution). A nil/empty userAgent contributes
|
|
185
|
+
/// nothing, so "no UA configured" still falls through to AVPlayer's default.
|
|
186
|
+
nonisolated static func buildAssetOptions(
|
|
187
|
+
headers: [String: String]?,
|
|
188
|
+
userAgent: String?,
|
|
189
|
+
) -> [String: Any]? {
|
|
190
|
+
var merged = headers ?? [:]
|
|
191
|
+
if let userAgent, !userAgent.isEmpty, merged["User-Agent"] == nil {
|
|
192
|
+
merged["User-Agent"] = userAgent
|
|
193
|
+
}
|
|
194
|
+
return merged.isEmpty ? nil : ["AVURLAssetHTTPHeaderFieldsKey": merged]
|
|
195
|
+
}
|
|
196
|
+
|
|
174
197
|
// MARK: - Private
|
|
175
198
|
|
|
176
199
|
private func loadWithResolvedUrl(_ resolved: MediaResolvedUrl) {
|
|
@@ -180,14 +203,9 @@ final class MediaLoader {
|
|
|
180
203
|
return
|
|
181
204
|
}
|
|
182
205
|
|
|
183
|
-
var options: [String: Any] = [:]
|
|
184
|
-
if let headers = resolved.headers, !headers.isEmpty {
|
|
185
|
-
options["AVURLAssetHTTPHeaderFieldsKey"] = headers
|
|
186
|
-
}
|
|
187
|
-
|
|
188
206
|
let isLocalFile = mediaUrl.isFileURL
|
|
189
207
|
url = isLocalFile ? URL(fileURLWithPath: mediaUrl.path) : mediaUrl
|
|
190
|
-
urlOptions =
|
|
208
|
+
urlOptions = Self.buildAssetOptions(headers: resolved.headers, userAgent: resolved.userAgent)
|
|
191
209
|
|
|
192
210
|
logger.debug(" final playbackUrl: \(mediaUrl.absoluteString)")
|
|
193
211
|
logger.debug(" isLocalFile: \(isLocalFile)")
|
|
@@ -3,59 +3,153 @@ import MediaPlayer
|
|
|
3
3
|
import NitroModules
|
|
4
4
|
import os.log
|
|
5
5
|
|
|
6
|
-
///
|
|
7
|
-
///
|
|
6
|
+
/// Owns the now-playing surface: publishes a track's static fields + artwork, and renders the
|
|
7
|
+
/// title/artist line — the formatter's result, or the track/override default. The single writer of
|
|
8
|
+
/// the title/artist fields, with a publish-dedupe so the frequent re-renders stay cheap.
|
|
9
|
+
///
|
|
10
|
+
/// Does not exclusively own NowPlayingInfoController -- other callers (e.g. HybridAudioBrowser for
|
|
11
|
+
/// overrides) can still access it directly.
|
|
8
12
|
@MainActor
|
|
9
13
|
final class NowPlayingUpdater {
|
|
10
14
|
private let logger = Logger(subsystem: "com.audiobrowser", category: "NowPlayingUpdater")
|
|
11
15
|
private let nowPlayingInfoController: NowPlayingInfoController
|
|
12
16
|
|
|
13
17
|
var artworkUrlResolver: ((Track, ImageContext?) async -> ImageSource?)?
|
|
18
|
+
/// Invoked when the published title/artist actually change, so the owner can emit the JS
|
|
19
|
+
/// `onNowPlayingChanged` event (which it shapes with elapsed time / artwork / etc.).
|
|
20
|
+
var onChanged: (@MainActor (_ track: Track, _ title: String, _ artist: String?, _ album: String?) -> Void)?
|
|
14
21
|
|
|
15
22
|
private var artworkLoadTask: Task<Void, Never>?
|
|
16
23
|
private var artworkGeneration: UInt = 0
|
|
17
24
|
|
|
25
|
+
/// Last published text lines, to dedupe redundant writes (render runs on every transition).
|
|
26
|
+
private struct Published: Equatable {
|
|
27
|
+
let trackId: String?
|
|
28
|
+
let title: String?
|
|
29
|
+
let artist: String?
|
|
30
|
+
let album: String?
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private var lastPublished: Published?
|
|
34
|
+
|
|
35
|
+
/// Bumped on every `render`; an async formatter result applies only if its render is still the
|
|
36
|
+
/// latest (latest-render-wins — drops a result whose track skipped or whose state moved on while
|
|
37
|
+
/// the formatter was in flight).
|
|
38
|
+
private var renderGeneration: UInt = 0
|
|
39
|
+
|
|
18
40
|
init(nowPlayingInfoController: NowPlayingInfoController) {
|
|
19
41
|
self.nowPlayingInfoController = nowPlayingInfoController
|
|
20
42
|
}
|
|
21
43
|
|
|
22
|
-
|
|
44
|
+
/// Publishes the static, per-track fields + artwork on a track change. The title/artist/album
|
|
45
|
+
/// lines are owned by `render` (routed through `applyFields` here so it dedupes against later
|
|
46
|
+
/// renders).
|
|
47
|
+
func loadMetaValues(for track: Track) {
|
|
23
48
|
nowPlayingInfoController.set(keyValues: [
|
|
24
|
-
MediaItemProperty.artist(track.artist),
|
|
25
|
-
MediaItemProperty.title(track.title),
|
|
26
|
-
MediaItemProperty.albumTitle(track.album),
|
|
27
|
-
NowPlayingInfoProperty.playbackRate(Double(rate)),
|
|
28
49
|
NowPlayingInfoProperty.isLiveStream(track.live),
|
|
29
50
|
])
|
|
51
|
+
applyFields(track: track, title: track.title, artist: track.artist, album: track.album)
|
|
30
52
|
loadArtwork(for: track)
|
|
31
53
|
}
|
|
32
54
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
/// Renders the now-playing text lines (title, artist, album): the default (`override ?? track`)
|
|
56
|
+
/// immediately, then — when a formatter is configured — its async result overlaid (each field
|
|
57
|
+
/// falling back to the default). A `flash` (transient line, e.g. feedback for a refused remote
|
|
58
|
+
/// command) outranks both: while one is active the formatter pass is skipped entirely, so its
|
|
59
|
+
/// async result can't land on top. Safe to call on every playback transition; redundant writes
|
|
60
|
+
/// are deduped.
|
|
61
|
+
func render(
|
|
62
|
+
track: Track,
|
|
63
|
+
timedMetadata: TimedMetadata?,
|
|
64
|
+
playWhenReady: Bool,
|
|
65
|
+
stalled: StallReason?,
|
|
66
|
+
error: PlaybackError?,
|
|
67
|
+
flash: NowPlayingUpdate? = nil,
|
|
68
|
+
override: NowPlayingUpdate?,
|
|
69
|
+
formatter: ((_ params: FormatNowPlayingParams) -> Promise<NowPlayingUpdate?>)?,
|
|
70
|
+
) {
|
|
71
|
+
renderGeneration &+= 1
|
|
72
|
+
let generation = renderGeneration
|
|
73
|
+
|
|
74
|
+
let defaultTitle = override?.title ?? track.title
|
|
75
|
+
let defaultSecondary = override?.artist ?? track.artist
|
|
76
|
+
let defaultAlbum = override?.album ?? track.album
|
|
77
|
+
|
|
78
|
+
if let flash {
|
|
79
|
+
applyFields(
|
|
80
|
+
track: track,
|
|
81
|
+
title: flash.title ?? defaultTitle,
|
|
82
|
+
artist: flash.artist ?? defaultSecondary,
|
|
83
|
+
album: flash.album ?? defaultAlbum,
|
|
84
|
+
)
|
|
85
|
+
return
|
|
86
|
+
}
|
|
41
87
|
|
|
42
|
-
|
|
43
|
-
func updatePlaybackState(playWhenReady: Bool) {
|
|
44
|
-
let state: MPNowPlayingPlaybackState = playWhenReady ? .playing : .paused
|
|
45
|
-
logger.debug("updatePlaybackState: \(state.rawValue) (playWhenReady=\(playWhenReady))")
|
|
46
|
-
nowPlayingInfoController.setPlaybackState(state)
|
|
47
|
-
}
|
|
88
|
+
applyFields(track: track, title: defaultTitle, artist: defaultSecondary, album: defaultAlbum)
|
|
48
89
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
90
|
+
guard let formatter else { return }
|
|
91
|
+
let params = FormatNowPlayingParams(
|
|
92
|
+
track: track,
|
|
93
|
+
timedMetadata: timedMetadata,
|
|
94
|
+
playWhenReady: playWhenReady,
|
|
95
|
+
stalled: stalled,
|
|
96
|
+
error: error,
|
|
52
97
|
)
|
|
98
|
+
// `@Sendable` breaks the @MainActor isolation inheritance: Nitro resolves the promise on the JS
|
|
99
|
+
// thread, so the resolver must NOT be main-isolated (a main-isolated closure run off-main traps
|
|
100
|
+
// in `_swift_task_checkIsolated`). Hop back to the main actor to apply (same pattern as the
|
|
101
|
+
// artwork callback below).
|
|
102
|
+
formatter(params)
|
|
103
|
+
.then { @Sendable [weak self] formatted in
|
|
104
|
+
guard let self, let formatted else { return }
|
|
105
|
+
Task { @MainActor in
|
|
106
|
+
// Apply only if no newer render has superseded this one (fast skip / state moved on).
|
|
107
|
+
guard self.renderGeneration == generation else { return }
|
|
108
|
+
self.applyFields(
|
|
109
|
+
track: track,
|
|
110
|
+
title: formatted.title ?? defaultTitle,
|
|
111
|
+
artist: formatted.artist ?? defaultSecondary,
|
|
112
|
+
album: formatted.album ?? defaultAlbum,
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
.catch { @Sendable [weak self] error in
|
|
117
|
+
let message = error.localizedDescription
|
|
118
|
+
Task { @MainActor in
|
|
119
|
+
self?.logger.error("nowPlayingMetadataFormatter failed: \(message)")
|
|
120
|
+
}
|
|
121
|
+
}
|
|
53
122
|
}
|
|
54
123
|
|
|
55
124
|
// MARK: - Private
|
|
56
125
|
|
|
126
|
+
/// Stamps the title/artist/album (each falling back to the track's own) onto
|
|
127
|
+
/// NowPlayingInfoCenter, deduped against the last publish, and notifies `onChanged`.
|
|
128
|
+
private func applyFields(track: Track, title: String?, artist: String?, album: String?) {
|
|
129
|
+
let resolvedTitle = title ?? track.title
|
|
130
|
+
let resolvedArtist = artist ?? track.artist
|
|
131
|
+
let resolvedAlbum = album ?? track.album
|
|
132
|
+
let published = Published(
|
|
133
|
+
trackId: track.src ?? track.url,
|
|
134
|
+
title: resolvedTitle,
|
|
135
|
+
artist: resolvedArtist,
|
|
136
|
+
album: resolvedAlbum,
|
|
137
|
+
)
|
|
138
|
+
guard published != lastPublished else { return }
|
|
139
|
+
lastPublished = published
|
|
140
|
+
|
|
141
|
+
nowPlayingInfoController.set(keyValues: [
|
|
142
|
+
MediaItemProperty.title(resolvedTitle),
|
|
143
|
+
MediaItemProperty.artist(resolvedArtist),
|
|
144
|
+
MediaItemProperty.albumTitle(resolvedAlbum),
|
|
145
|
+
])
|
|
146
|
+
onChanged?(track, resolvedTitle, resolvedArtist, resolvedAlbum)
|
|
147
|
+
}
|
|
148
|
+
|
|
57
149
|
private func loadArtwork(for track: Track) {
|
|
58
|
-
|
|
150
|
+
// Now-playing is a single image with no appearance to key off, so a pair
|
|
151
|
+
// collapses to its dark URL (see `Variant_String_ArtworkVariants.url`).
|
|
152
|
+
let artworkUrl = track.artworkSource?.uri ?? track.artwork?.url
|
|
59
153
|
logger.debug("loadArtwork: \(track.title), artworkUrl: \(artworkUrl ?? "nil")")
|
|
60
154
|
|
|
61
155
|
// Now Playing artwork: use screen width in pixels, capped at 1200px
|
|
@@ -102,5 +196,4 @@ final class NowPlayingUpdater {
|
|
|
102
196
|
}
|
|
103
197
|
}
|
|
104
198
|
}
|
|
105
|
-
|
|
106
199
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// A serialisable snapshot of the player's resumable state. Mirrors Android's
|
|
4
|
+
/// `PlaybackStateStore.PersistedState`. `positionMs` is `nil` for live streams.
|
|
5
|
+
struct PersistedPlaybackState: Codable {
|
|
6
|
+
let track: JsonTrack
|
|
7
|
+
let positionMs: Double?
|
|
8
|
+
let repeatMode: String
|
|
9
|
+
let shuffleEnabled: Bool
|
|
10
|
+
let playbackSpeed: Float
|
|
11
|
+
}
|