react-native-audio-browser 0.2.0-next.28 → 0.2.0-next.29

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.
Files changed (137) hide show
  1. package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +3 -4
  2. package/android/src/test/java/com/audiobrowser/browser/BrowserUrlResolutionTest.kt +2 -2
  3. package/ios/AVPlayerEngine.swift +334 -0
  4. package/ios/AVPlayerEngineCallbacks.swift +15 -0
  5. package/ios/Browser/BrowseGate.swift +58 -0
  6. package/ios/Browser/BrowserConfig.swift +31 -89
  7. package/ios/Browser/BrowserManager.swift +68 -487
  8. package/ios/Browser/NavigationErrorState.swift +41 -0
  9. package/ios/Browser/PageResolver.swift +227 -0
  10. package/ios/Browser/RequestLayer.swift +90 -0
  11. package/ios/Browser/{BrowserManager+URLResolution.swift → RequestPipeline.swift} +175 -107
  12. package/ios/CarPlay/CPInterfaceController+Safe.swift +11 -24
  13. package/ios/CarPlay/CarPlayArtworkResolver.swift +35 -83
  14. package/ios/CarPlay/CarPlayController.swift +42 -1442
  15. package/ios/CarPlay/CarPlayImageLoader.swift +42 -83
  16. package/ios/CarPlay/CarPlayListItemFactory.swift +9 -23
  17. package/ios/CarPlay/CarPlayNowPlayingManager.swift +119 -129
  18. package/ios/CarPlay/CarPlaySession+Navigator.swift +114 -0
  19. package/ios/CarPlay/CarPlaySession+PageLoader.swift +92 -0
  20. package/ios/CarPlay/CarPlaySession+Refresher.swift +43 -0
  21. package/ios/CarPlay/CarPlaySession+TabBar.swift +193 -0
  22. package/ios/CarPlay/CarPlaySession.swift +209 -0
  23. package/ios/CarPlay/CarPlayTemplates.swift +63 -0
  24. package/ios/CarPlay/HybridAudioBrowser+IntentFavorite.swift +20 -0
  25. package/ios/CarPlay/MediaIntentPlayback.swift +74 -0
  26. package/ios/CarPlay/RNABMediaAddHandler.swift +2 -18
  27. package/ios/CarPlay/RNABMediaAffinityHandler.swift +5 -21
  28. package/ios/CarPlay/RNABMediaIntentHandler.swift +2 -3
  29. package/ios/Extension/NavigationError+Conversion.swift +7 -4
  30. package/ios/Extension/UIImage+Adaptive.swift +12 -0
  31. package/ios/Extension/URLError+Connectivity.swift +15 -0
  32. package/ios/Http/HttpClient.swift +63 -145
  33. package/ios/HybridAudioBrowser+Browser.swift +153 -0
  34. package/ios/HybridAudioBrowser+Options.swift +144 -0
  35. package/ios/HybridAudioBrowser+Player.swift +397 -0
  36. package/ios/HybridAudioBrowser+PlayerCallbacks.swift +190 -0
  37. package/ios/HybridAudioBrowser+Stubs.swift +46 -0
  38. package/ios/HybridAudioBrowser.swift +74 -1687
  39. package/ios/Model/NitroTypeStubs.swift +18 -1
  40. package/ios/Model/PlayerUpdateOptions.swift +1 -1
  41. package/ios/NowPlayingInfo/NowPlayingInfoController.swift +18 -53
  42. package/ios/Observer/ItemObserver.swift +90 -0
  43. package/ios/Observer/PlayerObserver.swift +59 -0
  44. package/ios/Option/SessionCategories.swift +41 -92
  45. package/ios/Player/AudioSessionController.swift +177 -0
  46. package/ios/Player/DeferredSeek.swift +70 -0
  47. package/ios/Player/ErrorStatus.swift +27 -0
  48. package/ios/Player/MediaLoader.swift +24 -11
  49. package/ios/Player/NowPlayingUpdater.swift +157 -58
  50. package/ios/Player/PlaybackFailure.swift +125 -0
  51. package/ios/Player/PlaybackPersistence.swift +73 -0
  52. package/ios/Player/Player.swift +1083 -0
  53. package/ios/Player/{PlaybackCoordinatorCallbacks.swift → PlayerCallbacks.swift} +3 -4
  54. package/ios/Player/PlayerEngine.swift +89 -0
  55. package/ios/Player/PlayerStatusTypes.swift +2 -6
  56. package/ios/Player/QueueManager.swift +52 -59
  57. package/ios/Player/RetryLoop.swift +261 -0
  58. package/ios/Player/SleepTimerManager.swift +1 -1
  59. package/ios/RemoteCommand/RemoteCommandCallbacks.swift +2 -3
  60. package/ios/RemoteCommand/RemoteCommandController.swift +85 -367
  61. package/ios/Tests/CarPlayArtworkResolverTests.swift +60 -356
  62. package/ios/Tests/DeferredSeekTests.swift +70 -0
  63. package/ios/Tests/EmitterTests.swift +29 -0
  64. package/ios/Tests/GenerationMemoTests.swift +121 -0
  65. package/ios/Tests/LRUCacheTests.swift +4 -5
  66. package/ios/Tests/MediaLoaderTests.swift +12 -33
  67. package/ios/Tests/ObserverTests.swift +88 -0
  68. package/ios/Tests/PlaybackErrorTests.swift +76 -0
  69. package/ios/Tests/PlaybackFailureTests.swift +189 -0
  70. package/ios/Tests/PlaybackPersistenceTests.swift +93 -0
  71. package/ios/Tests/PlayerPolicyTests.swift +405 -0
  72. package/ios/Tests/{PlaybackCoordinatorTests.swift → PlayerTests.swift} +298 -248
  73. package/ios/Tests/PlayingStateTests.swift +42 -0
  74. package/ios/Tests/QueueManagerTests.swift +76 -107
  75. package/ios/Tests/ReadyValueTests.swift +73 -0
  76. package/ios/Tests/RemoteCommandControllerTests.swift +10 -30
  77. package/ios/Tests/RemoteCommandTests.swift +2 -4
  78. package/ios/Tests/RequestLayerTests.swift +112 -0
  79. package/ios/Tests/RetryLoopTests.swift +270 -0
  80. package/ios/Tests/Support/TestTypes.swift +111 -112
  81. package/ios/Tests/TrackIdTemplateTests.swift +1 -1
  82. package/ios/Tests/URLErrorConnectivityTests.swift +20 -0
  83. package/ios/TrackSelector.swift +1 -1
  84. package/ios/Util/ArtworkImageFetcher.swift +42 -0
  85. package/ios/Util/Emitter.swift +42 -0
  86. package/ios/Util/GenerationMemo.swift +36 -0
  87. package/ios/Util/LRUCache.swift +23 -162
  88. package/ios/Util/NetworkMonitor.swift +1 -1
  89. package/ios/Util/ReadyValue.swift +56 -0
  90. package/ios/Util/SFSymbolRenderer.swift +35 -29
  91. package/ios/Util/SVGProcessor.swift +0 -10
  92. package/lib/commonjs/web/NativeAudioBrowser.js +1 -1
  93. package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +1 -1
  94. package/lib/module/web/NativeAudioBrowser.js +1 -1
  95. package/lib/module/web/TrackPlayer/PlayingStateFactory.js +1 -1
  96. package/lib/typescript/src/types/browser.d.ts +3 -3
  97. package/package.json +1 -1
  98. package/src/types/browser.ts +3 -3
  99. package/src/web/NativeAudioBrowser.ts +1 -1
  100. package/src/web/TrackPlayer/PlayingStateFactory.test.ts +1 -1
  101. package/src/web/TrackPlayer/PlayingStateFactory.ts +1 -1
  102. package/ios/Bridge.h +0 -8
  103. package/ios/Browser/MediaResolveComposer.swift +0 -114
  104. package/ios/NowPlayingInfo/MediaItemProperty.swift +0 -78
  105. package/ios/NowPlayingInfo/NowPlayingInfoKeyValue.swift +0 -6
  106. package/ios/NowPlayingInfo/NowPlayingInfoProperty.swift +0 -220
  107. package/ios/Observer/PlayerItemNotificationObserver.swift +0 -119
  108. package/ios/Observer/PlayerItemPropertyObserver.swift +0 -133
  109. package/ios/Observer/PlayerStateObserver.swift +0 -50
  110. package/ios/Observer/PlayerTimeObserver.swift +0 -55
  111. package/ios/Option/PitchAlgorithms.swift +0 -17
  112. package/ios/Option/TimeEventFrequency.swift +0 -18
  113. package/ios/Player/LoadSeekCoordinator.swift +0 -99
  114. package/ios/Player/MediaLoaderDelegate.swift +0 -11
  115. package/ios/Player/PlaybackCoordinator.swift +0 -761
  116. package/ios/Player/PlaybackEffectHandler.swift +0 -54
  117. package/ios/Player/PlaybackErrorHandler.swift +0 -175
  118. package/ios/Player/PlaybackStateStore.swift +0 -27
  119. package/ios/Player/PlayingStateManager.swift +0 -33
  120. package/ios/Player/RetryManager.swift +0 -384
  121. package/ios/Player/SeekCompletionHandler.swift +0 -5
  122. package/ios/Player/SleepTimerHandling.swift +0 -28
  123. package/ios/Support/RNTrackPlayer-Bridging-Header.h +0 -7
  124. package/ios/Tests/LoadSeekCoordinatorTests.swift +0 -327
  125. package/ios/Tests/MediaResolveTests.swift +0 -126
  126. package/ios/Tests/OnceValueTests.swift +0 -79
  127. package/ios/Tests/PlaybackErrorHandlerTests.swift +0 -549
  128. package/ios/Tests/PlaybackStateStoreTests.swift +0 -49
  129. package/ios/Tests/PlayerTimeObserverTests.swift +0 -37
  130. package/ios/Tests/PlayingStateManagerTests.swift +0 -57
  131. package/ios/Tests/RetryManagerTests.swift +0 -178
  132. package/ios/TrackPlayer.swift +0 -1042
  133. package/ios/TrackPlayerCallbacks.swift +0 -53
  134. package/ios/Util/MetadataAdapter.swift +0 -131
  135. package/ios/Util/OnceValue.swift +0 -104
  136. /package/ios/{Player → CarPlay}/MediaIntentCriteria.swift +0 -0
  137. /package/ios/{Browser → CarPlay}/SectionPresentation.swift +0 -0
