react-native-nitro-player 0.6.1 → 0.7.1-alpha.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.
Files changed (164) hide show
  1. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrary.kt +9 -13
  2. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAudioDevices.kt +45 -90
  3. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridDownloadManager.kt +48 -182
  4. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridEqualizer.kt +21 -77
  5. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridPlayerQueue.kt +55 -104
  6. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridTrackPlayer.kt +113 -123
  7. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/ExoPlayerCore.kt +82 -0
  8. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/ListenerRegistry.kt +48 -0
  9. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerAndroidAuto.kt +62 -0
  10. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +153 -1887
  11. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerListener.kt +122 -0
  12. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerNotify.kt +44 -0
  13. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerPlayback.kt +162 -0
  14. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerQueue.kt +165 -0
  15. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerQueueBuild.kt +161 -0
  16. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerSetup.kt +28 -0
  17. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerTempQueue.kt +121 -0
  18. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerUrlLoader.kt +98 -0
  19. package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadDatabase.kt +27 -18
  20. package/android/src/main/java/com/margelo/nitro/nitroplayer/equalizer/EqualizerCore.kt +11 -58
  21. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaSessionManager.kt +13 -30
  22. package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/PlaylistManager.kt +102 -162
  23. package/ios/HybridDownloadManager.swift +32 -26
  24. package/ios/HybridEqualizer.swift +48 -35
  25. package/ios/HybridTrackPlayer.swift +127 -102
  26. package/ios/core/ListenerRegistry.swift +60 -0
  27. package/ios/core/TrackPlayerCore.swift +130 -2356
  28. package/ios/core/TrackPlayerListener.swift +395 -0
  29. package/ios/core/TrackPlayerNotify.swift +52 -0
  30. package/ios/core/TrackPlayerPlayback.swift +274 -0
  31. package/ios/core/TrackPlayerQueue.swift +212 -0
  32. package/ios/core/TrackPlayerQueueBuild.swift +482 -0
  33. package/ios/core/TrackPlayerTempQueue.swift +167 -0
  34. package/ios/core/TrackPlayerUrlLoader.swift +169 -0
  35. package/ios/equalizer/EqualizerCore.swift +24 -89
  36. package/ios/media/MediaSessionManager.swift +32 -49
  37. package/ios/playlist/PlaylistManager.swift +2 -9
  38. package/ios/queue/HybridPlayerQueue.swift +69 -66
  39. package/lib/hooks/useDownloadedTracks.js +16 -13
  40. package/lib/hooks/useEqualizer.d.ts +4 -4
  41. package/lib/hooks/useEqualizer.js +12 -12
  42. package/lib/hooks/useEqualizerPresets.d.ts +3 -3
  43. package/lib/hooks/useEqualizerPresets.js +12 -18
  44. package/lib/specs/AndroidAutoMediaLibrary.nitro.d.ts +2 -2
  45. package/lib/specs/AudioDevices.nitro.d.ts +2 -2
  46. package/lib/specs/DownloadManager.nitro.d.ts +10 -10
  47. package/lib/specs/Equalizer.nitro.d.ts +9 -9
  48. package/lib/specs/TrackPlayer.nitro.d.ts +38 -16
  49. package/nitro.json +44 -11
  50. package/nitrogen/generated/android/NitroPlayerOnLoad.cpp +63 -24
  51. package/nitrogen/generated/android/c++/JCurrentPlayingType.hpp +1 -1
  52. package/nitrogen/generated/android/c++/JDownloadConfig.hpp +1 -1
  53. package/nitrogen/generated/android/c++/JDownloadError.hpp +1 -1
  54. package/nitrogen/generated/android/c++/JDownloadErrorReason.hpp +1 -1
  55. package/nitrogen/generated/android/c++/JDownloadProgress.hpp +1 -1
  56. package/nitrogen/generated/android/c++/JDownloadQueueStatus.hpp +1 -1
  57. package/nitrogen/generated/android/c++/JDownloadState.hpp +1 -1
  58. package/nitrogen/generated/android/c++/JDownloadStorageInfo.hpp +1 -1
  59. package/nitrogen/generated/android/c++/JDownloadTask.hpp +1 -1
  60. package/nitrogen/generated/android/c++/JDownloadedPlaylist.hpp +1 -1
  61. package/nitrogen/generated/android/c++/JDownloadedTrack.hpp +1 -1
  62. package/nitrogen/generated/android/c++/JEqualizerBand.hpp +1 -1
  63. package/nitrogen/generated/android/c++/JEqualizerPreset.hpp +1 -1
  64. package/nitrogen/generated/android/c++/JEqualizerState.hpp +1 -1
  65. package/nitrogen/generated/android/c++/JFunc_void_DownloadProgress.hpp +2 -2
  66. package/nitrogen/generated/android/c++/JFunc_void_DownloadedTrack.hpp +2 -2
  67. package/nitrogen/generated/android/c++/JFunc_void_TrackItem_std__optional_Reason_.hpp +2 -2
  68. package/nitrogen/generated/android/c++/JFunc_void_TrackPlayerState_std__optional_Reason_.hpp +2 -2
  69. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +2 -2
  70. package/nitrogen/generated/android/c++/JFunc_void_double_double.hpp +2 -2
  71. package/nitrogen/generated/android/c++/JFunc_void_double_double_std__optional_bool_.hpp +2 -2
  72. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__std__string__.hpp +2 -2
  73. package/nitrogen/generated/android/c++/JFunc_void_std__string_Playlist_std__optional_QueueOperation_.hpp +2 -2
  74. package/nitrogen/generated/android/c++/JFunc_void_std__string_std__string_DownloadState_std__optional_DownloadError_.hpp +2 -2
  75. package/nitrogen/generated/android/c++/JFunc_void_std__vector_EqualizerBand_.hpp +2 -2
  76. package/nitrogen/generated/android/c++/JFunc_void_std__vector_Playlist__std__optional_QueueOperation_.hpp +2 -2
  77. package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__double.hpp +2 -2
  78. package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__std__vector_TrackItem_.hpp +122 -0
  79. package/nitrogen/generated/android/c++/JGainRange.hpp +1 -1
  80. package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.cpp +49 -30
  81. package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.hpp +21 -24
  82. package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.cpp +35 -28
  83. package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.hpp +20 -23
  84. package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.cpp +197 -93
  85. package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.hpp +29 -32
  86. package/nitrogen/generated/android/c++/JHybridEqualizerSpec.cpp +157 -67
  87. package/nitrogen/generated/android/c++/JHybridEqualizerSpec.hpp +28 -31
  88. package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.cpp +138 -53
  89. package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.hpp +27 -30
  90. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +282 -69
  91. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +35 -30
  92. package/nitrogen/generated/android/c++/JPlaybackSource.hpp +1 -1
  93. package/nitrogen/generated/android/c++/JPlayerConfig.hpp +1 -1
  94. package/nitrogen/generated/android/c++/JPlayerState.hpp +1 -1
  95. package/nitrogen/generated/android/c++/JPlaylist.hpp +1 -1
  96. package/nitrogen/generated/android/c++/JPresetType.hpp +1 -1
  97. package/nitrogen/generated/android/c++/JQueueOperation.hpp +1 -1
  98. package/nitrogen/generated/android/c++/JReason.hpp +1 -1
  99. package/nitrogen/generated/android/c++/JRepeatMode.hpp +1 -1
  100. package/nitrogen/generated/android/c++/JStorageLocation.hpp +1 -1
  101. package/nitrogen/generated/android/c++/JTAudioDevice.hpp +1 -1
  102. package/nitrogen/generated/android/c++/JTrackItem.hpp +1 -1
  103. package/nitrogen/generated/android/c++/JTrackPlayerState.hpp +1 -1
  104. package/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp +3 -3
  105. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadError.hpp +3 -3
  106. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadTask.hpp +3 -3
  107. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedPlaylist.hpp +3 -3
  108. package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedTrack.hpp +3 -3
  109. package/nitrogen/generated/android/c++/JVariant_NullType_Playlist.hpp +3 -3
  110. package/nitrogen/generated/android/c++/JVariant_NullType_String.hpp +3 -3
  111. package/nitrogen/generated/android/c++/JVariant_NullType_TrackItem.hpp +3 -3
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__vector_TrackItem__std__vector_TrackItem_.kt +80 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrarySpec.kt +18 -20
  114. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridAudioDevicesSpec.kt +17 -19
  115. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridDownloadManagerSpec.kt +25 -28
  116. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridEqualizerSpec.kt +25 -27
  117. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridPlayerQueueSpec.kt +24 -26
  118. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +60 -26
  119. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_Double.kt +0 -6
  120. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadError.kt +0 -6
  121. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadTask.kt +0 -6
  122. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadedPlaylist.kt +0 -6
  123. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadedTrack.kt +0 -6
  124. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_Playlist.kt +0 -6
  125. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_String.kt +0 -6
  126. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_TrackItem.kt +0 -6
  127. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.cpp +74 -18
  128. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +380 -151
  129. package/nitrogen/generated/ios/c++/HybridDownloadManagerSpecSwift.hpp +10 -10
  130. package/nitrogen/generated/ios/c++/HybridEqualizerSpecSwift.hpp +12 -9
  131. package/nitrogen/generated/ios/c++/HybridPlayerQueueSpecSwift.hpp +23 -8
  132. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +82 -8
  133. package/nitrogen/generated/ios/swift/Func_void_EqualizerState.swift +46 -0
  134. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__DownloadedPlaylist_.swift +58 -0
  135. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__DownloadedTrack_.swift +58 -0
  136. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__std__string_.swift +58 -0
  137. package/nitrogen/generated/ios/swift/Func_void_std__vector_DownloadedPlaylist_.swift +46 -0
  138. package/nitrogen/generated/ios/swift/Func_void_std__vector_DownloadedTrack_.swift +46 -0
  139. package/nitrogen/generated/ios/swift/Func_void_std__vector_EqualizerBand_.swift +5 -5
  140. package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem__std__vector_TrackItem_.swift +46 -0
  141. package/nitrogen/generated/ios/swift/HybridDownloadManagerSpec.swift +10 -10
  142. package/nitrogen/generated/ios/swift/HybridDownloadManagerSpec_cxx.swift +141 -71
  143. package/nitrogen/generated/ios/swift/HybridEqualizerSpec.swift +9 -9
  144. package/nitrogen/generated/ios/swift/HybridEqualizerSpec_cxx.swift +105 -41
  145. package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec.swift +8 -8
  146. package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec_cxx.swift +95 -32
  147. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +16 -8
  148. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +267 -32
  149. package/nitrogen/generated/shared/c++/HybridAndroidAutoMediaLibrarySpec.hpp +3 -2
  150. package/nitrogen/generated/shared/c++/HybridAudioDevicesSpec.hpp +2 -1
  151. package/nitrogen/generated/shared/c++/HybridDownloadManagerSpec.hpp +10 -10
  152. package/nitrogen/generated/shared/c++/HybridEqualizerSpec.hpp +10 -9
  153. package/nitrogen/generated/shared/c++/HybridPlayerQueueSpec.hpp +9 -8
  154. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +8 -0
  155. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +16 -8
  156. package/package.json +3 -3
  157. package/src/hooks/useDownloadedTracks.ts +17 -13
  158. package/src/hooks/useEqualizer.ts +16 -16
  159. package/src/hooks/useEqualizerPresets.ts +15 -21
  160. package/src/specs/AndroidAutoMediaLibrary.nitro.ts +2 -2
  161. package/src/specs/AudioDevices.nitro.ts +2 -2
  162. package/src/specs/DownloadManager.nitro.ts +10 -10
  163. package/src/specs/Equalizer.nitro.ts +9 -9
  164. package/src/specs/TrackPlayer.nitro.ts +52 -16
