@5stones/react-native-audio-browser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AudioBrowser.podspec +43 -0
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +210 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +36 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +1191 -0
- package/android/src/main/java/com/audiobrowser/AudioBrowserPackage.kt +21 -0
- package/android/src/main/java/com/audiobrowser/Callbacks.kt +92 -0
- package/android/src/main/java/com/audiobrowser/HeadlessTaskService.kt +59 -0
- package/android/src/main/java/com/audiobrowser/Service.kt +336 -0
- package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +1169 -0
- package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +103 -0
- package/android/src/main/java/com/audiobrowser/browser/RouteMatch.kt +9 -0
- package/android/src/main/java/com/audiobrowser/browser/SimpleRouter.kt +150 -0
- package/android/src/main/java/com/audiobrowser/extension/EnumExtensions.kt +5 -0
- package/android/src/main/java/com/audiobrowser/extension/NumberExt.kt +13 -0
- package/android/src/main/java/com/audiobrowser/http/HttpClient.kt +171 -0
- package/android/src/main/java/com/audiobrowser/http/RequestConfigBuilder.kt +251 -0
- package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +80 -0
- package/android/src/main/java/com/audiobrowser/model/PlayerSetupOptions.kt +101 -0
- package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +125 -0
- package/android/src/main/java/com/audiobrowser/player/AutomaticBufferManager.kt +256 -0
- package/android/src/main/java/com/audiobrowser/player/DynamicLoadControl.kt +163 -0
- package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +177 -0
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +580 -0
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +578 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackProgressUpdateManager.kt +58 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +245 -0
- package/android/src/main/java/com/audiobrowser/player/Player.kt +1509 -0
- package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +230 -0
- package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +191 -0
- package/android/src/main/java/com/audiobrowser/player/SleepTimer.kt +80 -0
- package/android/src/main/java/com/audiobrowser/util/AndroidAudioContentTypeFactory.kt +17 -0
- package/android/src/main/java/com/audiobrowser/util/BatteryOptimizationHelper.kt +95 -0
- package/android/src/main/java/com/audiobrowser/util/BatteryWarningStore.kt +38 -0
- package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +155 -0
- package/android/src/main/java/com/audiobrowser/util/CoilBitmapLoader.kt +390 -0
- package/android/src/main/java/com/audiobrowser/util/EqualizerManager.kt +197 -0
- package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +75 -0
- package/android/src/main/java/com/audiobrowser/util/MetadataAdapter.kt +97 -0
- package/android/src/main/java/com/audiobrowser/util/NetworkConnectivityMonitor.kt +121 -0
- package/android/src/main/java/com/audiobrowser/util/PlayingStateFactory.kt +25 -0
- package/android/src/main/java/com/audiobrowser/util/RatingFactory.kt +72 -0
- package/android/src/main/java/com/audiobrowser/util/RepeatModeFactory.kt +22 -0
- package/android/src/main/java/com/audiobrowser/util/ResolvedTrackFactory.kt +36 -0
- package/android/src/main/java/com/audiobrowser/util/SvgArtworkRenderer.kt +130 -0
- package/android/src/main/java/com/audiobrowser/util/SystemVolumeMonitor.kt +50 -0
- package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +125 -0
- package/android/src/main/res/values/strings.xml +6 -0
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +273 -0
- package/android/src/test/java/com/audiobrowser/browser/SimpleBrowserTest.kt +33 -0
- package/android/src/test/java/com/audiobrowser/browser/SimpleRouterTest.kt +156 -0
- package/android/src/test/java/com/audiobrowser/http/RequestConfigBuilderTest.kt +240 -0
- package/ios/Bridge.h +8 -0
- package/ios/Browser/BrowserConfig.swift +85 -0
- package/ios/Browser/BrowserManager.swift +985 -0
- package/ios/Browser/BrowserPathHelper.swift +156 -0
- package/ios/Browser/JsonModels.swift +165 -0
- package/ios/Browser/SimpleRouter.swift +184 -0
- package/ios/CarPlay/CarPlayController.swift +1342 -0
- package/ios/CarPlay/RNABCarPlaySceneDelegate.h +15 -0
- package/ios/CarPlay/RNABCarPlaySceneDelegate.m +59 -0
- package/ios/CarPlay/Track+CarPlay.swift +49 -0
- package/ios/Extension/Capability+RemoteCommand.swift +76 -0
- package/ios/Extension/ChapterMetadata+AVFoundation.swift +37 -0
- package/ios/Extension/TimedMetadata+AVFoundation.swift +126 -0
- package/ios/Extension/Track+AVPlayer.swift +68 -0
- package/ios/Extension/TrackMetadata+AVFoundation.swift +128 -0
- package/ios/Http/HttpClient.swift +237 -0
- package/ios/HybridAudioBrowser.swift +1309 -0
- package/ios/Model/MediaURL.swift +66 -0
- package/ios/Model/PlayerUpdateOptions.swift +116 -0
- package/ios/Model/RemoteCommand.swift +71 -0
- package/ios/Model/SourceType.swift +6 -0
- package/ios/Model/TrackPlayerError.swift +69 -0
- package/ios/NowPlayingInfo/MediaItemProperty.swift +78 -0
- package/ios/NowPlayingInfo/NowPlayingInfoCenter.swift +9 -0
- package/ios/NowPlayingInfo/NowPlayingInfoController.swift +283 -0
- package/ios/NowPlayingInfo/NowPlayingInfoKeyValue.swift +6 -0
- package/ios/NowPlayingInfo/NowPlayingInfoProperty.swift +220 -0
- package/ios/Observer/PlayerItemNotificationObserver.swift +83 -0
- package/ios/Observer/PlayerItemPropertyObserver.swift +110 -0
- package/ios/Observer/PlayerStateObserver.swift +52 -0
- package/ios/Observer/PlayerTimeObserver.swift +109 -0
- package/ios/Option/PitchAlgorithms.swift +17 -0
- package/ios/Option/SessionCategories.swift +100 -0
- package/ios/Option/TimeEventFrequency.swift +18 -0
- package/ios/Player/PlaybackProgressUpdateManager.swift +60 -0
- package/ios/Player/PlayingStateManager.swift +29 -0
- package/ios/Player/RetryManager.swift +281 -0
- package/ios/Player/ShuffleOrder.swift +191 -0
- package/ios/Player/SleepTimerManager.swift +137 -0
- package/ios/RemoteCommand/RemoteCommandController.swift +400 -0
- package/ios/Support/RNTrackPlayer-Bridging-Header.h +7 -0
- package/ios/TrackPlayer.swift +1590 -0
- package/ios/TrackPlayerCallbacks.swift +121 -0
- package/ios/Util/Emitter.swift +46 -0
- package/ios/Util/LRUCache.swift +182 -0
- package/ios/Util/MetadataAdapter.swift +131 -0
- package/ios/Util/NetworkMonitor.swift +68 -0
- package/ios/Util/OnceValue.swift +70 -0
- package/ios/Util/SVGProcessor.swift +56 -0
- package/lib/commonjs/AudioBrowser.js +50 -0
- package/lib/commonjs/AudioBrowser.js.map +1 -0
- package/lib/commonjs/features/battery.js +154 -0
- package/lib/commonjs/features/battery.js.map +1 -0
- package/lib/commonjs/features/browser.js +271 -0
- package/lib/commonjs/features/browser.js.map +1 -0
- package/lib/commonjs/features/equalizer.js +69 -0
- package/lib/commonjs/features/equalizer.js.map +1 -0
- package/lib/commonjs/features/errors.js +165 -0
- package/lib/commonjs/features/errors.js.map +1 -0
- package/lib/commonjs/features/favorites.js +101 -0
- package/lib/commonjs/features/favorites.js.map +1 -0
- package/lib/commonjs/features/index.js +160 -0
- package/lib/commonjs/features/index.js.map +1 -0
- package/lib/commonjs/features/metadata.js +54 -0
- package/lib/commonjs/features/metadata.js.map +1 -0
- package/lib/commonjs/features/network.js +40 -0
- package/lib/commonjs/features/network.js.map +1 -0
- package/lib/commonjs/features/nowPlaying.js +61 -0
- package/lib/commonjs/features/nowPlaying.js.map +1 -0
- package/lib/commonjs/features/output.js +54 -0
- package/lib/commonjs/features/output.js.map +1 -0
- package/lib/commonjs/features/playback/controls.js +79 -0
- package/lib/commonjs/features/playback/controls.js.map +1 -0
- package/lib/commonjs/features/playback/index.js +83 -0
- package/lib/commonjs/features/playback/index.js.map +1 -0
- package/lib/commonjs/features/playback/playWhenReady.js +55 -0
- package/lib/commonjs/features/playback/playWhenReady.js.map +1 -0
- package/lib/commonjs/features/playback/playing.js +41 -0
- package/lib/commonjs/features/playback/playing.js.map +1 -0
- package/lib/commonjs/features/playback/progress.js +104 -0
- package/lib/commonjs/features/playback/progress.js.map +1 -0
- package/lib/commonjs/features/playback/rate.js +29 -0
- package/lib/commonjs/features/playback/rate.js.map +1 -0
- package/lib/commonjs/features/playback/state.js +62 -0
- package/lib/commonjs/features/playback/state.js.map +1 -0
- package/lib/commonjs/features/playback/volume.js +68 -0
- package/lib/commonjs/features/playback/volume.js.map +1 -0
- package/lib/commonjs/features/player/index.js +28 -0
- package/lib/commonjs/features/player/index.js.map +1 -0
- package/lib/commonjs/features/player/options.js +182 -0
- package/lib/commonjs/features/player/options.js.map +1 -0
- package/lib/commonjs/features/player/setup.js +143 -0
- package/lib/commonjs/features/player/setup.js.map +1 -0
- package/lib/commonjs/features/queue/activeTrack.js +52 -0
- package/lib/commonjs/features/queue/activeTrack.js.map +1 -0
- package/lib/commonjs/features/queue/index.js +50 -0
- package/lib/commonjs/features/queue/index.js.map +1 -0
- package/lib/commonjs/features/queue/queue.js +177 -0
- package/lib/commonjs/features/queue/queue.js.map +1 -0
- package/lib/commonjs/features/queue/repeatMode.js +58 -0
- package/lib/commonjs/features/queue/repeatMode.js.map +1 -0
- package/lib/commonjs/features/queue/shuffle.js +57 -0
- package/lib/commonjs/features/queue/shuffle.js.map +1 -0
- package/lib/commonjs/features/rating.js +2 -0
- package/lib/commonjs/features/rating.js.map +1 -0
- package/lib/commonjs/features/remoteControls.js +286 -0
- package/lib/commonjs/features/remoteControls.js.map +1 -0
- package/lib/commonjs/features/sleepTimer.js +164 -0
- package/lib/commonjs/features/sleepTimer.js.map +1 -0
- package/lib/commonjs/index.js +22 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/native.js +9 -0
- package/lib/commonjs/native.js.map +1 -0
- package/lib/commonjs/native.web.js +10 -0
- package/lib/commonjs/native.web.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/audio-browser.nitro.js +6 -0
- package/lib/commonjs/specs/audio-browser.nitro.js.map +1 -0
- package/lib/commonjs/types/browser-native.js +6 -0
- package/lib/commonjs/types/browser-native.js.map +1 -0
- package/lib/commonjs/types/browser-nodes.js +6 -0
- package/lib/commonjs/types/browser-nodes.js.map +1 -0
- package/lib/commonjs/types/browser.js +6 -0
- package/lib/commonjs/types/browser.js.map +1 -0
- package/lib/commonjs/types/index.js +28 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/types/player.js +2 -0
- package/lib/commonjs/types/player.js.map +1 -0
- package/lib/commonjs/utils/LazyNativeEmitter.js +58 -0
- package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -0
- package/lib/commonjs/utils/NativeUpdatedValue.js +59 -0
- package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -0
- package/lib/commonjs/utils/resolveAssetSource.js +11 -0
- package/lib/commonjs/utils/resolveAssetSource.js.map +1 -0
- package/lib/commonjs/utils/useDebug.js +221 -0
- package/lib/commonjs/utils/useDebug.js.map +1 -0
- package/lib/commonjs/utils/useNativeUpdatedValue.js +44 -0
- package/lib/commonjs/utils/useNativeUpdatedValue.js.map +1 -0
- package/lib/commonjs/web/NativeAudioBrowser.js +668 -0
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -0
- package/lib/commonjs/web/SimpleRouter.js +144 -0
- package/lib/commonjs/web/SimpleRouter.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Event.js +19 -0
- package/lib/commonjs/web/TrackPlayer/Event.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Player.js +276 -0
- package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js +284 -0
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js +12 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/SetupNotCalledError.js +13 -0
- package/lib/commonjs/web/TrackPlayer/SetupNotCalledError.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js +75 -0
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/State.js +18 -0
- package/lib/commonjs/web/TrackPlayer/State.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/index.js +52 -0
- package/lib/commonjs/web/TrackPlayer/index.js.map +1 -0
- package/lib/commonjs/web/browser/BrowserManager.js +594 -0
- package/lib/commonjs/web/browser/BrowserManager.js.map +1 -0
- package/lib/commonjs/web/browser/FavoriteManager.js +80 -0
- package/lib/commonjs/web/browser/FavoriteManager.js.map +1 -0
- package/lib/commonjs/web/browser/NavigationErrorManager.js +106 -0
- package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -0
- package/lib/commonjs/web/browser/SearchManager.js +80 -0
- package/lib/commonjs/web/browser/SearchManager.js.map +1 -0
- package/lib/commonjs/web/http/HttpClient.js +81 -0
- package/lib/commonjs/web/http/HttpClient.js.map +1 -0
- package/lib/commonjs/web/http/RequestConfigBuilder.js +294 -0
- package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -0
- package/lib/commonjs/web/player/NowPlayingManager.js +70 -0
- package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -0
- package/lib/commonjs/web/player/OptionsManager.js +88 -0
- package/lib/commonjs/web/player/OptionsManager.js.map +1 -0
- package/lib/commonjs/web/util/BrowserPathHelper.js +138 -0
- package/lib/commonjs/web/util/BrowserPathHelper.js.map +1 -0
- package/lib/commonjs/web/util/shuffle.js +21 -0
- package/lib/commonjs/web/util/shuffle.js.map +1 -0
- package/lib/module/AudioBrowser.js +7 -0
- package/lib/module/AudioBrowser.js.map +1 -0
- package/lib/module/features/battery.js +144 -0
- package/lib/module/features/battery.js.map +1 -0
- package/lib/module/features/browser.js +257 -0
- package/lib/module/features/browser.js.map +1 -0
- package/lib/module/features/equalizer.js +60 -0
- package/lib/module/features/equalizer.js.map +1 -0
- package/lib/module/features/errors.js +156 -0
- package/lib/module/features/errors.js.map +1 -0
- package/lib/module/features/favorites.js +95 -0
- package/lib/module/features/favorites.js.map +1 -0
- package/lib/module/features/index.js +26 -0
- package/lib/module/features/index.js.map +1 -0
- package/lib/module/features/metadata.js +51 -0
- package/lib/module/features/metadata.js.map +1 -0
- package/lib/module/features/network.js +35 -0
- package/lib/module/features/network.js.map +1 -0
- package/lib/module/features/nowPlaying.js +54 -0
- package/lib/module/features/nowPlaying.js.map +1 -0
- package/lib/module/features/output.js +47 -0
- package/lib/module/features/output.js.map +1 -0
- package/lib/module/features/playback/controls.js +69 -0
- package/lib/module/features/playback/controls.js.map +1 -0
- package/lib/module/features/playback/index.js +10 -0
- package/lib/module/features/playback/index.js.map +1 -0
- package/lib/module/features/playback/playWhenReady.js +49 -0
- package/lib/module/features/playback/playWhenReady.js.map +1 -0
- package/lib/module/features/playback/playing.js +36 -0
- package/lib/module/features/playback/playing.js.map +1 -0
- package/lib/module/features/playback/progress.js +98 -0
- package/lib/module/features/playback/progress.js.map +1 -0
- package/lib/module/features/playback/rate.js +25 -0
- package/lib/module/features/playback/rate.js.map +1 -0
- package/lib/module/features/playback/state.js +57 -0
- package/lib/module/features/playback/state.js.map +1 -0
- package/lib/module/features/playback/volume.js +60 -0
- package/lib/module/features/playback/volume.js.map +1 -0
- package/lib/module/features/player/index.js +5 -0
- package/lib/module/features/player/index.js.map +1 -0
- package/lib/module/features/player/options.js +176 -0
- package/lib/module/features/player/options.js.map +1 -0
- package/lib/module/features/player/setup.js +140 -0
- package/lib/module/features/player/setup.js.map +1 -0
- package/lib/module/features/queue/activeTrack.js +46 -0
- package/lib/module/features/queue/activeTrack.js.map +1 -0
- package/lib/module/features/queue/index.js +7 -0
- package/lib/module/features/queue/index.js.map +1 -0
- package/lib/module/features/queue/queue.js +162 -0
- package/lib/module/features/queue/queue.js.map +1 -0
- package/lib/module/features/queue/repeatMode.js +52 -0
- package/lib/module/features/queue/repeatMode.js.map +1 -0
- package/lib/module/features/queue/shuffle.js +50 -0
- package/lib/module/features/queue/shuffle.js.map +1 -0
- package/lib/module/features/rating.js +2 -0
- package/lib/module/features/rating.js.map +1 -0
- package/lib/module/features/remoteControls.js +275 -0
- package/lib/module/features/remoteControls.js.map +1 -0
- package/lib/module/features/sleepTimer.js +155 -0
- package/lib/module/features/sleepTimer.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native.js +5 -0
- package/lib/module/native.js.map +1 -0
- package/lib/module/native.web.js +7 -0
- package/lib/module/native.web.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/specs/audio-browser.nitro.js +4 -0
- package/lib/module/specs/audio-browser.nitro.js.map +1 -0
- package/lib/module/types/browser-native.js +4 -0
- package/lib/module/types/browser-native.js.map +1 -0
- package/lib/module/types/browser-nodes.js +4 -0
- package/lib/module/types/browser-nodes.js.map +1 -0
- package/lib/module/types/browser.js +4 -0
- package/lib/module/types/browser.js.map +1 -0
- package/lib/module/types/index.js +5 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/player.js +2 -0
- package/lib/module/types/player.js.map +1 -0
- package/lib/module/utils/LazyNativeEmitter.js +53 -0
- package/lib/module/utils/LazyNativeEmitter.js.map +1 -0
- package/lib/module/utils/NativeUpdatedValue.js +54 -0
- package/lib/module/utils/NativeUpdatedValue.js.map +1 -0
- package/lib/module/utils/resolveAssetSource.js +7 -0
- package/lib/module/utils/resolveAssetSource.js.map +1 -0
- package/lib/module/utils/useDebug.js +218 -0
- package/lib/module/utils/useDebug.js.map +1 -0
- package/lib/module/utils/useNativeUpdatedValue.js +40 -0
- package/lib/module/utils/useNativeUpdatedValue.js.map +1 -0
- package/lib/module/web/NativeAudioBrowser.js +664 -0
- package/lib/module/web/NativeAudioBrowser.js.map +1 -0
- package/lib/module/web/SimpleRouter.js +139 -0
- package/lib/module/web/SimpleRouter.js.map +1 -0
- package/lib/module/web/TrackPlayer/Event.js +15 -0
- package/lib/module/web/TrackPlayer/Event.js.map +1 -0
- package/lib/module/web/TrackPlayer/Player.js +271 -0
- package/lib/module/web/TrackPlayer/Player.js.map +1 -0
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js +279 -0
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js.map +1 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js +8 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js.map +1 -0
- package/lib/module/web/TrackPlayer/SetupNotCalledError.js +8 -0
- package/lib/module/web/TrackPlayer/SetupNotCalledError.js.map +1 -0
- package/lib/module/web/TrackPlayer/SleepTimer.js +70 -0
- package/lib/module/web/TrackPlayer/SleepTimer.js.map +1 -0
- package/lib/module/web/TrackPlayer/State.js +14 -0
- package/lib/module/web/TrackPlayer/State.js.map +1 -0
- package/lib/module/web/TrackPlayer/index.js +7 -0
- package/lib/module/web/TrackPlayer/index.js.map +1 -0
- package/lib/module/web/browser/BrowserManager.js +590 -0
- package/lib/module/web/browser/BrowserManager.js.map +1 -0
- package/lib/module/web/browser/FavoriteManager.js +75 -0
- package/lib/module/web/browser/FavoriteManager.js.map +1 -0
- package/lib/module/web/browser/NavigationErrorManager.js +101 -0
- package/lib/module/web/browser/NavigationErrorManager.js.map +1 -0
- package/lib/module/web/browser/SearchManager.js +76 -0
- package/lib/module/web/browser/SearchManager.js.map +1 -0
- package/lib/module/web/http/HttpClient.js +76 -0
- package/lib/module/web/http/HttpClient.js.map +1 -0
- package/lib/module/web/http/RequestConfigBuilder.js +291 -0
- package/lib/module/web/http/RequestConfigBuilder.js.map +1 -0
- package/lib/module/web/player/NowPlayingManager.js +65 -0
- package/lib/module/web/player/NowPlayingManager.js.map +1 -0
- package/lib/module/web/player/OptionsManager.js +83 -0
- package/lib/module/web/player/OptionsManager.js.map +1 -0
- package/lib/module/web/util/BrowserPathHelper.js +134 -0
- package/lib/module/web/util/BrowserPathHelper.js.map +1 -0
- package/lib/module/web/util/shuffle.js +17 -0
- package/lib/module/web/util/shuffle.js.map +1 -0
- package/lib/typescript/src/AudioBrowser.d.ts +5 -0
- package/lib/typescript/src/AudioBrowser.d.ts.map +1 -0
- package/lib/typescript/src/features/battery.d.ts +112 -0
- package/lib/typescript/src/features/battery.d.ts.map +1 -0
- package/lib/typescript/src/features/browser.d.ts +68 -0
- package/lib/typescript/src/features/browser.d.ts.map +1 -0
- package/lib/typescript/src/features/equalizer.d.ts +35 -0
- package/lib/typescript/src/features/equalizer.d.ts.map +1 -0
- package/lib/typescript/src/features/errors.d.ts +136 -0
- package/lib/typescript/src/features/errors.d.ts.map +1 -0
- package/lib/typescript/src/features/favorites.d.ts +84 -0
- package/lib/typescript/src/features/favorites.d.ts.map +1 -0
- package/lib/typescript/src/features/index.d.ts +23 -0
- package/lib/typescript/src/features/index.d.ts.map +1 -0
- package/lib/typescript/src/features/metadata.d.ts +103 -0
- package/lib/typescript/src/features/metadata.d.ts.map +1 -0
- package/lib/typescript/src/features/network.d.ts +18 -0
- package/lib/typescript/src/features/network.d.ts.map +1 -0
- package/lib/typescript/src/features/nowPlaying.d.ts +36 -0
- package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -0
- package/lib/typescript/src/features/output.d.ts +28 -0
- package/lib/typescript/src/features/output.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/controls.d.ts +40 -0
- package/lib/typescript/src/features/playback/controls.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/index.d.ts +8 -0
- package/lib/typescript/src/features/playback/index.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/playWhenReady.d.ts +30 -0
- package/lib/typescript/src/features/playback/playWhenReady.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/playing.d.ts +21 -0
- package/lib/typescript/src/features/playback/playing.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/progress.d.ts +51 -0
- package/lib/typescript/src/features/playback/progress.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/rate.d.ts +12 -0
- package/lib/typescript/src/features/playback/rate.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/state.d.ts +43 -0
- package/lib/typescript/src/features/playback/state.d.ts.map +1 -0
- package/lib/typescript/src/features/playback/volume.d.ts +32 -0
- package/lib/typescript/src/features/playback/volume.d.ts.map +1 -0
- package/lib/typescript/src/features/player/index.d.ts +3 -0
- package/lib/typescript/src/features/player/index.d.ts.map +1 -0
- package/lib/typescript/src/features/player/options.d.ts +413 -0
- package/lib/typescript/src/features/player/options.d.ts.map +1 -0
- package/lib/typescript/src/features/player/setup.d.ts +471 -0
- package/lib/typescript/src/features/player/setup.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/activeTrack.d.ts +38 -0
- package/lib/typescript/src/features/queue/activeTrack.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/index.d.ts +5 -0
- package/lib/typescript/src/features/queue/index.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/queue.d.ts +111 -0
- package/lib/typescript/src/features/queue/queue.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/repeatMode.d.ts +34 -0
- package/lib/typescript/src/features/queue/repeatMode.d.ts.map +1 -0
- package/lib/typescript/src/features/queue/shuffle.d.ts +27 -0
- package/lib/typescript/src/features/queue/shuffle.d.ts.map +1 -0
- package/lib/typescript/src/features/rating.d.ts +14 -0
- package/lib/typescript/src/features/rating.d.ts.map +1 -0
- package/lib/typescript/src/features/remoteControls.d.ts +164 -0
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -0
- package/lib/typescript/src/features/sleepTimer.d.ts +80 -0
- package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/native.d.ts +3 -0
- package/lib/typescript/src/native.d.ts.map +1 -0
- package/lib/typescript/src/native.web.d.ts +3 -0
- package/lib/typescript/src/native.web.d.ts.map +1 -0
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts +242 -0
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -0
- package/lib/typescript/src/types/browser-native.d.ts +39 -0
- package/lib/typescript/src/types/browser-native.d.ts.map +1 -0
- package/lib/typescript/src/types/browser-nodes.d.ts +153 -0
- package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -0
- package/lib/typescript/src/types/browser.d.ts +710 -0
- package/lib/typescript/src/types/browser.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +3 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -0
- package/lib/typescript/src/types/player.d.ts +64 -0
- package/lib/typescript/src/types/player.d.ts.map +1 -0
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +35 -0
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -0
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +39 -0
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -0
- package/lib/typescript/src/utils/resolveAssetSource.d.ts +4 -0
- package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -0
- package/lib/typescript/src/utils/useDebug.d.ts +65 -0
- package/lib/typescript/src/utils/useDebug.d.ts.map +1 -0
- package/lib/typescript/src/utils/useNativeUpdatedValue.d.ts +14 -0
- package/lib/typescript/src/utils/useNativeUpdatedValue.d.ts.map +1 -0
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts +176 -0
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts.map +1 -0
- package/lib/typescript/src/web/SimpleRouter.d.ts +40 -0
- package/lib/typescript/src/web/SimpleRouter.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts +11 -0
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts +71 -0
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts +39 -0
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts +6 -0
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts +4 -0
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts +34 -0
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/State.d.ts +13 -0
- package/lib/typescript/src/web/TrackPlayer/State.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/index.d.ts +5 -0
- package/lib/typescript/src/web/TrackPlayer/index.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/BrowserManager.d.ts +154 -0
- package/lib/typescript/src/web/browser/BrowserManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts +42 -0
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts +40 -0
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/SearchManager.d.ts +22 -0
- package/lib/typescript/src/web/browser/SearchManager.d.ts.map +1 -0
- package/lib/typescript/src/web/http/HttpClient.d.ts +25 -0
- package/lib/typescript/src/web/http/HttpClient.d.ts.map +1 -0
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts +98 -0
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts.map +1 -0
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts +34 -0
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts.map +1 -0
- package/lib/typescript/src/web/player/OptionsManager.d.ts +32 -0
- package/lib/typescript/src/web/player/OptionsManager.d.ts.map +1 -0
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts +69 -0
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts.map +1 -0
- package/lib/typescript/src/web/util/shuffle.d.ts +8 -0
- package/lib/typescript/src/web/util/shuffle.d.ts.map +1 -0
- package/nitro.json +24 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +88 -0
- package/nitrogen/generated/android/AudioBrowser+autolinking.gradle +27 -0
- package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +124 -0
- package/nitrogen/generated/android/AudioBrowserOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +68 -0
- package/nitrogen/generated/android/c++/JAndroidAudioOffloadSettings.hpp +61 -0
- package/nitrogen/generated/android/c++/JAndroidOptions.hpp +86 -0
- package/nitrogen/generated/android/c++/JAndroidPlayerWakeMode.hpp +62 -0
- package/nitrogen/generated/android/c++/JAndroidUpdateOptions.hpp +86 -0
- package/nitrogen/generated/android/c++/JAppKilledPlaybackBehavior.hpp +62 -0
- package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +163 -0
- package/nitrogen/generated/android/c++/JBatteryOptimizationStatus.hpp +62 -0
- package/nitrogen/generated/android/c++/JBatteryOptimizationStatusChangedEvent.hpp +58 -0
- package/nitrogen/generated/android/c++/JBatteryWarningPendingChangedEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JBrowseError.hpp +57 -0
- package/nitrogen/generated/android/c++/JBrowseResult.cpp +26 -0
- package/nitrogen/generated/android/c++/JBrowseResult.hpp +83 -0
- package/nitrogen/generated/android/c++/JBrowserSourceCallbackParam.hpp +76 -0
- package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +65 -0
- package/nitrogen/generated/android/c++/JChapterMetadata.hpp +70 -0
- package/nitrogen/generated/android/c++/JEqualizerSettings.hpp +125 -0
- package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +71 -0
- package/nitrogen/generated/android/c++/JFormatNavigationErrorParams.hpp +72 -0
- package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +61 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.hpp +111 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.hpp +134 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +143 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +136 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.hpp +143 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +157 -0
- package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_BatteryOptimizationStatusChangedEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_BatteryWarningPendingChangedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_EqualizerSettings.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +88 -0
- package/nitrogen/generated/android/c++/JFunc_void_IosOutput.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_NavigationErrorEvent.hpp +83 -0
- package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +89 -0
- package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +98 -0
- package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +83 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +88 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +81 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackPlayWhenReadyChangedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackProgressUpdatedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackQueueEndedEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_PlayingState.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpBackwardEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpForwardEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemotePlayIdEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemotePlaySearchEvent.hpp +78 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSeekEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSetRatingEvent.hpp +87 -0
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSkipEvent.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_RepeatModeChangedEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_TimedMetadata.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_TrackMetadata.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_double.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_FormattedNavigationError_.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +89 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.hpp +84 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_ChapterMetadata_.hpp +98 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +105 -0
- package/nitrogen/generated/android/c++/JHeartRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JHttpMethod.hpp +74 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +1811 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +250 -0
- package/nitrogen/generated/android/c++/JIOSCategory.hpp +71 -0
- package/nitrogen/generated/android/c++/JIOSCategoryMode.hpp +80 -0
- package/nitrogen/generated/android/c++/JIOSCategoryOptions.hpp +74 -0
- package/nitrogen/generated/android/c++/JIOSCategoryPolicy.hpp +62 -0
- package/nitrogen/generated/android/c++/JImageContext.hpp +61 -0
- package/nitrogen/generated/android/c++/JImageQueryParams.hpp +62 -0
- package/nitrogen/generated/android/c++/JImageSource.hpp +86 -0
- package/nitrogen/generated/android/c++/JIosOutput.hpp +67 -0
- package/nitrogen/generated/android/c++/JIosOutputType.hpp +86 -0
- package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +153 -0
- package/nitrogen/generated/android/c++/JMediaTransformParams.hpp +69 -0
- package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +196 -0
- package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +147 -0
- package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +105 -0
- package/nitrogen/generated/android/c++/JNavigationError.hpp +72 -0
- package/nitrogen/generated/android/c++/JNavigationErrorEvent.hpp +62 -0
- package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +68 -0
- package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +86 -0
- package/nitrogen/generated/android/c++/JNotificationButton.hpp +68 -0
- package/nitrogen/generated/android/c++/JNotificationButtonLayout.hpp +94 -0
- package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +104 -0
- package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +62 -0
- package/nitrogen/generated/android/c++/JOptions.hpp +97 -0
- package/nitrogen/generated/android/c++/JPartialAndroidSetupPlayerOptions.hpp +104 -0
- package/nitrogen/generated/android/c++/JPartialIOSSetupPlayerOptions.hpp +100 -0
- package/nitrogen/generated/android/c++/JPartialSetupPlayerOptions.hpp +96 -0
- package/nitrogen/generated/android/c++/JPercentageRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JPlayback.hpp +66 -0
- package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +83 -0
- package/nitrogen/generated/android/c++/JPlaybackError.hpp +61 -0
- package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +60 -0
- package/nitrogen/generated/android/c++/JPlaybackPlayWhenReadyChangedEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JPlaybackProgressUpdatedEvent.hpp +69 -0
- package/nitrogen/generated/android/c++/JPlaybackQueueEndedEvent.hpp +61 -0
- package/nitrogen/generated/android/c++/JPlaybackState.hpp +80 -0
- package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +101 -0
- package/nitrogen/generated/android/c++/JPlayingState.hpp +61 -0
- package/nitrogen/generated/android/c++/JProgress.hpp +65 -0
- package/nitrogen/generated/android/c++/JRatingType.hpp +74 -0
- package/nitrogen/generated/android/c++/JRemoteJumpBackwardEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemoteJumpForwardEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemotePlayIdEvent.hpp +62 -0
- package/nitrogen/generated/android/c++/JRemotePlaySearchEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemoteSeekEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRemoteSetRatingEvent.hpp +66 -0
- package/nitrogen/generated/android/c++/JRemoteSkipEvent.hpp +57 -0
- package/nitrogen/generated/android/c++/JRepeatMode.hpp +62 -0
- package/nitrogen/generated/android/c++/JRepeatModeChangedEvent.hpp +58 -0
- package/nitrogen/generated/android/c++/JRequestConfig.hpp +115 -0
- package/nitrogen/generated/android/c++/JResolvedTrack.hpp +154 -0
- package/nitrogen/generated/android/c++/JRetryConfig.hpp +61 -0
- package/nitrogen/generated/android/c++/JSearchMode.hpp +71 -0
- package/nitrogen/generated/android/c++/JSearchParams.hpp +84 -0
- package/nitrogen/generated/android/c++/JSleepTimer.cpp +30 -0
- package/nitrogen/generated/android/c++/JSleepTimer.hpp +88 -0
- package/nitrogen/generated/android/c++/JSleepTimerEndOfTrack.hpp +57 -0
- package/nitrogen/generated/android/c++/JSleepTimerTime.hpp +57 -0
- package/nitrogen/generated/android/c++/JStarRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JThumbsRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JTimedMetadata.hpp +74 -0
- package/nitrogen/generated/android/c++/JTrack.hpp +129 -0
- package/nitrogen/generated/android/c++/JTrackMetadata.hpp +118 -0
- package/nitrogen/generated/android/c++/JTrackStyle.hpp +59 -0
- package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +134 -0
- package/nitrogen/generated/android/c++/JUpdateOptions.hpp +105 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_AndroidAudioOffloadSettings.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_AndroidAudioOffloadSettings.hpp +70 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_RetryConfig.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_RetryConfig.hpp +70 -0
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.cpp +34 -0
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.hpp +105 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_Double.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp +69 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.hpp +75 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioContentType.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioOffloadSettings.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidPlayerWakeMode.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidUpdateOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AppKilledPlaybackBehavior.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +72 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AudioBrowserOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryOptimizationStatus.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryOptimizationStatusChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryWarningPendingChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseError.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseResult.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowserSourceCallbackParam.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayNowPlayingButton.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ChapterMetadata.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/EqualizerSettings.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FavoriteChangedEvent.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNavigationErrorParams.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_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_std__shared_ptr_Promise_RequestConfig_____Track.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 +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryOptimizationStatusChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryWarningPendingChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_EqualizerSettings.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_FavoriteChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_IosOutput.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NavigationErrorEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NowPlayingMetadata.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Options.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Playback.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackActiveTrackChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackErrorEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackPlayWhenReadyChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackProgressUpdatedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackQueueEndedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlayingState.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpBackwardEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpForwardEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlayIdEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlaySearchEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSeekEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSetRatingEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSkipEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RepeatModeChangedEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TimedMetadata.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TrackMetadata.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_double.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_FormattedNavigationError_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_ResolvedTrack_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__string.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_ChapterMetadata_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_Track_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HeartRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HttpMethod.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +1137 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategory.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategoryMode.kt +28 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategoryOptions.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSCategoryPolicy.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageContext.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageQueryParams.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageSource.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutput.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutputType.kt +30 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +69 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaTransformParams.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +69 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +63 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationError.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorType.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButton.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButtonLayout.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialAndroidSetupPlayerOptions.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialIOSSetupPlayerOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialSetupPlayerOptions.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PercentageRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Playback.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackActiveTrackChangedEvent.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackPlayWhenReadyChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackProgressUpdatedEvent.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackQueueEndedEvent.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackState.kt +28 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +71 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayingState.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Progress.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RatingType.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpBackwardEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpForwardEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlayIdEvent.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlaySearchEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSeekEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSetRatingEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSkipEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RepeatMode.kt +22 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RepeatModeChangedEvent.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RequestConfig.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +89 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchMode.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimer.kt +72 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerEndOfTrack.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerTime.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StarRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ThumbsRating.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TimedMetadata.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +86 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackMetadata.kt +83 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackStyle.kt +21 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/UpdateOptions.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_AndroidAudioOffloadSettings.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_RetryConfig.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.kt +85 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_NullType_Double.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_NullType_NotificationButtonLayout.kt +59 -0
- package/nitrogen/generated/ios/AudioBrowser+autolinking.rb +60 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +407 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +2822 -0
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +300 -0
- package/nitrogen/generated/ios/AudioBrowserAutolinking.mm +33 -0
- package/nitrogen/generated/ios/AudioBrowserAutolinking.swift +25 -0
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +1190 -0
- package/nitrogen/generated/ios/swift/AndroidAudioContentType.swift +52 -0
- package/nitrogen/generated/ios/swift/AndroidAudioOffloadSettings.swift +85 -0
- package/nitrogen/generated/ios/swift/AndroidOptions.swift +125 -0
- package/nitrogen/generated/ios/swift/AndroidPlayerWakeMode.swift +44 -0
- package/nitrogen/generated/ios/swift/AndroidUpdateOptions.swift +187 -0
- package/nitrogen/generated/ios/swift/AppKilledPlaybackBehavior.swift +44 -0
- package/nitrogen/generated/ios/swift/ArtworkRequestConfig.swift +445 -0
- package/nitrogen/generated/ios/swift/BatteryOptimizationStatus.swift +44 -0
- package/nitrogen/generated/ios/swift/BatteryOptimizationStatusChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/BatteryWarningPendingChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/BrowseError.swift +36 -0
- package/nitrogen/generated/ios/swift/BrowseResult.swift +18 -0
- package/nitrogen/generated/ios/swift/BrowserSourceCallbackParam.swift +86 -0
- package/nitrogen/generated/ios/swift/CarPlayNowPlayingButton.swift +48 -0
- package/nitrogen/generated/ios/swift/ChapterMetadata.swift +107 -0
- package/nitrogen/generated/ios/swift/EqualizerSettings.swift +168 -0
- package/nitrogen/generated/ios/swift/FavoriteChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/FormatNavigationErrorParams.swift +58 -0
- package/nitrogen/generated/ios/swift/FormattedNavigationError.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.swift +61 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.swift +62 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____RequestConfig_std__optional_std__unordered_map_std__string__std__string__.swift +77 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.swift +62 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.swift +69 -0
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.swift +68 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_BatteryOptimizationStatusChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_BatteryWarningPendingChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_EqualizerSettings.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_FavoriteChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_IosOutput.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_NavigationErrorEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_NowPlayingMetadata.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_Options.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_Playback.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackActiveTrackChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackErrorEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackPlayWhenReadyChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackProgressUpdatedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlaybackQueueEndedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PlayingState.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteJumpBackwardEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteJumpForwardEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemotePlayIdEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemotePlaySearchEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteSeekEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteSetRatingEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RemoteSkipEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RepeatModeChangedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_RequestConfig.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_TimedMetadata.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_TrackMetadata.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_double.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_FormattedNavigationError_.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_ResolvedTrack_.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.swift +69 -0
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_RequestConfig__.swift +67 -0
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError___.swift +67 -0
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_std__vector_Track___.swift +67 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_ResolvedTrack__BrowseError_.swift +59 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_ChapterMetadata_.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_Track_.swift +47 -0
- package/nitrogen/generated/ios/swift/HeartRating.swift +36 -0
- package/nitrogen/generated/ios/swift/HttpMethod.swift +60 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +181 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +2352 -0
- package/nitrogen/generated/ios/swift/IOSCategory.swift +56 -0
- package/nitrogen/generated/ios/swift/IOSCategoryMode.swift +68 -0
- package/nitrogen/generated/ios/swift/IOSCategoryOptions.swift +60 -0
- package/nitrogen/generated/ios/swift/IOSCategoryPolicy.swift +44 -0
- package/nitrogen/generated/ios/swift/ImageContext.swift +71 -0
- package/nitrogen/generated/ios/swift/ImageQueryParams.swift +85 -0
- package/nitrogen/generated/ios/swift/ImageSource.swift +139 -0
- package/nitrogen/generated/ios/swift/IosOutput.swift +58 -0
- package/nitrogen/generated/ios/swift/IosOutputType.swift +76 -0
- package/nitrogen/generated/ios/swift/MediaRequestConfig.swift +434 -0
- package/nitrogen/generated/ios/swift/MediaTransformParams.swift +59 -0
- package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +360 -0
- package/nitrogen/generated/ios/swift/NativeRouteEntry.swift +275 -0
- package/nitrogen/generated/ios/swift/NativeUpdateOptions.swift +215 -0
- package/nitrogen/generated/ios/swift/NavigationError.swift +100 -0
- package/nitrogen/generated/ios/swift/NavigationErrorEvent.swift +48 -0
- package/nitrogen/generated/ios/swift/NavigationErrorType.swift +52 -0
- package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +187 -0
- package/nitrogen/generated/ios/swift/NotificationButton.swift +52 -0
- package/nitrogen/generated/ios/swift/NotificationButtonLayout.swift +159 -0
- package/nitrogen/generated/ios/swift/NowPlayingMetadata.swift +351 -0
- package/nitrogen/generated/ios/swift/NowPlayingUpdate.swift +85 -0
- package/nitrogen/generated/ios/swift/Options.swift +148 -0
- package/nitrogen/generated/ios/swift/PartialAndroidSetupPlayerOptions.swift +328 -0
- package/nitrogen/generated/ios/swift/PartialIOSSetupPlayerOptions.swift +159 -0
- package/nitrogen/generated/ios/swift/PartialSetupPlayerOptions.swift +157 -0
- package/nitrogen/generated/ios/swift/PercentageRating.swift +36 -0
- package/nitrogen/generated/ios/swift/Playback.swift +59 -0
- package/nitrogen/generated/ios/swift/PlaybackActiveTrackChangedEvent.swift +128 -0
- package/nitrogen/generated/ios/swift/PlaybackError.swift +47 -0
- package/nitrogen/generated/ios/swift/PlaybackErrorEvent.swift +48 -0
- package/nitrogen/generated/ios/swift/PlaybackPlayWhenReadyChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/PlaybackProgressUpdatedEvent.swift +69 -0
- package/nitrogen/generated/ios/swift/PlaybackQueueEndedEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/PlaybackState.swift +68 -0
- package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +385 -0
- package/nitrogen/generated/ios/swift/PlayingState.swift +47 -0
- package/nitrogen/generated/ios/swift/Progress.swift +58 -0
- package/nitrogen/generated/ios/swift/RatingType.swift +60 -0
- package/nitrogen/generated/ios/swift/RemoteJumpBackwardEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemoteJumpForwardEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemotePlayIdEvent.swift +59 -0
- package/nitrogen/generated/ios/swift/RemotePlaySearchEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemoteSeekEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RemoteSetRatingEvent.swift +76 -0
- package/nitrogen/generated/ios/swift/RemoteSkipEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RepeatMode.swift +44 -0
- package/nitrogen/generated/ios/swift/RepeatModeChangedEvent.swift +36 -0
- package/nitrogen/generated/ios/swift/RequestConfig.swift +298 -0
- package/nitrogen/generated/ios/swift/ResolvedTrack.swift +511 -0
- package/nitrogen/generated/ios/swift/RetryConfig.swift +59 -0
- package/nitrogen/generated/ios/swift/SearchMode.swift +56 -0
- package/nitrogen/generated/ios/swift/SearchParams.swift +209 -0
- package/nitrogen/generated/ios/swift/SleepTimer.swift +19 -0
- package/nitrogen/generated/ios/swift/SleepTimerEndOfTrack.swift +36 -0
- package/nitrogen/generated/ios/swift/SleepTimerTime.swift +36 -0
- package/nitrogen/generated/ios/swift/StarRating.swift +36 -0
- package/nitrogen/generated/ios/swift/ThumbsRating.swift +36 -0
- package/nitrogen/generated/ios/swift/TimedMetadata.swift +175 -0
- package/nitrogen/generated/ios/swift/Track.swift +488 -0
- package/nitrogen/generated/ios/swift/TrackMetadata.swift +505 -0
- package/nitrogen/generated/ios/swift/TrackStyle.swift +40 -0
- package/nitrogen/generated/ios/swift/TransformableRequestConfig.swift +372 -0
- package/nitrogen/generated/ios/swift/UpdateOptions.swift +215 -0
- package/nitrogen/generated/ios/swift/Variant_Bool_AndroidAudioOffloadSettings.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_Bool_RetryConfig.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.swift +20 -0
- package/nitrogen/generated/ios/swift/Variant_NullType_Double.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_NullType_NotificationButtonLayout.swift +18 -0
- package/nitrogen/generated/shared/c++/AndroidAudioContentType.hpp +88 -0
- package/nitrogen/generated/shared/c++/AndroidAudioOffloadSettings.hpp +79 -0
- package/nitrogen/generated/shared/c++/AndroidOptions.hpp +101 -0
- package/nitrogen/generated/shared/c++/AndroidPlayerWakeMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/AndroidUpdateOptions.hpp +101 -0
- package/nitrogen/generated/shared/c++/AppKilledPlaybackBehavior.hpp +80 -0
- package/nitrogen/generated/shared/c++/ArtworkRequestConfig.hpp +133 -0
- package/nitrogen/generated/shared/c++/BatteryOptimizationStatus.hpp +80 -0
- package/nitrogen/generated/shared/c++/BatteryOptimizationStatusChangedEvent.hpp +76 -0
- package/nitrogen/generated/shared/c++/BatteryWarningPendingChangedEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/BrowseError.hpp +75 -0
- package/nitrogen/generated/shared/c++/BrowserSourceCallbackParam.hpp +81 -0
- package/nitrogen/generated/shared/c++/CarPlayNowPlayingButton.hpp +84 -0
- package/nitrogen/generated/shared/c++/ChapterMetadata.hpp +88 -0
- package/nitrogen/generated/shared/c++/EqualizerSettings.hpp +105 -0
- package/nitrogen/generated/shared/c++/FavoriteChangedEvent.hpp +80 -0
- package/nitrogen/generated/shared/c++/FormatNavigationErrorParams.hpp +88 -0
- package/nitrogen/generated/shared/c++/FormattedNavigationError.hpp +79 -0
- package/nitrogen/generated/shared/c++/HeartRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/HttpMethod.hpp +96 -0
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +207 -0
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +375 -0
- package/nitrogen/generated/shared/c++/IOSCategory.hpp +92 -0
- package/nitrogen/generated/shared/c++/IOSCategoryMode.hpp +104 -0
- package/nitrogen/generated/shared/c++/IOSCategoryOptions.hpp +96 -0
- package/nitrogen/generated/shared/c++/IOSCategoryPolicy.hpp +80 -0
- package/nitrogen/generated/shared/c++/ImageContext.hpp +79 -0
- package/nitrogen/generated/shared/c++/ImageQueryParams.hpp +80 -0
- package/nitrogen/generated/shared/c++/ImageSource.hpp +91 -0
- package/nitrogen/generated/shared/c++/IosOutput.hpp +85 -0
- package/nitrogen/generated/shared/c++/IosOutputType.hpp +112 -0
- package/nitrogen/generated/shared/c++/MediaRequestConfig.hpp +123 -0
- package/nitrogen/generated/shared/c++/MediaTransformParams.hpp +84 -0
- package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +135 -0
- package/nitrogen/generated/shared/c++/NativeRouteEntry.hpp +131 -0
- package/nitrogen/generated/shared/c++/NativeUpdateOptions.hpp +103 -0
- package/nitrogen/generated/shared/c++/NavigationError.hpp +90 -0
- package/nitrogen/generated/shared/c++/NavigationErrorEvent.hpp +77 -0
- package/nitrogen/generated/shared/c++/NavigationErrorType.hpp +88 -0
- package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +101 -0
- package/nitrogen/generated/shared/c++/NotificationButton.hpp +88 -0
- package/nitrogen/generated/shared/c++/NotificationButtonLayout.hpp +94 -0
- package/nitrogen/generated/shared/c++/NowPlayingMetadata.hpp +124 -0
- package/nitrogen/generated/shared/c++/NowPlayingUpdate.hpp +80 -0
- package/nitrogen/generated/shared/c++/Options.hpp +105 -0
- package/nitrogen/generated/shared/c++/PartialAndroidSetupPlayerOptions.hpp +121 -0
- package/nitrogen/generated/shared/c++/PartialIOSSetupPlayerOptions.hpp +103 -0
- package/nitrogen/generated/shared/c++/PartialSetupPlayerOptions.hpp +96 -0
- package/nitrogen/generated/shared/c++/PercentageRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/Playback.hpp +84 -0
- package/nitrogen/generated/shared/c++/PlaybackActiveTrackChangedEvent.hpp +93 -0
- package/nitrogen/generated/shared/c++/PlaybackError.hpp +79 -0
- package/nitrogen/generated/shared/c++/PlaybackErrorEvent.hpp +77 -0
- package/nitrogen/generated/shared/c++/PlaybackPlayWhenReadyChangedEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/PlaybackProgressUpdatedEvent.hpp +87 -0
- package/nitrogen/generated/shared/c++/PlaybackQueueEndedEvent.hpp +79 -0
- package/nitrogen/generated/shared/c++/PlaybackState.hpp +104 -0
- package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +119 -0
- package/nitrogen/generated/shared/c++/PlayingState.hpp +79 -0
- package/nitrogen/generated/shared/c++/Progress.hpp +83 -0
- package/nitrogen/generated/shared/c++/RatingType.hpp +96 -0
- package/nitrogen/generated/shared/c++/RemoteJumpBackwardEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemoteJumpForwardEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemotePlayIdEvent.hpp +80 -0
- package/nitrogen/generated/shared/c++/RemotePlaySearchEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemoteSeekEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RemoteSetRatingEvent.hpp +86 -0
- package/nitrogen/generated/shared/c++/RemoteSkipEvent.hpp +75 -0
- package/nitrogen/generated/shared/c++/RepeatMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/RepeatModeChangedEvent.hpp +76 -0
- package/nitrogen/generated/shared/c++/RequestConfig.hpp +107 -0
- package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +153 -0
- package/nitrogen/generated/shared/c++/RetryConfig.hpp +79 -0
- package/nitrogen/generated/shared/c++/SearchMode.hpp +92 -0
- package/nitrogen/generated/shared/c++/SearchParams.hpp +102 -0
- package/nitrogen/generated/shared/c++/SleepTimerEndOfTrack.hpp +75 -0
- package/nitrogen/generated/shared/c++/SleepTimerTime.hpp +75 -0
- package/nitrogen/generated/shared/c++/StarRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/ThumbsRating.hpp +75 -0
- package/nitrogen/generated/shared/c++/TimedMetadata.hpp +92 -0
- package/nitrogen/generated/shared/c++/Track.hpp +145 -0
- package/nitrogen/generated/shared/c++/TrackMetadata.hpp +136 -0
- package/nitrogen/generated/shared/c++/TrackStyle.hpp +76 -0
- package/nitrogen/generated/shared/c++/TransformableRequestConfig.hpp +116 -0
- package/nitrogen/generated/shared/c++/UpdateOptions.hpp +103 -0
- package/package.json +120 -0
- package/src/AudioBrowser.ts +4 -0
- package/src/features/battery.ts +176 -0
- package/src/features/browser.ts +315 -0
- package/src/features/equalizer.ts +64 -0
- package/src/features/errors.ts +196 -0
- package/src/features/favorites.ts +102 -0
- package/src/features/index.ts +23 -0
- package/src/features/metadata.ts +130 -0
- package/src/features/network.ts +34 -0
- package/src/features/nowPlaying.ts +56 -0
- package/src/features/output.ts +50 -0
- package/src/features/playback/controls.ts +66 -0
- package/src/features/playback/index.ts +7 -0
- package/src/features/playback/playWhenReady.ts +57 -0
- package/src/features/playback/playing.ts +40 -0
- package/src/features/playback/progress.ts +122 -0
- package/src/features/playback/rate.ts +22 -0
- package/src/features/playback/state.ts +72 -0
- package/src/features/playback/volume.ts +59 -0
- package/src/features/player/index.ts +2 -0
- package/src/features/player/options.ts +479 -0
- package/src/features/player/setup.ts +551 -0
- package/src/features/queue/activeTrack.ts +59 -0
- package/src/features/queue/index.ts +4 -0
- package/src/features/queue/queue.ts +173 -0
- package/src/features/queue/repeatMode.ts +58 -0
- package/src/features/queue/shuffle.ts +49 -0
- package/src/features/rating.ts +17 -0
- package/src/features/remoteControls.ts +341 -0
- package/src/features/sleepTimer.ts +186 -0
- package/src/index.ts +5 -0
- package/src/native.ts +5 -0
- package/src/native.web.ts +4 -0
- package/src/specs/audio-browser.nitro.ts +326 -0
- package/src/types/browser-native.ts +66 -0
- package/src/types/browser-nodes.ts +174 -0
- package/src/types/browser.ts +792 -0
- package/src/types/index.ts +2 -0
- package/src/types/player.ts +69 -0
- package/src/utils/LazyNativeEmitter.ts +58 -0
- package/src/utils/NativeUpdatedValue.ts +56 -0
- package/src/utils/resolveAssetSource.ts +4 -0
- package/src/utils/useDebug.ts +283 -0
- package/src/utils/useNativeUpdatedValue.ts +41 -0
- package/src/web/NativeAudioBrowser.ts +781 -0
- package/src/web/SimpleRouter.ts +177 -0
- package/src/web/TrackPlayer/Event.ts +11 -0
- package/src/web/TrackPlayer/Player.ts +323 -0
- package/src/web/TrackPlayer/PlaylistPlayer.ts +337 -0
- package/src/web/TrackPlayer/RepeatMode.ts +7 -0
- package/src/web/TrackPlayer/SetupNotCalledError.ts +5 -0
- package/src/web/TrackPlayer/SleepTimer.ts +71 -0
- package/src/web/TrackPlayer/State.ts +15 -0
- package/src/web/TrackPlayer/index.ts +4 -0
- package/src/web/browser/BrowserManager.ts +642 -0
- package/src/web/browser/FavoriteManager.ts +77 -0
- package/src/web/browser/NavigationErrorManager.ts +112 -0
- package/src/web/browser/SearchManager.ts +82 -0
- package/src/web/http/HttpClient.ts +107 -0
- package/src/web/http/RequestConfigBuilder.ts +347 -0
- package/src/web/player/NowPlayingManager.ts +83 -0
- package/src/web/player/OptionsManager.ts +101 -0
- package/src/web/util/BrowserPathHelper.ts +147 -0
- package/src/web/util/shuffle.ts +14 -0
|
@@ -0,0 +1,1309 @@
|
|
|
1
|
+
import AVFoundation
|
|
2
|
+
import AVKit
|
|
3
|
+
import Foundation
|
|
4
|
+
import MediaPlayer
|
|
5
|
+
import NitroModules
|
|
6
|
+
import os.log
|
|
7
|
+
|
|
8
|
+
@MainActor let playerAndConfiguredBrowser = OnceValue<(HybridAudioBrowser, TrackPlayer)> {
|
|
9
|
+
guard let browser = HybridAudioBrowser.shared,
|
|
10
|
+
browser.browserManager.isConfigured,
|
|
11
|
+
let player = browser.getPlayer() else { return nil }
|
|
12
|
+
return (browser, player)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
|
|
16
|
+
private let logger = Logger(subsystem: "com.audiobrowser", category: "AudioBrowser")
|
|
17
|
+
|
|
18
|
+
// MARK: - Shared Instance for CarPlay
|
|
19
|
+
|
|
20
|
+
/// Shared instance for CarPlay access. Set when HybridAudioBrowser is created.
|
|
21
|
+
private(set) nonisolated(unsafe) weak static var shared: HybridAudioBrowser?
|
|
22
|
+
|
|
23
|
+
// MARK: - Private Properties
|
|
24
|
+
|
|
25
|
+
private var player: TrackPlayer?
|
|
26
|
+
private let networkMonitor = NetworkMonitor()
|
|
27
|
+
let browserManager = BrowserManager()
|
|
28
|
+
private var volumeObservation: NSKeyValueObservation?
|
|
29
|
+
private var routeChangeObserver: NSObjectProtocol?
|
|
30
|
+
private var nowPlayingOverride: NowPlayingUpdate?
|
|
31
|
+
private let playerOptions = PlayerUpdateOptions()
|
|
32
|
+
|
|
33
|
+
/// Configured playback rates for the playback-rate capability (for CarPlay rate cycling)
|
|
34
|
+
var playbackRates: [Double] { playerOptions.playbackRates }
|
|
35
|
+
private var lastNavigationError: NavigationError? {
|
|
36
|
+
didSet {
|
|
37
|
+
// Skip if both nil (no real change)
|
|
38
|
+
guard oldValue != nil || lastNavigationError != nil else { return }
|
|
39
|
+
navigationErrorEmitter.emit(NavigationErrorEvent(error: lastNavigationError))
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private var lastFormattedNavigationError: FormattedNavigationError? {
|
|
44
|
+
didSet {
|
|
45
|
+
// Skip if both nil (no real change)
|
|
46
|
+
guard oldValue != nil || lastFormattedNavigationError != nil else { return }
|
|
47
|
+
onFormattedNavigationError(lastFormattedNavigationError)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// MARK: - Internal Callbacks (for CarPlay/external controllers)
|
|
52
|
+
|
|
53
|
+
/// Called when notifyContentChanged is invoked, allowing CarPlay to refresh its templates.
|
|
54
|
+
/// Set by CarPlayController during setup.
|
|
55
|
+
var onExternalContentChanged: ((String) -> Void)?
|
|
56
|
+
|
|
57
|
+
// MARK: - Multi-Listener Emitters
|
|
58
|
+
|
|
59
|
+
/// Emitters allow multiple listeners for each event type, avoiding callback hijacking
|
|
60
|
+
public let tabsChangedEmitter = Emitter<[Track]>()
|
|
61
|
+
public let contentChangedEmitter = Emitter<ResolvedTrack?>()
|
|
62
|
+
public let favoriteChangedEmitter = Emitter<FavoriteChangedEvent>()
|
|
63
|
+
public let activeTrackChangedEmitter = Emitter<PlaybackActiveTrackChangedEvent>()
|
|
64
|
+
public let queueChangedEmitter = Emitter<[Track]>()
|
|
65
|
+
public let navigationErrorEmitter = Emitter<NavigationErrorEvent>()
|
|
66
|
+
public let repeatModeChangedEmitter = Emitter<RepeatModeChangedEvent>()
|
|
67
|
+
public let externalContentChangedEmitter = Emitter<String>()
|
|
68
|
+
|
|
69
|
+
// MARK: - Thread Safety
|
|
70
|
+
|
|
71
|
+
/// Executes a closure on the main actor synchronously, returning its result.
|
|
72
|
+
/// Uses MainActor.assumeIsolated when already on main thread, otherwise dispatches synchronously.
|
|
73
|
+
private func onMainActor<T: Sendable>(_ work: @MainActor () -> T) -> T {
|
|
74
|
+
if Thread.isMainThread {
|
|
75
|
+
MainActor.assumeIsolated { work() }
|
|
76
|
+
} else {
|
|
77
|
+
DispatchQueue.main.sync {
|
|
78
|
+
MainActor.assumeIsolated { work() }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/// Executes a throwing closure on the main actor synchronously.
|
|
84
|
+
private func onMainActor<T: Sendable>(_ work: @MainActor () throws -> T) throws -> T {
|
|
85
|
+
if Thread.isMainThread {
|
|
86
|
+
try MainActor.assumeIsolated { try work() }
|
|
87
|
+
} else {
|
|
88
|
+
try DispatchQueue.main.sync {
|
|
89
|
+
try MainActor.assumeIsolated { try work() }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// MARK: - Browser Properties
|
|
95
|
+
|
|
96
|
+
public var path: String? {
|
|
97
|
+
get { browserManager.getPath() }
|
|
98
|
+
set {
|
|
99
|
+
guard let newPath = newValue else { return }
|
|
100
|
+
Task {
|
|
101
|
+
do {
|
|
102
|
+
try await browserManager.navigate(newPath)
|
|
103
|
+
} catch {
|
|
104
|
+
handleNavigationError(error, path: newPath)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public var tabs: [Track]? {
|
|
111
|
+
get { browserManager.getTabs() }
|
|
112
|
+
set { /* tabs are managed internally by browserManager */ }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public var configuration: NativeBrowserConfiguration = .init(
|
|
116
|
+
path: nil, request: nil, media: nil, artwork: nil, routes: nil,
|
|
117
|
+
singleTrack: nil, androidControllerOfflineError: nil, carPlayUpNextButton: nil,
|
|
118
|
+
carPlayNowPlayingButtons: nil, formatNavigationError: nil,
|
|
119
|
+
) {
|
|
120
|
+
didSet {
|
|
121
|
+
browserManager.config = BrowserConfig(from: configuration)
|
|
122
|
+
|
|
123
|
+
// Query tabs and navigate to initial path after config is set (matches Kotlin behavior)
|
|
124
|
+
Task { @MainActor in
|
|
125
|
+
// Notify waiting listeners (e.g., CarPlay cold start)
|
|
126
|
+
playerAndConfiguredBrowser.check()
|
|
127
|
+
}
|
|
128
|
+
Task {
|
|
129
|
+
let tabs = try? await browserManager.queryTabs()
|
|
130
|
+
// Navigate to configured path, first tab, or "/"
|
|
131
|
+
let initialPath = configuration.path ?? tabs?.first?.url ?? "/"
|
|
132
|
+
// Clear error before navigation (matches Kotlin clearNavigationError())
|
|
133
|
+
await MainActor.run {
|
|
134
|
+
lastNavigationError = nil
|
|
135
|
+
lastFormattedNavigationError = nil
|
|
136
|
+
}
|
|
137
|
+
do {
|
|
138
|
+
try await browserManager.navigate(initialPath)
|
|
139
|
+
} catch {
|
|
140
|
+
handleNavigationError(error, path: initialPath)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// MARK: - Browser Callbacks
|
|
147
|
+
|
|
148
|
+
public var onPathChanged: (String) -> Void = { _ in }
|
|
149
|
+
public var onContentChanged: (ResolvedTrack?) -> Void = { _ in }
|
|
150
|
+
public var onTabsChanged: ([Track]) -> Void = { _ in }
|
|
151
|
+
public var onNavigationError: (NavigationErrorEvent) -> Void = { _ in }
|
|
152
|
+
public var onFormattedNavigationError: (FormattedNavigationError?) -> Void = { _ in }
|
|
153
|
+
|
|
154
|
+
// MARK: - Player Callbacks
|
|
155
|
+
|
|
156
|
+
public var onChapterMetadata: ([ChapterMetadata]) -> Void = { _ in }
|
|
157
|
+
public var onTrackMetadata: (TrackMetadata) -> Void = { _ in }
|
|
158
|
+
public var onTimedMetadata: (TimedMetadata) -> Void = { _ in }
|
|
159
|
+
public var onPlaybackActiveTrackChanged: (PlaybackActiveTrackChangedEvent) -> Void = { _ in }
|
|
160
|
+
public var onPlaybackError: (PlaybackErrorEvent) -> Void = { _ in }
|
|
161
|
+
public var onPlaybackPlayWhenReadyChanged: (PlaybackPlayWhenReadyChangedEvent) -> Void = { _ in }
|
|
162
|
+
public var onPlaybackPlayingState: (PlayingState) -> Void = { _ in }
|
|
163
|
+
public var onPlaybackProgressUpdated: (PlaybackProgressUpdatedEvent) -> Void = { _ in }
|
|
164
|
+
public var onPlaybackQueueEnded: (PlaybackQueueEndedEvent) -> Void = { _ in }
|
|
165
|
+
public var onPlaybackQueueChanged: ([Track]) -> Void = { _ in }
|
|
166
|
+
public var onPlaybackRepeatModeChanged: (RepeatModeChangedEvent) -> Void = { _ in }
|
|
167
|
+
public var onPlaybackShuffleModeChanged: (Bool) -> Void = { _ in }
|
|
168
|
+
public var onSleepTimerChanged: (SleepTimer?) -> Void = { _ in }
|
|
169
|
+
public var onPlaybackChanged: (Playback) -> Void = { _ in }
|
|
170
|
+
|
|
171
|
+
// MARK: - Remote Callbacks
|
|
172
|
+
|
|
173
|
+
public var onRemoteBookmark: () -> Void = {}
|
|
174
|
+
public var onRemoteDislike: () -> Void = {}
|
|
175
|
+
public var onRemoteJumpBackward: (RemoteJumpBackwardEvent) -> Void = { _ in }
|
|
176
|
+
public var onRemoteJumpForward: (RemoteJumpForwardEvent) -> Void = { _ in }
|
|
177
|
+
public var onRemoteLike: () -> Void = {}
|
|
178
|
+
public var onRemoteNext: () -> Void = {}
|
|
179
|
+
public var onRemotePause: () -> Void = {}
|
|
180
|
+
public var onRemotePlay: () -> Void = {}
|
|
181
|
+
public var onRemotePlayId: (RemotePlayIdEvent) -> Void = { _ in }
|
|
182
|
+
public var onRemotePlaySearch: (RemotePlaySearchEvent) -> Void = { _ in }
|
|
183
|
+
public var onRemotePrevious: () -> Void = {}
|
|
184
|
+
public var onRemoteSeek: (RemoteSeekEvent) -> Void = { _ in }
|
|
185
|
+
public var onRemoteSetRating: (RemoteSetRatingEvent) -> Void = { _ in }
|
|
186
|
+
public var onRemoteSkip: (RemoteSkipEvent) -> Void = { _ in }
|
|
187
|
+
public var onRemoteStop: () -> Void = {}
|
|
188
|
+
|
|
189
|
+
// MARK: - Remote Handlers (optional overrides from JS)
|
|
190
|
+
|
|
191
|
+
public var handleRemoteBookmark: (() -> Void)?
|
|
192
|
+
public var handleRemoteDislike: (() -> Void)?
|
|
193
|
+
public var handleRemoteJumpBackward: ((RemoteJumpBackwardEvent) -> Void)?
|
|
194
|
+
public var handleRemoteJumpForward: ((RemoteJumpForwardEvent) -> Void)?
|
|
195
|
+
public var handleRemoteLike: (() -> Void)?
|
|
196
|
+
public var handleRemoteNext: (() -> Void)?
|
|
197
|
+
public var handleRemotePause: (() -> Void)?
|
|
198
|
+
public var handleRemotePlay: (() -> Void)?
|
|
199
|
+
public var handleRemotePlayId: ((RemotePlayIdEvent) -> Void)?
|
|
200
|
+
public var handleRemotePlaySearch: ((RemotePlaySearchEvent) -> Void)?
|
|
201
|
+
public var handleRemotePrevious: (() -> Void)?
|
|
202
|
+
public var handleRemoteSeek: ((RemoteSeekEvent) -> Void)?
|
|
203
|
+
public var handleRemoteSkip: (() -> Void)?
|
|
204
|
+
public var handleRemoteStop: (() -> Void)?
|
|
205
|
+
|
|
206
|
+
// MARK: - Other Callbacks
|
|
207
|
+
|
|
208
|
+
public var onOptionsChanged: (Options) -> Void = { _ in }
|
|
209
|
+
public var onFavoriteChanged: (FavoriteChangedEvent) -> Void = { _ in }
|
|
210
|
+
public var onNowPlayingChanged: (NowPlayingMetadata) -> Void = { _ in }
|
|
211
|
+
public var onOnlineChanged: (Bool) -> Void = { _ in } {
|
|
212
|
+
didSet {
|
|
213
|
+
networkMonitor.onChanged = { [weak self] isOnline in
|
|
214
|
+
self?.onOnlineChanged(isOnline)
|
|
215
|
+
}
|
|
216
|
+
// Immediately notify current state
|
|
217
|
+
onOnlineChanged(networkMonitor.isOnline)
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public var onEqualizerChanged: (EqualizerSettings) -> Void = { _ in }
|
|
222
|
+
public var onBatteryWarningPendingChanged: (BatteryWarningPendingChangedEvent) -> Void = { _ in }
|
|
223
|
+
public var onBatteryOptimizationStatusChanged: (BatteryOptimizationStatusChangedEvent) -> Void = { _ in }
|
|
224
|
+
public var onSystemVolumeChanged: (Double) -> Void = { _ in } {
|
|
225
|
+
didSet {
|
|
226
|
+
setupVolumeObserver()
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
public var onIosOutputChanged: (IosOutput) -> Void = { _ in } {
|
|
230
|
+
didSet {
|
|
231
|
+
setupRouteChangeObserver()
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// MARK: - Initialization
|
|
236
|
+
|
|
237
|
+
override public init() {
|
|
238
|
+
super.init()
|
|
239
|
+
HybridAudioBrowser.shared = self
|
|
240
|
+
setupEmitterToNitroForwarding()
|
|
241
|
+
setupBrowserCallbacks()
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/// Returns the TrackPlayer instance, if setup has been called.
|
|
245
|
+
func getPlayer() -> TrackPlayer? {
|
|
246
|
+
player
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/// Sets up automatic forwarding from emitters to Nitro callbacks
|
|
250
|
+
private func setupEmitterToNitroForwarding() {
|
|
251
|
+
tabsChangedEmitter.addListener { [weak self] tabs in
|
|
252
|
+
self?.onTabsChanged(tabs)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
contentChangedEmitter.addListener { [weak self] content in
|
|
256
|
+
self?.onContentChanged(content)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
favoriteChangedEmitter.addListener { [weak self] event in
|
|
260
|
+
self?.onFavoriteChanged(event)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
activeTrackChangedEmitter.addListener { [weak self] event in
|
|
264
|
+
self?.onPlaybackActiveTrackChanged(event)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
queueChangedEmitter.addListener { [weak self] tracks in
|
|
268
|
+
self?.onPlaybackQueueChanged(tracks)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
navigationErrorEmitter.addListener { [weak self] event in
|
|
272
|
+
self?.onNavigationError(event)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
repeatModeChangedEmitter.addListener { [weak self] event in
|
|
276
|
+
self?.onPlaybackRepeatModeChanged(event)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private func setupBrowserCallbacks() {
|
|
281
|
+
browserManager.onPathChanged = { [weak self] path in
|
|
282
|
+
self?.onPathChanged(path)
|
|
283
|
+
}
|
|
284
|
+
browserManager.onContentChanged = { [weak self] content in
|
|
285
|
+
self?.contentChangedEmitter.emit(content)
|
|
286
|
+
}
|
|
287
|
+
browserManager.onTabsChanged = { [weak self] tabs in
|
|
288
|
+
self?.tabsChangedEmitter.emit(tabs)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Configure artwork URL resolver for transforming artwork URLs during browsing
|
|
292
|
+
browserManager.artworkUrlResolver = { [weak browserManager] track, artworkConfig, imageContext in
|
|
293
|
+
guard let browserManager else { return nil }
|
|
294
|
+
return await browserManager.resolveArtworkUrl(track: track, perRouteConfig: artworkConfig, imageContext: imageContext)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private func handleNavigationError(_ error: Error, path: String) {
|
|
299
|
+
let navError = if let browserError = error as? BrowserError {
|
|
300
|
+
switch browserError {
|
|
301
|
+
case .contentNotFound:
|
|
302
|
+
NavigationError(code: .contentNotFound, message: browserError.localizedDescription, statusCode: nil, statusCodeSuccess: nil)
|
|
303
|
+
case let .httpError(code, _):
|
|
304
|
+
NavigationError(code: .httpError, message: browserError.localizedDescription, statusCode: Double(code), statusCodeSuccess: (200 ... 299).contains(code))
|
|
305
|
+
case .networkError:
|
|
306
|
+
NavigationError(code: .networkError, message: browserError.localizedDescription, statusCode: nil, statusCodeSuccess: nil)
|
|
307
|
+
case .invalidConfiguration:
|
|
308
|
+
NavigationError(code: .unknownError, message: browserError.localizedDescription, statusCode: nil, statusCodeSuccess: nil)
|
|
309
|
+
case .callbackError:
|
|
310
|
+
NavigationError(code: .callbackError, message: browserError.localizedDescription, statusCode: nil, statusCodeSuccess: nil)
|
|
311
|
+
}
|
|
312
|
+
} else if let httpError = error as? HttpClient.HttpException {
|
|
313
|
+
// HTTP error from HttpClient (non-2xx response)
|
|
314
|
+
NavigationError(code: .httpError, message: httpError.localizedDescription, statusCode: Double(httpError.code), statusCodeSuccess: (200 ... 299).contains(httpError.code))
|
|
315
|
+
} else if error is URLError {
|
|
316
|
+
// Network error (connection failed, timeout, no internet, etc.)
|
|
317
|
+
NavigationError(code: .networkError, message: error.localizedDescription, statusCode: nil, statusCodeSuccess: nil)
|
|
318
|
+
} else {
|
|
319
|
+
NavigationError(code: .unknownError, message: error.localizedDescription, statusCode: nil, statusCodeSuccess: nil)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
lastNavigationError = navError
|
|
323
|
+
|
|
324
|
+
// Format the error (async if using JS callback, sync for defaults)
|
|
325
|
+
let defaultFormatted = defaultFormattedError(navError)
|
|
326
|
+
if let formatter = browserManager.config.formatNavigationError {
|
|
327
|
+
let params = FormatNavigationErrorParams(error: navError, defaultFormatted: defaultFormatted, path: path)
|
|
328
|
+
formatter(params)
|
|
329
|
+
.then { [weak self] customDisplay in
|
|
330
|
+
self?.lastFormattedNavigationError = customDisplay ?? defaultFormatted
|
|
331
|
+
}
|
|
332
|
+
.catch { [weak self] _ in
|
|
333
|
+
self?.lastFormattedNavigationError = defaultFormatted
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
lastFormattedNavigationError = defaultFormatted
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private func defaultFormattedError(_ error: NavigationError) -> FormattedNavigationError {
|
|
341
|
+
let title: String = switch error.code {
|
|
342
|
+
case .contentNotFound:
|
|
343
|
+
"Content Not Found"
|
|
344
|
+
case .networkError:
|
|
345
|
+
"Network Error"
|
|
346
|
+
case .httpError:
|
|
347
|
+
if let statusCode = error.statusCode {
|
|
348
|
+
// Use system-localized HTTP status text (e.g., "Not Found", "Service Unavailable")
|
|
349
|
+
HTTPURLResponse.localizedString(forStatusCode: Int(statusCode)).capitalized
|
|
350
|
+
} else {
|
|
351
|
+
"Server Error"
|
|
352
|
+
}
|
|
353
|
+
case .callbackError:
|
|
354
|
+
"Error"
|
|
355
|
+
case .unknownError:
|
|
356
|
+
"Error"
|
|
357
|
+
}
|
|
358
|
+
return FormattedNavigationError(title: title, message: error.message)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// MARK: - Browser Methods
|
|
362
|
+
|
|
363
|
+
public func navigatePath(path: String) throws {
|
|
364
|
+
// Clear error synchronously before starting navigation (didSet notifies JS)
|
|
365
|
+
lastNavigationError = nil
|
|
366
|
+
lastFormattedNavigationError = nil
|
|
367
|
+
Task {
|
|
368
|
+
do {
|
|
369
|
+
try await browserManager.navigate(path)
|
|
370
|
+
} catch {
|
|
371
|
+
handleNavigationError(error, path: path)
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
public func navigateTrack(track: Track) throws {
|
|
377
|
+
let url = track.url
|
|
378
|
+
|
|
379
|
+
// Check if this is a contextual URL (playable-only track with queue context)
|
|
380
|
+
if let url, BrowserPathHelper.isContextual(url) {
|
|
381
|
+
let parentPath = BrowserPathHelper.stripTrackId(url)
|
|
382
|
+
let trackId = BrowserPathHelper.extractTrackId(url)
|
|
383
|
+
|
|
384
|
+
// Check if queue already came from this parent path - just skip to the track
|
|
385
|
+
let existingIndex: Int? = onMainActor {
|
|
386
|
+
guard let trackId,
|
|
387
|
+
parentPath == player?.queueSourcePath,
|
|
388
|
+
let index = player?.tracks.firstIndex(where: { $0.src == trackId })
|
|
389
|
+
else { return nil }
|
|
390
|
+
return index
|
|
391
|
+
}
|
|
392
|
+
if let index = existingIndex {
|
|
393
|
+
logger.debug("Queue already from \(parentPath), skipping to index \(index)")
|
|
394
|
+
onMainActor {
|
|
395
|
+
try? player?.skipTo(index, playWhenReady: true)
|
|
396
|
+
}
|
|
397
|
+
return
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
Task {
|
|
401
|
+
do {
|
|
402
|
+
// Expand the queue from the contextual URL
|
|
403
|
+
if let expanded = try await browserManager.expandQueueFromContextualUrl(url) {
|
|
404
|
+
let (tracks, startIndex) = expanded
|
|
405
|
+
|
|
406
|
+
// Replace queue and start at the selected track (auto-play)
|
|
407
|
+
await MainActor.run {
|
|
408
|
+
player?.setQueue(tracks, initialIndex: startIndex, playWhenReady: true, sourcePath: parentPath)
|
|
409
|
+
}
|
|
410
|
+
} else {
|
|
411
|
+
// Fallback: just load the single track (auto-play)
|
|
412
|
+
await MainActor.run {
|
|
413
|
+
player?.load(track, playWhenReady: true)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
} catch {
|
|
417
|
+
logger.error("Error expanding queue: \(error.localizedDescription)")
|
|
418
|
+
// Fallback to single track (auto-play) - playback errors reported via TrackPlayer callbacks
|
|
419
|
+
await MainActor.run {
|
|
420
|
+
player?.load(track, playWhenReady: true)
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// If track has src, it's playable - load and auto-play
|
|
426
|
+
else if track.src != nil {
|
|
427
|
+
onMainActor {
|
|
428
|
+
player?.load(track, playWhenReady: true)
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// If track has url, it's browsable - navigate to it
|
|
432
|
+
else if let url {
|
|
433
|
+
// Clear error synchronously before starting navigation (didSet notifies JS)
|
|
434
|
+
lastNavigationError = nil
|
|
435
|
+
lastFormattedNavigationError = nil
|
|
436
|
+
Task {
|
|
437
|
+
do {
|
|
438
|
+
try await browserManager.navigate(url)
|
|
439
|
+
} catch {
|
|
440
|
+
handleNavigationError(error, path: url)
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
public func onSearch(query: String) throws -> Promise<[Track]> {
|
|
447
|
+
Promise.async { [weak self] in
|
|
448
|
+
guard let self else { return [] }
|
|
449
|
+
let resolved = try await browserManager.search(query)
|
|
450
|
+
return resolved.children ?? []
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
public func getContent() throws -> ResolvedTrack? {
|
|
455
|
+
browserManager.getContent()
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
public func getNavigationError() throws -> NavigationError? {
|
|
459
|
+
lastNavigationError
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
public func getFormattedNavigationError() throws -> FormattedNavigationError? {
|
|
463
|
+
lastFormattedNavigationError
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
public func notifyContentChanged(path: String) throws {
|
|
467
|
+
browserManager.invalidateContentCache(path)
|
|
468
|
+
|
|
469
|
+
// Notify external controllers (CarPlay) that content changed
|
|
470
|
+
onExternalContentChanged?(path)
|
|
471
|
+
externalContentChangedEmitter.emit(path)
|
|
472
|
+
|
|
473
|
+
// Re-resolve the path if it's the current browser path
|
|
474
|
+
if browserManager.getPath() == path {
|
|
475
|
+
Task {
|
|
476
|
+
do {
|
|
477
|
+
try await browserManager.navigate(path)
|
|
478
|
+
} catch {
|
|
479
|
+
handleNavigationError(error, path: path)
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
public func setFavorites(favorites: [String]) throws {
|
|
486
|
+
browserManager.setFavorites(favorites)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// MARK: - Player Setup
|
|
490
|
+
|
|
491
|
+
public func setupPlayer(options: PartialSetupPlayerOptions) throws -> Promise<Void> {
|
|
492
|
+
Promise.async {
|
|
493
|
+
// Configure audio session
|
|
494
|
+
let session = AVAudioSession.sharedInstance()
|
|
495
|
+
try session.setCategory(.playback, mode: .default)
|
|
496
|
+
try session.setActive(true)
|
|
497
|
+
|
|
498
|
+
// Create player and configure on main actor
|
|
499
|
+
await MainActor.run { [weak self] in
|
|
500
|
+
guard let self else { return }
|
|
501
|
+
|
|
502
|
+
// Create player with self as callbacks delegate
|
|
503
|
+
player = TrackPlayer(callbacks: self)
|
|
504
|
+
|
|
505
|
+
// Apply buffer duration from options (in ms)
|
|
506
|
+
if let buffer = options.ios?.buffer {
|
|
507
|
+
player?.bufferDuration = buffer
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Apply retry configuration (top-level, cross-platform)
|
|
511
|
+
if let retry = options.retry {
|
|
512
|
+
player?.retryConfig = retry
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Wire up network monitor for accelerated retries when connectivity is restored
|
|
516
|
+
player?.networkMonitor = networkMonitor
|
|
517
|
+
|
|
518
|
+
// Configure media URL resolver
|
|
519
|
+
player?.mediaUrlResolver = { [weak self] src in
|
|
520
|
+
guard let self else {
|
|
521
|
+
return MediaResolvedUrl(url: src, headers: nil, userAgent: nil)
|
|
522
|
+
}
|
|
523
|
+
return await browserManager.resolveMediaUrl(src)
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Configure artwork URL resolver for Now Playing (with size context)
|
|
527
|
+
player?.artworkUrlResolver = { [weak self] track, imageContext in
|
|
528
|
+
guard let self else { return nil }
|
|
529
|
+
return await browserManager.resolveArtworkUrl(track: track, perRouteConfig: nil, imageContext: imageContext)
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Configure sleep timer callback
|
|
533
|
+
player?.sleepTimerManager.onChanged = { [weak self] state in
|
|
534
|
+
self?.onSleepTimerChanged(state)
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Apply default remote commands (play, pause, next, previous, seekTo)
|
|
538
|
+
applyRemoteCommands()
|
|
539
|
+
|
|
540
|
+
// Notify listeners that player is ready (e.g., CarPlay)
|
|
541
|
+
playerAndConfiguredBrowser.check()
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
public func updateOptions(options: NativeUpdateOptions) {
|
|
547
|
+
onMainActor {
|
|
548
|
+
// Update stored options
|
|
549
|
+
playerOptions.update(from: options)
|
|
550
|
+
|
|
551
|
+
// Apply remote commands to player
|
|
552
|
+
applyRemoteCommands()
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/// Converts capabilities to remote commands and applies them to the player
|
|
557
|
+
@MainActor
|
|
558
|
+
private func applyRemoteCommands() {
|
|
559
|
+
guard let player else { return }
|
|
560
|
+
|
|
561
|
+
let remoteCommands = playerOptions.capabilities.buildRemoteCommands(
|
|
562
|
+
forwardJumpInterval: NSNumber(value: playerOptions.forwardJumpInterval),
|
|
563
|
+
backwardJumpInterval: NSNumber(value: playerOptions.backwardJumpInterval),
|
|
564
|
+
playbackRates: playerOptions.playbackRates,
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
player.remoteCommands = remoteCommands
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
public func getOptions() throws -> UpdateOptions {
|
|
571
|
+
playerOptions.toUpdateOptions()
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// MARK: - Playback Control
|
|
575
|
+
|
|
576
|
+
public func load(track: Track) throws {
|
|
577
|
+
try onMainActor {
|
|
578
|
+
guard let player else {
|
|
579
|
+
throw NSError(domain: "AudioBrowser", code: 1, userInfo: [NSLocalizedDescriptionKey: "Player not initialized"])
|
|
580
|
+
}
|
|
581
|
+
player.load(track)
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
public func reset() throws {
|
|
586
|
+
onMainActor { player?.clear() }
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
public func play() throws {
|
|
590
|
+
onMainActor { player?.play() }
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
public func pause() throws {
|
|
594
|
+
onMainActor { player?.pause() }
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
public func togglePlayback() throws {
|
|
598
|
+
onMainActor { player?.togglePlayback() }
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
public func stop() throws {
|
|
602
|
+
onMainActor { player?.stop() }
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
public func setPlayWhenReady(playWhenReady: Bool) throws {
|
|
606
|
+
onMainActor { player?.playWhenReady = playWhenReady }
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
public func getPlayWhenReady() throws -> Bool {
|
|
610
|
+
onMainActor { player?.playWhenReady ?? false }
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
public func seekTo(position: Double) throws {
|
|
614
|
+
onMainActor { player?.seekTo(position) }
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
public func seekBy(offset: Double) throws {
|
|
618
|
+
onMainActor { player?.seekBy(offset) }
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
public func setVolume(level: Double) throws {
|
|
622
|
+
onMainActor { player?.volume = Float(level) }
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
public func getVolume() throws -> Double {
|
|
626
|
+
onMainActor { Double(player?.volume ?? 1.0) }
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
public func setRate(rate: Double) throws {
|
|
630
|
+
onMainActor { player?.rate = Float(rate) }
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
public func getRate() throws -> Double {
|
|
634
|
+
onMainActor { Double(player?.rate ?? 1.0) }
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
public func getProgress() throws -> Progress {
|
|
638
|
+
onMainActor {
|
|
639
|
+
Progress(
|
|
640
|
+
position: player?.currentTime ?? 0,
|
|
641
|
+
duration: player?.duration ?? 0,
|
|
642
|
+
buffered: player?.bufferedPosition ?? 0,
|
|
643
|
+
)
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
public func getPlayback() throws -> Playback {
|
|
648
|
+
onMainActor { player?.getPlayback() ?? Playback(state: .none, error: nil) }
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
public func getPlayingState() throws -> PlayingState {
|
|
652
|
+
onMainActor {
|
|
653
|
+
player?.playingStateManager.toPlayingState() ?? PlayingState(playing: false, buffering: false)
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
public func getRepeatMode() throws -> RepeatMode {
|
|
658
|
+
onMainActor { player?.repeatMode ?? .off }
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
public func setRepeatMode(mode: RepeatMode) throws {
|
|
662
|
+
onMainActor { player?.repeatMode = mode }
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
public func getShuffleEnabled() throws -> Bool {
|
|
666
|
+
onMainActor { player?.shuffleEnabled ?? false }
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
public func setShuffleEnabled(enabled: Bool) throws {
|
|
670
|
+
onMainActor { player?.shuffleEnabled = enabled }
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
public func getPlaybackError() throws -> PlaybackError? {
|
|
674
|
+
onMainActor { player?.playbackError?.toNitroError() }
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
public func retry() throws {
|
|
678
|
+
onMainActor { player?.reload(startFromCurrentTime: true) }
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// MARK: - Sleep Timer
|
|
682
|
+
|
|
683
|
+
public func getSleepTimer() throws -> SleepTimer {
|
|
684
|
+
onMainActor {
|
|
685
|
+
if let state = player?.sleepTimerManager.get() {
|
|
686
|
+
return state
|
|
687
|
+
}
|
|
688
|
+
return .first(NullType.null)
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
public func setSleepTimer(seconds: Double) throws {
|
|
693
|
+
onMainActor {
|
|
694
|
+
player?.sleepTimerManager.set(seconds: seconds)
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
public func setSleepTimerToEndOfTrack() throws {
|
|
699
|
+
onMainActor {
|
|
700
|
+
player?.sleepTimerManager.setToEndOfTrack()
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
public func clearSleepTimer() throws -> Bool {
|
|
705
|
+
onMainActor {
|
|
706
|
+
player?.sleepTimerManager.clear() ?? false
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// MARK: - Queue Management
|
|
711
|
+
|
|
712
|
+
public func add(tracks: [Track], insertBeforeIndex: Double?) throws {
|
|
713
|
+
try onMainActor {
|
|
714
|
+
guard let player else { return }
|
|
715
|
+
if let index = insertBeforeIndex {
|
|
716
|
+
try player.add(tracks, at: Int(index))
|
|
717
|
+
} else {
|
|
718
|
+
player.add(tracks)
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
public func move(fromIndex: Double, toIndex: Double) throws {
|
|
724
|
+
try onMainActor {
|
|
725
|
+
try player?.move(fromIndex: Int(fromIndex), toIndex: Int(toIndex))
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
public func remove(indexes: [Double]) throws {
|
|
730
|
+
try onMainActor {
|
|
731
|
+
guard let player else { return }
|
|
732
|
+
// Remove in reverse order to maintain index validity
|
|
733
|
+
for index in indexes.sorted().reversed() {
|
|
734
|
+
try player.remove(Int(index))
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
public func removeUpcomingTracks() throws {
|
|
740
|
+
onMainActor { player?.removeUpcomingTracks() }
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
public func skip(index: Double, initialPosition: Double?) throws {
|
|
744
|
+
try onMainActor {
|
|
745
|
+
try player?.skipTo(Int(index))
|
|
746
|
+
if let position = initialPosition {
|
|
747
|
+
player?.seekTo(position)
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
public func skipToNext(initialPosition: Double?) throws {
|
|
753
|
+
onMainActor {
|
|
754
|
+
player?.next()
|
|
755
|
+
if let position = initialPosition {
|
|
756
|
+
player?.seekTo(position)
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
public func skipToPrevious(initialPosition: Double?) throws {
|
|
762
|
+
onMainActor {
|
|
763
|
+
player?.previous()
|
|
764
|
+
if let position = initialPosition {
|
|
765
|
+
player?.seekTo(position)
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
public func setActiveTrackFavorited(favorited: Bool) throws {
|
|
771
|
+
onMainActor {
|
|
772
|
+
guard let track = player?.currentTrack, let src = track.src else { return }
|
|
773
|
+
guard let index = player?.currentIndex, index >= 0 else { return }
|
|
774
|
+
browserManager.updateFavorite(id: src, favorited: favorited)
|
|
775
|
+
// Create updated track with new favorited state
|
|
776
|
+
let updatedTrack = Track(
|
|
777
|
+
url: track.url,
|
|
778
|
+
src: track.src,
|
|
779
|
+
artwork: track.artwork,
|
|
780
|
+
artworkSource: track.artworkSource,
|
|
781
|
+
artworkCarPlayTinted: track.artworkCarPlayTinted,
|
|
782
|
+
title: track.title,
|
|
783
|
+
subtitle: track.subtitle,
|
|
784
|
+
artist: track.artist,
|
|
785
|
+
album: track.album,
|
|
786
|
+
description: track.description,
|
|
787
|
+
genre: track.genre,
|
|
788
|
+
duration: track.duration,
|
|
789
|
+
style: track.style,
|
|
790
|
+
childrenStyle: track.childrenStyle,
|
|
791
|
+
favorited: favorited,
|
|
792
|
+
groupTitle: track.groupTitle,
|
|
793
|
+
live: track.live,
|
|
794
|
+
)
|
|
795
|
+
// Update the track in the player's queue so getActiveTrack() returns correct state
|
|
796
|
+
player?.setTrack(at: index, updatedTrack)
|
|
797
|
+
favoriteChangedEmitter.emit(FavoriteChangedEvent(track: updatedTrack, favorited: favorited))
|
|
798
|
+
// Fire active track changed so useActiveTrack() hook updates UI
|
|
799
|
+
let position = player?.currentTime ?? 0
|
|
800
|
+
activeTrackChangedEmitter.emit(PlaybackActiveTrackChangedEvent(
|
|
801
|
+
lastIndex: Double(index),
|
|
802
|
+
lastTrack: track,
|
|
803
|
+
lastPosition: position,
|
|
804
|
+
index: Double(index),
|
|
805
|
+
track: updatedTrack,
|
|
806
|
+
))
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
public func toggleActiveTrackFavorited() throws {
|
|
811
|
+
onMainActor {
|
|
812
|
+
guard let track = player?.currentTrack, let src = track.src else { return }
|
|
813
|
+
// Check current favorited state from cache
|
|
814
|
+
let currentTrack = browserManager.getCachedTrack(src)
|
|
815
|
+
let isFavorited = currentTrack?.favorited ?? track.favorited ?? false
|
|
816
|
+
try? setActiveTrackFavorited(favorited: !isFavorited)
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
public func setQueue(tracks: [Track], startIndex: Double?, startPositionMs: Double?) throws {
|
|
821
|
+
try onMainActor {
|
|
822
|
+
guard let player else { return }
|
|
823
|
+
player.clear()
|
|
824
|
+
player.add(tracks)
|
|
825
|
+
if let index = startIndex, index >= 0 {
|
|
826
|
+
try player.skipTo(Int(index))
|
|
827
|
+
}
|
|
828
|
+
if let position = startPositionMs {
|
|
829
|
+
player.seekTo(position / 1000.0)
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
public func getQueue() throws -> [Track] {
|
|
835
|
+
onMainActor { player?.tracks ?? [] }
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
public func getTrack(index: Double) throws -> Track? {
|
|
839
|
+
onMainActor {
|
|
840
|
+
guard let tracks = player?.tracks else { return nil }
|
|
841
|
+
let i = Int(index)
|
|
842
|
+
guard i >= 0, i < tracks.count else { return nil }
|
|
843
|
+
return tracks[i]
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
public func getActiveTrackIndex() throws -> Double? {
|
|
848
|
+
onMainActor {
|
|
849
|
+
guard let index = player?.currentIndex, index >= 0 else { return nil }
|
|
850
|
+
return Double(index)
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
public func getActiveTrack() throws -> Track? {
|
|
855
|
+
onMainActor { player?.currentTrack }
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// MARK: - Now Playing
|
|
859
|
+
|
|
860
|
+
public func updateNowPlaying(update: NowPlayingUpdate?) throws {
|
|
861
|
+
onMainActor {
|
|
862
|
+
nowPlayingOverride = update
|
|
863
|
+
applyNowPlayingMetadata()
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
public func getNowPlaying() throws -> NowPlayingMetadata? {
|
|
868
|
+
onMainActor {
|
|
869
|
+
guard let track = player?.currentTrack else { return nil }
|
|
870
|
+
let override = nowPlayingOverride
|
|
871
|
+
return NowPlayingMetadata(
|
|
872
|
+
elapsedTime: player?.currentTime,
|
|
873
|
+
title: override?.title ?? track.title,
|
|
874
|
+
album: track.album,
|
|
875
|
+
artist: override?.artist ?? track.artist,
|
|
876
|
+
duration: track.duration,
|
|
877
|
+
artwork: track.artwork,
|
|
878
|
+
description: track.description,
|
|
879
|
+
mediaId: track.src ?? track.url,
|
|
880
|
+
genre: track.genre,
|
|
881
|
+
rating: nil,
|
|
882
|
+
)
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/// Applies the current now playing metadata (with override if set) to NowPlayingInfoCenter and notifies JS.
|
|
887
|
+
@MainActor
|
|
888
|
+
private func applyNowPlayingMetadata() {
|
|
889
|
+
guard let track = player?.currentTrack else { return }
|
|
890
|
+
let override = nowPlayingOverride
|
|
891
|
+
|
|
892
|
+
let nowPlaying = NowPlayingMetadata(
|
|
893
|
+
elapsedTime: player?.currentTime,
|
|
894
|
+
title: override?.title ?? track.title,
|
|
895
|
+
album: track.album,
|
|
896
|
+
artist: override?.artist ?? track.artist,
|
|
897
|
+
duration: track.duration,
|
|
898
|
+
artwork: track.artwork,
|
|
899
|
+
description: track.description,
|
|
900
|
+
mediaId: track.src ?? track.url,
|
|
901
|
+
genre: track.genre,
|
|
902
|
+
rating: nil,
|
|
903
|
+
)
|
|
904
|
+
|
|
905
|
+
// Update NowPlayingInfoCenter with override values
|
|
906
|
+
if let override {
|
|
907
|
+
player?.nowPlayingInfoController.set(keyValue: MediaItemProperty.title(override.title ?? track.title))
|
|
908
|
+
player?.nowPlayingInfoController.set(keyValue: MediaItemProperty.artist(override.artist ?? track.artist))
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
onNowPlayingChanged(nowPlaying)
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// MARK: - Network
|
|
915
|
+
|
|
916
|
+
public func getOnline() throws -> Bool {
|
|
917
|
+
networkMonitor.getOnline()
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// MARK: - System Volume
|
|
921
|
+
|
|
922
|
+
/// Sets up KVO observer for system volume changes
|
|
923
|
+
private func setupVolumeObserver() {
|
|
924
|
+
// Remove existing observation if any
|
|
925
|
+
volumeObservation?.invalidate()
|
|
926
|
+
|
|
927
|
+
let audioSession = AVAudioSession.sharedInstance()
|
|
928
|
+
volumeObservation = audioSession.observe(\.outputVolume, options: [.new]) { [weak self] _, change in
|
|
929
|
+
guard let newVolume = change.newValue else { return }
|
|
930
|
+
self?.onSystemVolumeChanged(Double(newVolume))
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
public func getSystemVolume() throws -> Double {
|
|
935
|
+
Double(AVAudioSession.sharedInstance().outputVolume)
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
public func setSystemVolume(volume _: Double) throws {
|
|
939
|
+
// iOS doesn't provide a public API to set system volume programmatically.
|
|
940
|
+
// Users must adjust volume via hardware buttons or Control Center.
|
|
941
|
+
logger.debug("setSystemVolume is not supported on iOS - volume must be adjusted via hardware buttons or Control Center")
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// MARK: - External Audio Output
|
|
945
|
+
|
|
946
|
+
/// Sets up observer for audio route changes
|
|
947
|
+
private func setupRouteChangeObserver() {
|
|
948
|
+
if let observer = routeChangeObserver {
|
|
949
|
+
NotificationCenter.default.removeObserver(observer)
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
routeChangeObserver = NotificationCenter.default.addObserver(
|
|
953
|
+
forName: AVAudioSession.routeChangeNotification,
|
|
954
|
+
object: nil,
|
|
955
|
+
queue: .main
|
|
956
|
+
) { [weak self] _ in
|
|
957
|
+
guard let self, let output = self.getCurrentOutput() else { return }
|
|
958
|
+
self.onIosOutputChanged(output)
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/// Gets the current audio output info
|
|
963
|
+
private func getCurrentOutput() -> IosOutput? {
|
|
964
|
+
let session = AVAudioSession.sharedInstance()
|
|
965
|
+
guard let output = session.currentRoute.outputs.first else { return nil }
|
|
966
|
+
|
|
967
|
+
let (outputType, external): (IosOutputType, Bool) = switch output.portType {
|
|
968
|
+
case .builtInSpeaker:
|
|
969
|
+
(.builtInSpeaker, false)
|
|
970
|
+
case .builtInReceiver:
|
|
971
|
+
(.builtInReceiver, false)
|
|
972
|
+
case .airPlay:
|
|
973
|
+
(.airplay, true)
|
|
974
|
+
case .bluetoothA2DP:
|
|
975
|
+
(.bluetoothA2dp, true)
|
|
976
|
+
case .bluetoothHFP:
|
|
977
|
+
(.bluetoothHfp, true)
|
|
978
|
+
case .bluetoothLE:
|
|
979
|
+
(.bluetoothLe, true)
|
|
980
|
+
case .headphones:
|
|
981
|
+
(.headphones, true)
|
|
982
|
+
case .carAudio:
|
|
983
|
+
(.carAudio, true)
|
|
984
|
+
case .HDMI:
|
|
985
|
+
(.hdmi, true)
|
|
986
|
+
case .usbAudio:
|
|
987
|
+
(.usbAudio, true)
|
|
988
|
+
default:
|
|
989
|
+
(.other, true)
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
return IosOutput(type: outputType, name: output.portName, external: external)
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
public func getIosOutput() throws -> IosOutput? {
|
|
996
|
+
getCurrentOutput()
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
public func openIosOutputPicker() throws {
|
|
1000
|
+
DispatchQueue.main.async { [weak self] in
|
|
1001
|
+
guard let windowScene = UIApplication.shared.connectedScenes
|
|
1002
|
+
.compactMap({ $0 as? UIWindowScene })
|
|
1003
|
+
.first(where: { $0.activationState == .foregroundActive }),
|
|
1004
|
+
let window = windowScene.windows.first(where: { $0.isKeyWindow })
|
|
1005
|
+
else {
|
|
1006
|
+
self?.logger.debug("openIosOutputPicker: Could not find active window scene")
|
|
1007
|
+
return
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
let routePicker = AVRoutePickerView(frame: .zero)
|
|
1011
|
+
routePicker.isHidden = true
|
|
1012
|
+
window.addSubview(routePicker)
|
|
1013
|
+
|
|
1014
|
+
// Find the button inside AVRoutePickerView and trigger it
|
|
1015
|
+
for subview in routePicker.subviews {
|
|
1016
|
+
if let button = subview as? UIButton {
|
|
1017
|
+
button.sendActions(for: .touchUpInside)
|
|
1018
|
+
break
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
// Remove after a delay to ensure picker has opened
|
|
1023
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
1024
|
+
routePicker.removeFromSuperview()
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// MARK: - Equalizer (unsupported on iOS)
|
|
1030
|
+
|
|
1031
|
+
public func getEqualizerSettings() throws -> EqualizerSettings? {
|
|
1032
|
+
// No-op: equalizer unsupported on iOS
|
|
1033
|
+
nil
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
public func setEqualizerEnabled(enabled _: Bool) throws {
|
|
1037
|
+
// No-op: equalizer unsupported on iOS
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
public func setEqualizerPreset(preset _: String) throws {
|
|
1041
|
+
// No-op: equalizer unsupported on iOS
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
public func setEqualizerLevels(levels _: [Double]) throws {
|
|
1045
|
+
// No-op: equalizer unsupported on iOS
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// MARK: - Battery (Android-only, stub implementations)
|
|
1049
|
+
|
|
1050
|
+
public func getBatteryWarningPending() throws -> Bool {
|
|
1051
|
+
false
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
public func getBatteryOptimizationStatus() throws -> BatteryOptimizationStatus {
|
|
1055
|
+
// iOS doesn't have battery optimization restrictions like Android
|
|
1056
|
+
.unrestricted
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
public func dismissBatteryWarning() throws {
|
|
1060
|
+
// No-op on iOS
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
public func openBatterySettings() throws {
|
|
1064
|
+
// No-op on iOS
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// MARK: - TrackPlayerCallbacks
|
|
1069
|
+
|
|
1070
|
+
extension HybridAudioBrowser: TrackPlayerCallbacks {
|
|
1071
|
+
public func playerDidChangePlayback(_ playback: Playback) {
|
|
1072
|
+
onPlaybackChanged(playback)
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
public func playerDidChangeActiveTrack(_ event: PlaybackActiveTrackChangedEvent) {
|
|
1076
|
+
// Clear now playing override when track changes (matches Kotlin behavior)
|
|
1077
|
+
nowPlayingOverride = nil
|
|
1078
|
+
activeTrackChangedEmitter.emit(event)
|
|
1079
|
+
// Also notify now playing changed when track changes
|
|
1080
|
+
applyNowPlayingMetadata()
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
public func playerDidUpdateProgress(_ event: PlaybackProgressUpdatedEvent) {
|
|
1084
|
+
onPlaybackProgressUpdated(event)
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
public func playerDidChangePlayWhenReady(_ playWhenReady: Bool) {
|
|
1088
|
+
onPlaybackPlayWhenReadyChanged(PlaybackPlayWhenReadyChangedEvent(playWhenReady: playWhenReady))
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
public func playerDidChangePlayingState(_ state: PlayingState) {
|
|
1092
|
+
onPlaybackPlayingState(state)
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
public func playerDidEndQueue(_ event: PlaybackQueueEndedEvent) {
|
|
1096
|
+
onPlaybackQueueEnded(event)
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
public func playerDidChangeQueue(_ tracks: [Track]) {
|
|
1100
|
+
queueChangedEmitter.emit(tracks)
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
public func playerDidChangeRepeatMode(_ event: RepeatModeChangedEvent) {
|
|
1104
|
+
repeatModeChangedEmitter.emit(event)
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
public func playerDidChangeShuffleEnabled(_ enabled: Bool) {
|
|
1108
|
+
onPlaybackShuffleModeChanged(enabled)
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
public func playerDidError(_ event: PlaybackErrorEvent) {
|
|
1112
|
+
onPlaybackError(event)
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
public func playerDidReceiveCommonMetadata(_ items: [AVMetadataItem]) {
|
|
1116
|
+
let metadata = TrackMetadata.from(items: items)
|
|
1117
|
+
onTrackMetadata(metadata)
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
public func playerDidReceiveTimedMetadata(_ groups: [AVTimedMetadataGroup]) {
|
|
1121
|
+
for group in groups {
|
|
1122
|
+
if let metadata = TimedMetadata.from(items: group.items) {
|
|
1123
|
+
onTimedMetadata(metadata)
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
public func playerDidReceiveChapterMetadata(_ groups: [AVTimedMetadataGroup]) {
|
|
1129
|
+
let chapters = ChapterMetadata.from(groups: groups)
|
|
1130
|
+
onChapterMetadata(chapters)
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
public func playerDidCompleteSeek(position _: Double, didFinish _: Bool) {
|
|
1134
|
+
// Not exposed to JS currently
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
public func playerDidUpdateDuration(_: Double) {
|
|
1138
|
+
// Not exposed to JS currently
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
public func remotePlay() {
|
|
1142
|
+
if let handler = handleRemotePlay {
|
|
1143
|
+
handler()
|
|
1144
|
+
} else {
|
|
1145
|
+
// Default behavior: play the player
|
|
1146
|
+
onMainActor { player?.play() }
|
|
1147
|
+
}
|
|
1148
|
+
onRemotePlay()
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
public func remotePause() {
|
|
1152
|
+
if let handler = handleRemotePause {
|
|
1153
|
+
handler()
|
|
1154
|
+
} else {
|
|
1155
|
+
// Default behavior: pause the player
|
|
1156
|
+
onMainActor { player?.pause() }
|
|
1157
|
+
}
|
|
1158
|
+
onRemotePause()
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
public func remoteStop() {
|
|
1162
|
+
if let handler = handleRemoteStop {
|
|
1163
|
+
handler()
|
|
1164
|
+
} else {
|
|
1165
|
+
// Default behavior: stop the player
|
|
1166
|
+
onMainActor { player?.stop() }
|
|
1167
|
+
}
|
|
1168
|
+
onRemoteStop()
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
public func remotePlayPause() {
|
|
1172
|
+
// Toggle based on current state
|
|
1173
|
+
let isPlaying = onMainActor { player?.playWhenReady == true }
|
|
1174
|
+
if isPlaying {
|
|
1175
|
+
remotePause()
|
|
1176
|
+
} else {
|
|
1177
|
+
remotePlay()
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
public func remoteNext() {
|
|
1182
|
+
if let handler = handleRemoteNext {
|
|
1183
|
+
handler()
|
|
1184
|
+
} else {
|
|
1185
|
+
// Default behavior: skip to next track
|
|
1186
|
+
onMainActor { player?.next() }
|
|
1187
|
+
}
|
|
1188
|
+
onRemoteNext()
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
public func remotePrevious() {
|
|
1192
|
+
if let handler = handleRemotePrevious {
|
|
1193
|
+
handler()
|
|
1194
|
+
} else {
|
|
1195
|
+
// Default behavior: skip to previous track
|
|
1196
|
+
onMainActor { player?.previous() }
|
|
1197
|
+
}
|
|
1198
|
+
onRemotePrevious()
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
public func remoteJumpForward(interval: Double) {
|
|
1202
|
+
let event = RemoteJumpForwardEvent(interval: interval)
|
|
1203
|
+
if let handler = handleRemoteJumpForward {
|
|
1204
|
+
handler(event)
|
|
1205
|
+
} else {
|
|
1206
|
+
// Default behavior: seek forward by interval
|
|
1207
|
+
onMainActor { player?.seekBy(interval) }
|
|
1208
|
+
}
|
|
1209
|
+
onRemoteJumpForward(event)
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
public func remoteJumpBackward(interval: Double) {
|
|
1213
|
+
let event = RemoteJumpBackwardEvent(interval: interval)
|
|
1214
|
+
if let handler = handleRemoteJumpBackward {
|
|
1215
|
+
handler(event)
|
|
1216
|
+
} else {
|
|
1217
|
+
// Default behavior: seek backward by interval
|
|
1218
|
+
onMainActor { player?.seekBy(-interval) }
|
|
1219
|
+
}
|
|
1220
|
+
onRemoteJumpBackward(event)
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
public func remoteSeek(position: Double) {
|
|
1224
|
+
logger.info("remoteSeek called with position: \(position)")
|
|
1225
|
+
let event = RemoteSeekEvent(position: position)
|
|
1226
|
+
if let handler = handleRemoteSeek {
|
|
1227
|
+
handler(event)
|
|
1228
|
+
} else {
|
|
1229
|
+
// Default behavior: seek to position
|
|
1230
|
+
logger.info("remoteSeek: calling player.seekTo(\(position))")
|
|
1231
|
+
onMainActor { player?.seekTo(position) }
|
|
1232
|
+
}
|
|
1233
|
+
onRemoteSeek(event)
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
public func remoteChangePlaybackPosition(position: Double) {
|
|
1237
|
+
remoteSeek(position: position)
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
public func remoteSetRating(rating _: Any) {
|
|
1241
|
+
// TODO: Convert rating to RemoteSetRatingEvent
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
public func remotePlayId(id: String, index: Int?) {
|
|
1245
|
+
let event = RemotePlayIdEvent(id: id, index: index.map { Double($0) })
|
|
1246
|
+
if let handler = handleRemotePlayId {
|
|
1247
|
+
handler(event)
|
|
1248
|
+
} else {
|
|
1249
|
+
onRemotePlayId(event)
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
public func remotePlaySearch(query: String) {
|
|
1254
|
+
let event = RemotePlaySearchEvent(query: query)
|
|
1255
|
+
if let handler = handleRemotePlaySearch {
|
|
1256
|
+
handler(event)
|
|
1257
|
+
} else {
|
|
1258
|
+
onRemotePlaySearch(event)
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
public func remoteLike() {
|
|
1263
|
+
if let handler = handleRemoteLike {
|
|
1264
|
+
handler()
|
|
1265
|
+
} else {
|
|
1266
|
+
onRemoteLike()
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
public func remoteDislike() {
|
|
1271
|
+
if let handler = handleRemoteDislike {
|
|
1272
|
+
handler()
|
|
1273
|
+
} else {
|
|
1274
|
+
onRemoteDislike()
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
public func remoteBookmark() {
|
|
1279
|
+
if let handler = handleRemoteBookmark {
|
|
1280
|
+
handler()
|
|
1281
|
+
} else {
|
|
1282
|
+
onRemoteBookmark()
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
public func remoteChangeRepeatMode(mode: RepeatMode) {
|
|
1287
|
+
// Apply the repeat mode change from CarPlay/lock screen
|
|
1288
|
+
try? setRepeatMode(mode: mode)
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
public func remoteChangeShuffleMode(enabled: Bool) {
|
|
1292
|
+
// Apply the shuffle mode change from CarPlay/lock screen
|
|
1293
|
+
try? setShuffleEnabled(enabled: enabled)
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
public func remoteChangePlaybackRate(rate: Float) {
|
|
1297
|
+
// Apply the playback rate change from CarPlay/lock screen
|
|
1298
|
+
onMainActor { player?.rate = rate }
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
func playerDidChangeOptions(_: PlayerUpdateOptions) {
|
|
1302
|
+
// TODO: Convert to Options type
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// MARK: - Autolinking Alias
|
|
1307
|
+
|
|
1308
|
+
/// Alias for Nitro autolinking - expects class named "AudioBrowser"
|
|
1309
|
+
public typealias AudioBrowser = HybridAudioBrowser
|