@@ -1,53 +0,0 @@
1
- import AVFoundation
2
- import MediaPlayer
3
- import NitroModules
4
-
5
- /// Callbacks for all player events.
6
- ///
7
- /// This protocol defines the interface for receiving events from TrackPlayer.
8
- /// HybridAudioBrowser implements this protocol to bridge events to JavaScript.
9
- /// Note: Method names are prefixed to avoid conflicts with JS callback property names.
10
- /// All callbacks are called from the main actor since TrackPlayer is @MainActor.
11
- ///
12
- /// Extends PlaybackCoordinatorCallbacks for the state machine / coordinator callbacks
13
- /// and RemoteCommandCallbacks for the remote-command events, then adds metadata,
14
- /// seek, and configuration callbacks that are TrackPlayer-specific.
15
- @MainActor
16
- protocol TrackPlayerCallbacks: PlaybackCoordinatorCallbacks, RemoteCommandCallbacks {
17
- // MARK: - Metadata Events
18
-
19
- /// Called when common metadata is received.
20
- func playerDidReceiveCommonMetadata(_ metadata: [AVMetadataItem])
21
-
22
- /// Called when timed metadata is received.
23
- func playerDidReceiveTimedMetadata(_ metadata: [AVTimedMetadataGroup])
24
-
25
- /// Called when chapter metadata is received.
26
- func playerDidReceiveChapterMetadata(_ metadata: [AVTimedMetadataGroup])
27
-
28
- // MARK: - Playback Events
29
-
30
- /// Called when a seek operation completes.
31
- func playerDidCompleteSeek(position: Double, didFinish: Bool)
32
-
33
- /// Called when the duration is updated.
34
- func playerDidUpdateDuration(_ duration: Double)
35
-
36
- // MARK: - Remote Control Events
37
-
38
- // The command-center events live in RemoteCommandCallbacks, inherited above.
39
-
40
- /// Called when change playback position is triggered remotely.
41
- func remoteChangePlaybackPosition(position: Double)
42
-
43
- /// Called when play from ID is triggered remotely.
44
- func remotePlayId(id: String, index: Int?)
45
-
46
- /// Called when play from search is triggered remotely.
47
- func remotePlaySearch(query: String)
48
-
49
- // MARK: - Configuration Events
50
-
51
- /// Called when options are changed.
52
- func playerDidChangeOptions(_ options: PlayerUpdateOptions)
53
- }
@@ -1,131 +0,0 @@
1
- import AVFoundation
2
- import Foundation
3
-
4
- typealias RawMetadataGroup = [[String: Any]]
5
-
6
- class MetadataAdapter {
7
- private static func getMetadataItem(
8
- metadata: [AVMetadataItem],
9
- forIdentifier: AVMetadataIdentifier,
10
- ) -> String? {
11
- AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: forIdentifier).first?
12
- .stringValue
13
- }
14
-
15
- private static func convertToSerializableItems(items: [AVMetadataItem]) -> RawMetadataGroup {
16
- var rawGroup: RawMetadataGroup = []
17
-
18
- for metadataItem in items {
19
- var rawMetadataItem: [String: Any] = [:]
20
-
21
- if CMTIME_IS_VALID(metadataItem.time), CMTIME_IS_NUMERIC(metadataItem.time) {
22
- rawMetadataItem["time"] = metadataItem.time.seconds
23
- }
24
-
25
- rawMetadataItem["value"] = metadataItem.value
26
- rawMetadataItem["key"] = metadataItem.key
27
- if let commonKey = metadataItem.commonKey?.rawValue {
28
- rawMetadataItem["commonKey"] = commonKey
29
- }
30
- if let keySpace = metadataItem.keySpace?.rawValue {
31
- rawMetadataItem["keySpace"] = keySpace
32
- }
33
-
34
- rawGroup.append(rawMetadataItem)
35
- }
36
-
37
- return rawGroup
38
- }
39
-
40
- // MARK: - Public
41
-
42
- static func convertToGroupedMetadata(metadataGroups: [AVTimedMetadataGroup]) -> RawMetadataGroup {
43
- var ret: RawMetadataGroup = []
44
-
45
- for metadataGroup in metadataGroups {
46
- let entry = convertToCommonMetadata(metadata: metadataGroup.items)
47
- ret.append(entry)
48
- }
49
-
50
- return ret
51
- }
52
-
53
- static func convertToCommonMetadata(
54
- metadata: [AVMetadataItem],
55
- skipRaw: Bool = false,
56
- ) -> [String: Any] {
57
- var rawMetadataItem: [String: Any] = [:]
58
- rawMetadataItem["title"] = getMetadataItem(
59
- metadata: metadata,
60
- forIdentifier: .commonIdentifierTitle,
61
- )
62
- rawMetadataItem["artist"] = getMetadataItem(
63
- metadata: metadata,
64
- forIdentifier: .commonIdentifierArtist,
65
- )
66
- rawMetadataItem["albumName"] = getMetadataItem(
67
- metadata: metadata,
68
- forIdentifier: .commonIdentifierAlbumName,
69
- )
70
- rawMetadataItem["subtitle"] = getMetadataItem(
71
- metadata: metadata,
72
- forIdentifier: .id3MetadataSetSubtitle,
73
- )
74
- ?? getMetadataItem(metadata: metadata, forIdentifier: .iTunesMetadataTrackSubTitle)
75
- rawMetadataItem["description"] = getMetadataItem(
76
- metadata: metadata,
77
- forIdentifier: .commonIdentifierDescription,
78
- )
79
- rawMetadataItem["artworkUri"] = getMetadataItem(
80
- metadata: metadata,
81
- forIdentifier: .commonIdentifierArtwork,
82
- )
83
- rawMetadataItem["trackNumber"] = getMetadataItem(
84
- metadata: metadata,
85
- forIdentifier: .id3MetadataTrackNumber,
86
- )
87
- ?? getMetadataItem(metadata: metadata, forIdentifier: .iTunesMetadataTrackNumber)
88
- rawMetadataItem["composer"] = getMetadataItem(
89
- metadata: metadata,
90
- forIdentifier: .id3MetadataComposer,
91
- )
92
- ?? getMetadataItem(metadata: metadata, forIdentifier: .iTunesMetadataComposer)
93
- ?? getMetadataItem(metadata: metadata, forIdentifier: .quickTimeMetadataComposer)
94
- rawMetadataItem["conductor"] = getMetadataItem(
95
- metadata: metadata,
96
- forIdentifier: .id3MetadataConductor,
97
- )
98
- ?? getMetadataItem(metadata: metadata, forIdentifier: .iTunesMetadataConductor)
99
- rawMetadataItem["genre"] = getMetadataItem(
100
- metadata: metadata,
101
- forIdentifier: .quickTimeMetadataGenre,
102
- )
103
- rawMetadataItem["compilation"] = getMetadataItem(
104
- metadata: metadata,
105
- forIdentifier: .iTunesMetadataDiscCompilation,
106
- )
107
- rawMetadataItem["station"] = getMetadataItem(
108
- metadata: metadata,
109
- forIdentifier: .id3MetadataInternetRadioStationName,
110
- )
111
- rawMetadataItem["mediaType"] = getMetadataItem(
112
- metadata: metadata,
113
- forIdentifier: .id3MetadataMediaType,
114
- )
115
- rawMetadataItem["creationDate"] = getMetadataItem(
116
- metadata: metadata,
117
- forIdentifier: .commonIdentifierCreationDate,
118
- )
119
- rawMetadataItem["creationYear"] = getMetadataItem(
120
- metadata: metadata,
121
- forIdentifier: .id3MetadataYear,
122
- )
123
- ?? getMetadataItem(metadata: metadata, forIdentifier: .quickTimeMetadataYear)
124
-
125
- if !skipRaw {
126
- rawMetadataItem["raw"] = convertToSerializableItems(items: metadata)
127
- }
128
-
129
- return rawMetadataItem
130
- }
131
- }
@@ -1,104 +0,0 @@
1
- import Foundation
2
-
3
- /// Guards a continuation that two racing tasks may try to resume, so exactly
4
- /// one wins (see `OnceValue.wait(timeout:)`).
5
- private final class OneShot: @unchecked Sendable {
6
- private let lock = NSLock()
7
- private var claimed = false
8
- func claim() -> Bool {
9
- lock.lock()
10
- defer { lock.unlock() }
11
- if claimed { return false }
12
- claimed = true
13
- return true
14
- }
15
- }
16
-
17
- /// A thread-safe primitive that resolves to a value once, allowing multiple waiters.
18
- /// Once resolved, all current and future `wait()` calls return immediately with the value.
19
- final class OnceValue<T: Sendable>: @unchecked Sendable {
20
- private var continuations: [CheckedContinuation<T, Never>] = []
21
- private var value: T?
22
- private let lock = NSLock()
23
- private let provider: (() -> T?)?
24
-
25
- /// Creates a OnceValue with a provider closure that returns the value when ready.
26
- /// Call `check()` to attempt resolution using the provider.
27
- init(provider: @escaping () -> T?) {
28
- self.provider = provider
29
- }
30
-
31
- /// Creates a OnceValue without a provider. Use `resolve(_:)` to set the value manually.
32
- init() {
33
- self.provider = nil
34
- }
35
-
36
- /// Checks if the value is ready using the provider closure.
37
- /// If the provider returns a value, resolves and resumes all waiters.
38
- func check() {
39
- guard let provider, let value = provider() else { return }
40
- resolve(value)
41
- }
42
-
43
- /// Resolves the value, resuming all waiting continuations.
44
- /// Subsequent calls are ignored if already resolved.
45
- func resolve(_ value: T) {
46
- lock.lock()
47
- guard self.value == nil else {
48
- lock.unlock()
49
- return
50
- }
51
- self.value = value
52
- let pending = continuations
53
- continuations.removeAll()
54
- lock.unlock()
55
-
56
- for continuation in pending {
57
- continuation.resume(returning: value)
58
- }
59
- }
60
-
61
- /// Waits for the value to be resolved. Returns immediately if already resolved.
62
- func wait() async -> T {
63
- // All lock operations happen inside the synchronous continuation closure
64
- // to avoid Swift concurrency warnings about locks in async contexts
65
- await withCheckedContinuation { continuation in
66
- lock.lock()
67
- if let value {
68
- lock.unlock()
69
- continuation.resume(returning: value)
70
- } else {
71
- continuations.append(continuation)
72
- lock.unlock()
73
- }
74
- }
75
- }
76
-
77
- /// Waits for the value to be resolved, giving up after `timeout`.
78
- /// Returns the value, or nil if the timeout elapses first.
79
- ///
80
- /// Continuations aren't cancellable, so the internal waiter stays registered
81
- /// past a timeout; it resumes harmlessly (into a one-shot guard) if the value
82
- /// resolves later.
83
- func wait(timeout: Duration) async -> T? {
84
- let oneShot = OneShot()
85
- return await withCheckedContinuation { continuation in
86
- Task {
87
- let value = await self.wait()
88
- if oneShot.claim() { continuation.resume(returning: value) }
89
- }
90
- Task {
91
- try? await Task.sleep(for: timeout)
92
- if oneShot.claim() { continuation.resume(returning: nil) }
93
- }
94
- }
95
- }
96
-
97
- /// Resets the value, allowing it to be resolved again.
98
- /// Any pending waiters will continue waiting for the next resolve.
99
- func reset() {
100
- lock.lock()
101
- value = nil
102
- lock.unlock()
103
- }
104
- }