@@ -3,7 +3,10 @@ package com.margelo.nitro.nitroplayer
3
3
  import androidx.annotation.Keep
4
4
  import com.facebook.proguard.annotations.DoNotStrip
5
5
  import com.margelo.nitro.NitroModules
6
+ import com.margelo.nitro.core.Promise
6
7
  import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
8
+ import com.margelo.nitro.nitroplayer.core.clearAndroidAutoMediaLibrary
9
+ import com.margelo.nitro.nitroplayer.core.setAndroidAutoMediaLibrary
7
10
 
8
11
  @DoNotStrip
9
12
  @Keep
@@ -11,21 +14,14 @@ class HybridAndroidAutoMediaLibrary : HybridAndroidAutoMediaLibrarySpec() {
11
14
  private val core: TrackPlayerCore
12
15
 
13
16
  init {
14
- val context =
15
- NitroModules.applicationContext
16
- ?: throw IllegalStateException("React Context is not initialized")
17
+ val context = NitroModules.applicationContext
18
+ ?: throw IllegalStateException("React Context is not initialized")
17
19
  core = TrackPlayerCore.getInstance(context)
18
20
  }
19
21
 
20
- @DoNotStrip
21
- @Keep
22
- override fun setMediaLibrary(libraryJson: String) {
23
- core.setAndroidAutoMediaLibrary(libraryJson)
24
- }
22
+ override fun setMediaLibrary(libraryJson: String): Promise<Unit> =
23
+ Promise.async { core.setAndroidAutoMediaLibrary(libraryJson) }
25
24
 
26
- @DoNotStrip
27
- @Keep
28
- override fun clearMediaLibrary() {
29
- core.clearAndroidAutoMediaLibrary()
30
- }
25
+ override fun clearMediaLibrary(): Promise<Unit> =
26
+ Promise.async { core.clearAndroidAutoMediaLibrary() }
31
27
  }
@@ -1,3 +1,5 @@
1
+ @file:Suppress("ktlint:standard:max-line-length")
2
+
1
3
  package com.margelo.nitro.nitroplayer
2
4
 
3
5
  import android.content.Context
@@ -7,6 +9,7 @@ import android.os.Build
7
9
  import androidx.annotation.Keep
8
10
  import com.facebook.proguard.annotations.DoNotStrip
9
11
  import com.margelo.nitro.NitroModules
12
+ import com.margelo.nitro.core.Promise
10
13
  import com.margelo.nitro.nitroplayer.core.NitroPlayerLogger
11
14
 
12
15
  @DoNotStrip
@@ -15,19 +18,13 @@ class HybridAudioDevices : HybridAudioDevicesSpec() {
15
18
  val applicationContext = NitroModules.applicationContext
16
19
  private val audioManager = applicationContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
17
20
 
18
- // Device types that can be set as communication devices
19
21
  private val validCommunicationDeviceTypes: Set<Int> by lazy {
20
- val types =
21
- mutableSetOf(
22
- AudioDeviceInfo.TYPE_BUILTIN_EARPIECE,
23
- AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
24
- AudioDeviceInfo.TYPE_WIRED_HEADSET,
25
- AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
26
- AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
27
- AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
28
- AudioDeviceInfo.TYPE_USB_HEADSET,
29
- )
30
- // BLE types are only available on Android S (API 31) and above
22
+ val types = mutableSetOf(
23
+ AudioDeviceInfo.TYPE_BUILTIN_EARPIECE, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
24
+ AudioDeviceInfo.TYPE_WIRED_HEADSET, AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
25
+ AudioDeviceInfo.TYPE_BLUETOOTH_SCO, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
26
+ AudioDeviceInfo.TYPE_USB_HEADSET,
27
+ )
31
28
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
32
29
  types.add(AudioDeviceInfo.TYPE_BLE_HEADSET)
33
30
  types.add(AudioDeviceInfo.TYPE_BLE_SPEAKER)
@@ -35,100 +32,58 @@ class HybridAudioDevices : HybridAudioDevicesSpec() {
35
32
  types
36
33
  }
37
34
 
38
- @DoNotStrip
39
- @Keep
40
35
  override fun getAudioDevices(): Array<TAudioDevice> {
41
- val devices = audioManager.getDevices(android.media.AudioManager.GET_DEVICES_OUTPUTS)
42
- var activeDevice: AudioDeviceInfo? = null
43
-
44
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
45
- activeDevice = audioManager.communicationDevice
46
- }
47
-
48
- // Filter to only include valid communication devices
49
- return devices
50
- .filter { device ->
51
- validCommunicationDeviceTypes.contains(device.type)
52
- }.map { device ->
53
- TAudioDevice(
54
- id = device.id.toDouble(),
55
- name = device.productName?.toString() ?: getDeviceTypeName(device.type),
56
- type = device.type.toDouble(),
57
- isActive = device == activeDevice,
58
- )
59
- }.toTypedArray()
36
+ val devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
37
+ val activeDevice: AudioDeviceInfo? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) audioManager.communicationDevice else null
38
+ return devices.filter { validCommunicationDeviceTypes.contains(it.type) }.map { device ->
39
+ TAudioDevice(
40
+ id = device.id.toDouble(),
41
+ name = device.productName?.toString() ?: getDeviceTypeName(device.type),
42
+ type = device.type.toDouble(),
43
+ isActive = device == activeDevice,
44
+ )
45
+ }.toTypedArray()
60
46
  }
61
47
 
62
- private fun getDeviceTypeName(type: Int): String =
63
- when (type) {
64
- AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> "Built-in Earpiece"
65
- AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> "Built-in Speaker"
66
- AudioDeviceInfo.TYPE_WIRED_HEADSET -> "Wired Headset"
67
- AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> "Wired Headphones"
68
- AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> "Bluetooth SCO"
69
- AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> "Bluetooth"
70
- AudioDeviceInfo.TYPE_USB_HEADSET -> "USB Headset"
71
- 26 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Headset" else "Type 26"
72
- 27 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Speaker" else "Type 27"
73
- else -> "Type $type"
74
- }
75
-
76
- @DoNotStrip
77
- @Keep
78
- override fun setAudioDevice(deviceId: Double): Boolean {
79
- val device =
80
- audioManager
81
- .getDevices(android.media.AudioManager.GET_DEVICES_OUTPUTS)
82
- .firstOrNull { it.id == deviceId.toInt() }
83
- ?: return false
84
-
85
- // Check if device type is valid for communication
48
+ /** v2: setAudioDevice now returns Promise<Unit> instead of Boolean */
49
+ override fun setAudioDevice(deviceId: Double): Promise<Unit> = Promise.async {
50
+ val device = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
51
+ .firstOrNull { it.id == deviceId.toInt() }
52
+ ?: throw IllegalArgumentException("Audio device $deviceId not found")
86
53
  if (!validCommunicationDeviceTypes.contains(device.type)) {
87
- NitroPlayerLogger.log("HybridAudioDevices", "Device type ${device.type} is not a valid communication device")
88
- return false
54
+ throw IllegalArgumentException("Device type ${device.type} is not a valid communication device")
89
55
  }
90
-
91
- return try {
92
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
56
+ try {
57
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
93
58
  audioManager.setCommunicationDevice(device)
94
59
  } else {
95
- // Pre-Android 12 fallback (best-effort)
96
60
  when (device.type) {
97
- android.media.AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
98
- android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
99
- -> {
100
- audioManager.startBluetoothSco()
101
- audioManager.isBluetoothScoOn = true
102
- true
103
- }
104
-
105
- android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> {
106
- audioManager.isSpeakerphoneOn = true
107
- true
108
- }
109
-
110
- android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET,
111
- android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
112
- -> {
113
- audioManager.isSpeakerphoneOn = false
114
- audioManager.isBluetoothScoOn = false
115
- true
61
+ AudioDeviceInfo.TYPE_BLUETOOTH_SCO, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> {
62
+ audioManager.startBluetoothSco(); audioManager.isBluetoothScoOn = true
116
63
  }
117
-
118
- else -> {
119
- NitroPlayerLogger.log("HybridAudioDevices", "Unsupported device type for pre-Android 12: ${device.type}")
120
- false
64
+ AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> audioManager.isSpeakerphoneOn = true
65
+ AudioDeviceInfo.TYPE_WIRED_HEADSET, AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> {
66
+ audioManager.isSpeakerphoneOn = false; audioManager.isBluetoothScoOn = false
121
67
  }
68
+ else -> throw IllegalArgumentException("Unsupported device type for pre-Android 12: ${device.type}")
122
69
  }
123
70
  }
124
71
  } catch (e: Exception) {
125
72
  NitroPlayerLogger.log("HybridAudioDevices", "Error setting audio device: ${e.message}")
126
- e.printStackTrace()
127
- false
73
+ throw e
128
74
  }
129
75
  }
130
76
 
131
- companion object {
132
- private const val TAG = "HybridAudioDevices"
77
+ private fun getDeviceTypeName(type: Int): String = when (type) {
78
+ AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> "Built-in Earpiece"
79
+ AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> "Built-in Speaker"
80
+ AudioDeviceInfo.TYPE_WIRED_HEADSET -> "Wired Headset"
81
+ AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> "Wired Headphones"
82
+ AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> "Bluetooth SCO"
83
+ AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> "Bluetooth"
84
+ AudioDeviceInfo.TYPE_USB_HEADSET -> "USB Headset"
85
+ 26 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Headset" else "Type 26"
86
+ 27 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Speaker" else "Type 27"
87
+ else -> "Type $type"
133
88
  }
134
89
  }
@@ -1,3 +1,5 @@
1
+ @file:Suppress("ktlint:standard:max-line-length")
2
+
1
3
  package com.margelo.nitro.nitroplayer
2
4
 
3
5
  import androidx.annotation.Keep
@@ -7,219 +9,83 @@ import com.margelo.nitro.core.NullType
7
9
  import com.margelo.nitro.core.Promise
8
10
  import com.margelo.nitro.nitroplayer.download.DownloadManagerCore
9
11
 
10
- /**
11
- * Hybrid implementation of DownloadManagerSpec for Android
12
- * Bridges Nitro modules with the native DownloadManagerCore implementation
13
- */
14
12
  @DoNotStrip
15
13
  @Keep
16
14
  class HybridDownloadManager : HybridDownloadManagerSpec() {
17
15
  private val core: DownloadManagerCore
18
16
 
19
17
  init {
20
- val context =
21
- NitroModules.applicationContext
22
- ?: throw IllegalStateException("React Context is not initialized")
18
+ val context = NitroModules.applicationContext
19
+ ?: throw IllegalStateException("React Context is not initialized")
23
20
  core = DownloadManagerCore.getInstance(context)
24
21
  }
25
22
 
26
- // Configuration
27
- @DoNotStrip
28
- @Keep
29
- override fun configure(config: DownloadConfig) {
30
- core.configure(config)
31
- }
32
-
33
- @DoNotStrip
34
- @Keep
23
+ // ── Configuration ─────────────────────────────────────────────────────────
24
+ override fun configure(config: DownloadConfig) = core.configure(config)
35
25
  override fun getConfig(): DownloadConfig = core.getConfig()
36
26
 
37
- // Download Operations
38
- override fun downloadTrack(
39
- track: TrackItem,
40
- playlistId: String?,
41
- ): Promise<String> =
42
- Promise.async {
43
- core.downloadTrack(track, playlistId)
44
- }
45
-
46
- override fun downloadPlaylist(
47
- playlistId: String,
48
- tracks: Array<TrackItem>,
49
- ): Promise<Array<String>> =
50
- Promise.async {
51
- core.downloadPlaylist(playlistId, tracks)
52
- }
53
-
54
- // Download Control
55
- override fun pauseDownload(downloadId: String): Promise<Unit> =
56
- Promise.async {
57
- core.pauseDownload(downloadId)
58
- }
59
-
60
- override fun resumeDownload(downloadId: String): Promise<Unit> =
61
- Promise.async {
62
- core.resumeDownload(downloadId)
63
- }
64
-
65
- override fun cancelDownload(downloadId: String): Promise<Unit> =
66
- Promise.async {
67
- core.cancelDownload(downloadId)
68
- }
69
-
70
- override fun retryDownload(downloadId: String): Promise<Unit> =
71
- Promise.async {
72
- core.retryDownload(downloadId)
73
- }
74
-
75
- override fun pauseAllDownloads(): Promise<Unit> =
76
- Promise.async {
77
- core.pauseAllDownloads()
78
- }
79
-
80
- override fun resumeAllDownloads(): Promise<Unit> =
81
- Promise.async {
82
- core.resumeAllDownloads()
83
- }
84
-
85
- override fun cancelAllDownloads(): Promise<Unit> =
86
- Promise.async {
87
- core.cancelAllDownloads()
88
- }
89
-
90
- // Download Status
91
- @DoNotStrip
92
- @Keep
27
+ // ── Download operations ───────────────────────────────────────────────────
28
+ override fun downloadTrack(track: TrackItem, playlistId: String?): Promise<String> = Promise.async { core.downloadTrack(track, playlistId) }
29
+ override fun downloadPlaylist(playlistId: String, tracks: Array<TrackItem>): Promise<Array<String>> = Promise.async { core.downloadPlaylist(playlistId, tracks) }
30
+ override fun pauseDownload(downloadId: String): Promise<Unit> = Promise.async { core.pauseDownload(downloadId) }
31
+ override fun resumeDownload(downloadId: String): Promise<Unit> = Promise.async { core.resumeDownload(downloadId) }
32
+ override fun cancelDownload(downloadId: String): Promise<Unit> = Promise.async { core.cancelDownload(downloadId) }
33
+ override fun retryDownload(downloadId: String): Promise<Unit> = Promise.async { core.retryDownload(downloadId) }
34
+ override fun pauseAllDownloads(): Promise<Unit> = Promise.async { core.pauseAllDownloads() }
35
+ override fun resumeAllDownloads(): Promise<Unit> = Promise.async { core.resumeAllDownloads() }
36
+ override fun cancelAllDownloads(): Promise<Unit> = Promise.async { core.cancelAllDownloads() }
37
+
38
+ // ── Download status (sync) ────────────────────────────────────────────────
93
39
  override fun getDownloadTask(downloadId: String): Variant_NullType_DownloadTask {
94
40
  val task = core.getDownloadTask(downloadId)
95
- return if (task != null) {
96
- Variant_NullType_DownloadTask.create(task)
97
- } else {
98
- Variant_NullType_DownloadTask.create(NullType.NULL)
99
- }
41
+ return if (task != null) Variant_NullType_DownloadTask.create(task)
42
+ else Variant_NullType_DownloadTask.create(NullType.NULL)
100
43
  }
101
-
102
- @DoNotStrip
103
- @Keep
104
44
  override fun getActiveDownloads(): Array<DownloadTask> = core.getActiveDownloads()
105
-
106
- @DoNotStrip
107
- @Keep
108
45
  override fun getQueueStatus(): DownloadQueueStatus = core.getQueueStatus()
109
-
110
- @DoNotStrip
111
- @Keep
112
46
  override fun isDownloading(trackId: String): Boolean = core.isDownloading(trackId)
113
-
114
- @DoNotStrip
115
- @Keep
116
47
  override fun getDownloadState(trackId: String): DownloadState = core.getDownloadState(trackId)
117
48
 
118
- // Downloaded Content Queries
119
- @DoNotStrip
120
- @Keep
121
- override fun isTrackDownloaded(trackId: String): Boolean = core.isTrackDownloaded(trackId)
49
+ // ── Downloaded content queries (now async per spec) ───────────────────────
50
+ override fun isTrackDownloaded(trackId: String): Promise<Boolean> = Promise.async { core.isTrackDownloaded(trackId) }
51
+ override fun isPlaylistDownloaded(playlistId: String): Promise<Boolean> = Promise.async { core.isPlaylistDownloaded(playlistId) }
52
+ override fun isPlaylistPartiallyDownloaded(playlistId: String): Promise<Boolean> = Promise.async { core.isPlaylistPartiallyDownloaded(playlistId) }
122
53
 
123
- @DoNotStrip
124
- @Keep
125
- override fun isPlaylistDownloaded(playlistId: String): Boolean = core.isPlaylistDownloaded(playlistId)
126
-
127
- @DoNotStrip
128
- @Keep
129
- override fun isPlaylistPartiallyDownloaded(playlistId: String): Boolean = core.isPlaylistPartiallyDownloaded(playlistId)
130
-
131
- @DoNotStrip
132
- @Keep
133
- override fun getDownloadedTrack(trackId: String): Variant_NullType_DownloadedTrack {
54
+ override fun getDownloadedTrack(trackId: String): Promise<Variant_NullType_DownloadedTrack> = Promise.async {
134
55
  val track = core.getDownloadedTrack(trackId)
135
- return if (track != null) {
136
- Variant_NullType_DownloadedTrack.create(track)
137
- } else {
138
- Variant_NullType_DownloadedTrack.create(NullType.NULL)
139
- }
56
+ if (track != null) Variant_NullType_DownloadedTrack.create(track)
57
+ else Variant_NullType_DownloadedTrack.create(NullType.NULL)
140
58
  }
59
+ override fun getAllDownloadedTracks(): Promise<Array<DownloadedTrack>> = Promise.async { core.getAllDownloadedTracks() }
141
60
 
142
- @DoNotStrip
143
- @Keep
144
- override fun getAllDownloadedTracks(): Array<DownloadedTrack> = core.getAllDownloadedTracks()
145
-
146
- @DoNotStrip
147
- @Keep
148
- override fun getDownloadedPlaylist(playlistId: String): Variant_NullType_DownloadedPlaylist {
61
+ override fun getDownloadedPlaylist(playlistId: String): Promise<Variant_NullType_DownloadedPlaylist> = Promise.async {
149
62
  val playlist = core.getDownloadedPlaylist(playlistId)
150
- return if (playlist != null) {
151
- Variant_NullType_DownloadedPlaylist.create(playlist)
152
- } else {
153
- Variant_NullType_DownloadedPlaylist.create(NullType.NULL)
154
- }
63
+ if (playlist != null) Variant_NullType_DownloadedPlaylist.create(playlist)
64
+ else Variant_NullType_DownloadedPlaylist.create(NullType.NULL)
155
65
  }
66
+ override fun getAllDownloadedPlaylists(): Promise<Array<DownloadedPlaylist>> = Promise.async { core.getAllDownloadedPlaylists() }
156
67
 
157
- @DoNotStrip
158
- @Keep
159
- override fun getAllDownloadedPlaylists(): Array<DownloadedPlaylist> = core.getAllDownloadedPlaylists()
160
-
161
- @DoNotStrip
162
- @Keep
163
- override fun getLocalPath(trackId: String): Variant_NullType_String {
68
+ override fun getLocalPath(trackId: String): Promise<Variant_NullType_String> = Promise.async {
164
69
  val path = core.getLocalPath(trackId)
165
- return if (path != null) {
166
- Variant_NullType_String.create(path)
167
- } else {
168
- Variant_NullType_String.create(NullType.NULL)
169
- }
70
+ if (path != null) Variant_NullType_String.create(path)
71
+ else Variant_NullType_String.create(NullType.NULL)
170
72
  }
171
73
 
172
- // Deletion
173
- override fun deleteDownloadedTrack(trackId: String): Promise<Unit> =
174
- Promise.async {
175
- core.deleteDownloadedTrack(trackId)
176
- }
74
+ override fun syncDownloads(): Promise<Double> = Promise.async { core.syncDownloads().toDouble() }
75
+ override fun getEffectiveUrl(track: TrackItem): Promise<String> = Promise.async { core.getEffectiveUrl(track) }
177
76
 
178
- override fun deleteDownloadedPlaylist(playlistId: String): Promise<Unit> =
179
- Promise.async {
180
- core.deleteDownloadedPlaylist(playlistId)
181
- }
77
+ // ── Deletion ──────────────────────────────────────────────────────────────
78
+ override fun deleteDownloadedTrack(trackId: String): Promise<Unit> = Promise.async { core.deleteDownloadedTrack(trackId) }
79
+ override fun deleteDownloadedPlaylist(playlistId: String): Promise<Unit> = Promise.async { core.deleteDownloadedPlaylist(playlistId) }
80
+ override fun deleteAllDownloads(): Promise<Unit> = Promise.async { core.deleteAllDownloads() }
81
+ override fun getStorageInfo(): Promise<DownloadStorageInfo> = Promise.async { core.getStorageInfo() }
182
82
 
183
- override fun deleteAllDownloads(): Promise<Unit> =
184
- Promise.async {
185
- core.deleteAllDownloads()
186
- }
187
-
188
- // Storage Management
189
- override fun getStorageInfo(): Promise<DownloadStorageInfo> =
190
- Promise.async {
191
- core.getStorageInfo()
192
- }
193
-
194
- @DoNotStrip
195
- @Keep
196
- override fun syncDownloads(): Double = core.syncDownloads().toDouble()
197
-
198
- // Playback Source Preference
199
- @DoNotStrip
200
- @Keep
201
- override fun setPlaybackSourcePreference(preference: PlaybackSource) {
202
- core.setPlaybackSourcePreference(preference)
203
- }
204
-
205
- @DoNotStrip
206
- @Keep
83
+ // ── Playback source ───────────────────────────────────────────────────────
84
+ override fun setPlaybackSourcePreference(preference: PlaybackSource) = core.setPlaybackSourcePreference(preference)
207
85
  override fun getPlaybackSourcePreference(): PlaybackSource = core.getPlaybackSourcePreference()
208
86
 
209
- @DoNotStrip
210
- @Keep
211
- override fun getEffectiveUrl(track: TrackItem): String = core.getEffectiveUrl(track)
212
-
213
- // Event Callbacks
214
- override fun onDownloadProgress(callback: (progress: DownloadProgress) -> Unit) {
215
- core.addProgressCallback(callback)
216
- }
217
-
218
- override fun onDownloadStateChange(callback: (downloadId: String, trackId: String, state: DownloadState, error: DownloadError?) -> Unit) {
219
- core.addStateChangeCallback(callback)
220
- }
221
-
222
- override fun onDownloadComplete(callback: (downloadedTrack: DownloadedTrack) -> Unit) {
223
- core.addCompleteCallback(callback)
224
- }
87
+ // ── Events ────────────────────────────────────────────────────────────────
88
+ override fun onDownloadProgress(callback: (progress: DownloadProgress) -> Unit) = core.addProgressCallback(callback)
89
+ override fun onDownloadStateChange(callback: (downloadId: String, trackId: String, state: DownloadState, error: DownloadError?) -> Unit) = core.addStateChangeCallback(callback)
90
+ override fun onDownloadComplete(callback: (downloadedTrack: DownloadedTrack) -> Unit) = core.addCompleteCallback(callback)
225
91
  }
@@ -4,6 +4,7 @@ import androidx.annotation.Keep
4
4
  import com.facebook.proguard.annotations.DoNotStrip
5
5
  import com.margelo.nitro.NitroModules
6
6
  import com.margelo.nitro.core.NullType
7
+ import com.margelo.nitro.core.Promise
7
8
  import com.margelo.nitro.nitroplayer.equalizer.EqualizerCore
8
9
 
9
10
  @DoNotStrip
@@ -12,94 +13,37 @@ class HybridEqualizer : HybridEqualizerSpec() {
12
13
  private val core: EqualizerCore
13
14
 
14
15
  init {
15
- val context =
16
- NitroModules.applicationContext ?: throw IllegalStateException("React Context is not initialized")
17
-
18
- // Get the equalizer core - it will initialize lazily with audio session 0
19
- // and be re-initialized with the proper session when onAudioSessionIdChanged fires
16
+ val context = NitroModules.applicationContext
17
+ ?: throw IllegalStateException("React Context is not initialized")
20
18
  core = EqualizerCore.getInstance(context)
21
19
  core.ensureInitialized()
22
20
  }
23
21
 
24
- @DoNotStrip
25
- @Keep
26
- override fun setEnabled(enabled: Boolean): Boolean = core.setEnabled(enabled)
27
-
28
- @DoNotStrip
29
- @Keep
22
+ // ── Sync reads ────────────────────────────────────────────────────────────
30
23
  override fun isEnabled(): Boolean = core.isEnabled()
31
-
32
- @DoNotStrip
33
- @Keep
34
- override fun getBands(): Array<EqualizerBand> = core.getBands()
35
-
36
- @DoNotStrip
37
- @Keep
38
- override fun setBandGain(
39
- bandIndex: Double,
40
- gainDb: Double,
41
- ): Boolean = core.setBandGain(bandIndex.toInt(), gainDb)
42
-
43
- @DoNotStrip
44
- @Keep
45
- override fun setAllBandGains(gains: DoubleArray): Boolean = core.setAllBandGains(gains)
46
-
47
- @DoNotStrip
48
- @Keep
49
24
  override fun getBandRange(): GainRange = core.getBandRange()
50
-
51
- @DoNotStrip
52
- @Keep
53
25
  override fun getPresets(): Array<EqualizerPreset> = core.getPresets()
54
-
55
- @DoNotStrip
56
- @Keep
57
26
  override fun getBuiltInPresets(): Array<EqualizerPreset> = core.getBuiltInPresets()
58
-
59
- @DoNotStrip
60
- @Keep
61
27
  override fun getCustomPresets(): Array<EqualizerPreset> = core.getCustomPresets()
62
-
63
- @DoNotStrip
64
- @Keep
65
- override fun applyPreset(presetName: String): Boolean = core.applyPreset(presetName)
66
-
67
- @DoNotStrip
68
- @Keep
69
28
  override fun getCurrentPresetName(): Variant_NullType_String {
70
29
  val name = core.getCurrentPresetName()
71
- return if (name != null) {
72
- Variant_NullType_String.create(name)
73
- } else {
74
- Variant_NullType_String.create(NullType.NULL)
75
- }
76
- }
77
-
78
- @DoNotStrip
79
- @Keep
80
- override fun saveCustomPreset(name: String): Boolean = core.saveCustomPreset(name)
81
-
82
- @DoNotStrip
83
- @Keep
84
- override fun deleteCustomPreset(name: String): Boolean = core.deleteCustomPreset(name)
85
-
86
- @DoNotStrip
87
- @Keep
88
- override fun getState(): EqualizerState = core.getState()
89
-
90
- @DoNotStrip
91
- @Keep
92
- override fun reset() = core.reset()
93
-
94
- override fun onEnabledChange(callback: (enabled: Boolean) -> Unit) {
95
- core.addOnEnabledChangeListener(callback)
30
+ return if (name != null) Variant_NullType_String.create(name)
31
+ else Variant_NullType_String.create(NullType.NULL)
96
32
  }
97
33
 
98
- override fun onBandChange(callback: (bands: Array<EqualizerBand>) -> Unit) {
99
- core.addOnBandChangeListener(callback)
100
- }
101
-
102
- override fun onPresetChange(callback: (presetName: Variant_NullType_String?) -> Unit) {
103
- core.addOnPresetChangeListener(callback)
104
- }
34
+ // ── Async mutations (per v2 spec) ─────────────────────────────────────────
35
+ override fun setEnabled(enabled: Boolean): Promise<Unit> = Promise.async { core.setEnabled(enabled) }
36
+ override fun getBands(): Promise<Array<EqualizerBand>> = Promise.async { core.getBands() }
37
+ override fun setBandGain(bandIndex: Double, gainDb: Double): Promise<Unit> = Promise.async { core.setBandGain(bandIndex.toInt(), gainDb) }
38
+ override fun setAllBandGains(gains: DoubleArray): Promise<Unit> = Promise.async { core.setAllBandGains(gains) }
39
+ override fun applyPreset(presetName: String): Promise<Unit> = Promise.async { core.applyPreset(presetName) }
40
+ override fun saveCustomPreset(name: String): Promise<Unit> = Promise.async { core.saveCustomPreset(name) }
41
+ override fun deleteCustomPreset(name: String): Promise<Unit> = Promise.async { core.deleteCustomPreset(name) }
42
+ override fun getState(): Promise<EqualizerState> = Promise.async { core.getState() }
43
+ override fun reset(): Promise<Unit> = Promise.async { core.reset() }
44
+
45
+ // ── Events ────────────────────────────────────────────────────────────────
46
+ override fun onEnabledChange(callback: (enabled: Boolean) -> Unit) = core.addOnEnabledChangeListener(callback)
47
+ override fun onBandChange(callback: (bands: Array<EqualizerBand>) -> Unit) = core.addOnBandChangeListener(callback)
48
+ override fun onPresetChange(callback: (presetName: Variant_NullType_String?) -> Unit) = core.addOnPresetChangeListener(callback)
105
49
  }