react-native-audio-api 0.6.0-rc.5 → 0.6.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 (201) hide show
  1. package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +35 -2
  2. package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +4 -0
  3. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +31 -17
  4. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +1 -3
  5. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +56 -2
  6. package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +0 -12
  7. package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +35 -12
  8. package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +30 -29
  9. package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +20 -22
  10. package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +19 -9
  11. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +30 -11
  12. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +34 -27
  13. package/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt +10 -5
  14. package/android/src/oldarch/NativeAudioAPIModuleSpec.java +39 -0
  15. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +20 -14
  16. package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +2 -3
  17. package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +24 -11
  18. package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +1 -0
  19. package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +10 -89
  20. package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +3 -24
  21. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +2 -2
  22. package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +2 -3
  23. package/common/cpp/audioapi/core/AudioContext.cpp +4 -1
  24. package/common/cpp/audioapi/core/AudioContext.h +1 -1
  25. package/common/cpp/audioapi/core/AudioNode.cpp +31 -2
  26. package/common/cpp/audioapi/core/AudioNode.h +7 -1
  27. package/common/cpp/audioapi/core/AudioParam.cpp +84 -2
  28. package/common/cpp/audioapi/core/AudioParam.h +14 -1
  29. package/common/cpp/audioapi/core/BaseAudioContext.cpp +6 -1
  30. package/common/cpp/audioapi/core/BaseAudioContext.h +7 -1
  31. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +3 -2
  32. package/common/cpp/audioapi/core/OfflineAudioContext.h +1 -1
  33. package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +28 -26
  34. package/common/cpp/audioapi/core/effects/GainNode.cpp +9 -9
  35. package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +5 -2
  36. package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +56 -0
  37. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +13 -13
  38. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +14 -10
  39. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +1 -1
  40. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +7 -6
  41. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +5 -3
  42. package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +15 -10
  43. package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +35 -1
  44. package/common/cpp/audioapi/core/utils/AudioNodeManager.h +15 -1
  45. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +108 -0
  46. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +62 -0
  47. package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +48 -0
  48. package/common/cpp/audioapi/jsi/JsiPromise.cpp +3 -4
  49. package/ios/audioapi/ios/AudioAPIModule.h +13 -0
  50. package/ios/audioapi/ios/AudioAPIModule.mm +115 -6
  51. package/ios/audioapi/ios/core/IOSAudioRecorder.h +2 -10
  52. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +6 -17
  53. package/ios/audioapi/ios/core/NativeAudioPlayer.m +2 -0
  54. package/ios/audioapi/ios/core/NativeAudioRecorder.m +7 -3
  55. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +7 -0
  56. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +12 -0
  57. package/ios/audioapi/ios/system/AudioEngine.h +5 -0
  58. package/ios/audioapi/ios/system/AudioEngine.mm +7 -15
  59. package/ios/audioapi/ios/system/AudioSessionManager.h +1 -1
  60. package/ios/audioapi/ios/system/AudioSessionManager.mm +2 -18
  61. package/ios/audioapi/ios/system/LockScreenManager.h +3 -3
  62. package/ios/audioapi/ios/system/LockScreenManager.mm +36 -48
  63. package/ios/audioapi/ios/system/NotificationManager.h +3 -3
  64. package/ios/audioapi/ios/system/NotificationManager.mm +21 -29
  65. package/lib/commonjs/api.js +4 -4
  66. package/lib/commonjs/api.js.map +1 -1
  67. package/lib/commonjs/core/AudioBufferSourceNode.js +2 -2
  68. package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
  69. package/lib/commonjs/core/AudioNode.js +8 -2
  70. package/lib/commonjs/core/AudioNode.js.map +1 -1
  71. package/lib/commonjs/core/AudioParam.js +2 -1
  72. package/lib/commonjs/core/AudioParam.js.map +1 -1
  73. package/lib/commonjs/core/AudioRecorder.js +11 -28
  74. package/lib/commonjs/core/AudioRecorder.js.map +1 -1
  75. package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -1
  76. package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
  77. package/lib/commonjs/core/BiquadFilterNode.js +4 -4
  78. package/lib/commonjs/core/BiquadFilterNode.js.map +1 -1
  79. package/lib/commonjs/core/GainNode.js +1 -1
  80. package/lib/commonjs/core/GainNode.js.map +1 -1
  81. package/lib/commonjs/core/OscillatorNode.js +2 -2
  82. package/lib/commonjs/core/OscillatorNode.js.map +1 -1
  83. package/lib/commonjs/core/StereoPannerNode.js +1 -1
  84. package/lib/commonjs/core/StereoPannerNode.js.map +1 -1
  85. package/lib/commonjs/events/AudioEventEmitter.js +22 -0
  86. package/lib/commonjs/events/AudioEventEmitter.js.map +1 -0
  87. package/lib/commonjs/events/AudioEventSubscription.js +20 -0
  88. package/lib/commonjs/events/AudioEventSubscription.js.map +1 -0
  89. package/lib/commonjs/events/index.js +21 -0
  90. package/lib/commonjs/events/index.js.map +1 -0
  91. package/lib/commonjs/events/types.js +6 -0
  92. package/lib/commonjs/events/types.js.map +1 -0
  93. package/lib/commonjs/hooks/useSytemVolume.js +1 -1
  94. package/lib/commonjs/hooks/useSytemVolume.js.map +1 -1
  95. package/lib/commonjs/specs/NativeAudioAPIModule.js +3 -3
  96. package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
  97. package/lib/commonjs/specs/index.js +2 -16
  98. package/lib/commonjs/specs/index.js.map +1 -1
  99. package/lib/commonjs/system/AudioManager.js +22 -28
  100. package/lib/commonjs/system/AudioManager.js.map +1 -1
  101. package/lib/module/api.js +2 -2
  102. package/lib/module/api.js.map +1 -1
  103. package/lib/module/core/AudioBufferSourceNode.js +2 -2
  104. package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
  105. package/lib/module/core/AudioNode.js +7 -2
  106. package/lib/module/core/AudioNode.js.map +1 -1
  107. package/lib/module/core/AudioParam.js +2 -1
  108. package/lib/module/core/AudioParam.js.map +1 -1
  109. package/lib/module/core/AudioRecorder.js +11 -28
  110. package/lib/module/core/AudioRecorder.js.map +1 -1
  111. package/lib/module/core/AudioScheduledSourceNode.js +4 -1
  112. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
  113. package/lib/module/core/BiquadFilterNode.js +4 -4
  114. package/lib/module/core/BiquadFilterNode.js.map +1 -1
  115. package/lib/module/core/GainNode.js +1 -1
  116. package/lib/module/core/GainNode.js.map +1 -1
  117. package/lib/module/core/OscillatorNode.js +2 -2
  118. package/lib/module/core/OscillatorNode.js.map +1 -1
  119. package/lib/module/core/StereoPannerNode.js +1 -1
  120. package/lib/module/core/StereoPannerNode.js.map +1 -1
  121. package/lib/module/events/AudioEventEmitter.js +16 -0
  122. package/lib/module/events/AudioEventEmitter.js.map +1 -0
  123. package/lib/module/events/AudioEventSubscription.js +15 -0
  124. package/lib/module/events/AudioEventSubscription.js.map +1 -0
  125. package/lib/module/events/index.js +6 -0
  126. package/lib/module/events/index.js.map +1 -0
  127. package/lib/module/events/types.js +4 -0
  128. package/lib/module/events/types.js.map +1 -0
  129. package/lib/module/hooks/useSytemVolume.js +1 -1
  130. package/lib/module/hooks/useSytemVolume.js.map +1 -1
  131. package/lib/module/specs/NativeAudioAPIModule.js +3 -2
  132. package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
  133. package/lib/module/specs/index.js +2 -3
  134. package/lib/module/specs/index.js.map +1 -1
  135. package/lib/module/system/AudioManager.js +23 -29
  136. package/lib/module/system/AudioManager.js.map +1 -1
  137. package/lib/typescript/api.d.ts +2 -1
  138. package/lib/typescript/api.d.ts.map +1 -1
  139. package/lib/typescript/core/AudioNode.d.ts +2 -1
  140. package/lib/typescript/core/AudioNode.d.ts.map +1 -1
  141. package/lib/typescript/core/AudioParam.d.ts +4 -2
  142. package/lib/typescript/core/AudioParam.d.ts.map +1 -1
  143. package/lib/typescript/core/AudioRecorder.d.ts +4 -14
  144. package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
  145. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +3 -1
  146. package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
  147. package/lib/typescript/events/AudioEventEmitter.d.ts +10 -0
  148. package/lib/typescript/events/AudioEventEmitter.d.ts.map +1 -0
  149. package/lib/typescript/events/AudioEventSubscription.d.ts +11 -0
  150. package/lib/typescript/events/AudioEventSubscription.d.ts.map +1 -0
  151. package/lib/typescript/events/index.d.ts +4 -0
  152. package/lib/typescript/events/index.d.ts.map +1 -0
  153. package/lib/typescript/events/types.d.ts +50 -0
  154. package/lib/typescript/events/types.d.ts.map +1 -0
  155. package/lib/typescript/hooks/useSytemVolume.d.ts.map +1 -1
  156. package/lib/typescript/interfaces.d.ts +10 -10
  157. package/lib/typescript/interfaces.d.ts.map +1 -1
  158. package/lib/typescript/specs/NativeAudioAPIModule.d.ts +15 -3
  159. package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
  160. package/lib/typescript/specs/index.d.ts +2 -3
  161. package/lib/typescript/specs/index.d.ts.map +1 -1
  162. package/lib/typescript/system/AudioManager.d.ts +6 -4
  163. package/lib/typescript/system/AudioManager.d.ts.map +1 -1
  164. package/lib/typescript/system/types.d.ts +0 -34
  165. package/lib/typescript/system/types.d.ts.map +1 -1
  166. package/lib/typescript/types.d.ts +0 -1
  167. package/lib/typescript/types.d.ts.map +1 -1
  168. package/package.json +3 -3
  169. package/src/api.ts +6 -3
  170. package/src/core/AudioBufferSourceNode.ts +2 -2
  171. package/src/core/AudioNode.ts +8 -3
  172. package/src/core/AudioParam.ts +5 -2
  173. package/src/core/AudioRecorder.ts +22 -62
  174. package/src/core/AudioScheduledSourceNode.ts +13 -2
  175. package/src/core/BiquadFilterNode.ts +4 -4
  176. package/src/core/GainNode.ts +1 -1
  177. package/src/core/OscillatorNode.ts +2 -2
  178. package/src/core/StereoPannerNode.ts +1 -1
  179. package/src/events/AudioEventEmitter.ts +29 -0
  180. package/src/events/AudioEventSubscription.ts +26 -0
  181. package/src/events/index.ts +4 -0
  182. package/src/events/types.ts +64 -0
  183. package/src/hooks/useSytemVolume.ts +2 -1
  184. package/src/interfaces.ts +19 -20
  185. package/src/specs/NativeAudioAPIModule.ts +23 -2
  186. package/src/specs/index.ts +2 -4
  187. package/src/system/AudioManager.ts +35 -43
  188. package/src/system/types.ts +0 -42
  189. package/src/types.ts +0 -8
  190. package/android/src/main/java/com/swmansion/audioapi/AudioManagerModule.kt +0 -77
  191. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionEventEmitter.kt +0 -88
  192. package/android/src/oldarch/NativeAudioManagerModuleSpec.java +0 -99
  193. package/ios/audioapi/ios/AudioManagerModule.h +0 -18
  194. package/ios/audioapi/ios/AudioManagerModule.mm +0 -108
  195. package/lib/commonjs/specs/NativeAudioManagerModule.js +0 -42
  196. package/lib/commonjs/specs/NativeAudioManagerModule.js.map +0 -1
  197. package/lib/module/specs/NativeAudioManagerModule.js +0 -39
  198. package/lib/module/specs/NativeAudioManagerModule.js.map +0 -1
  199. package/lib/typescript/specs/NativeAudioManagerModule.d.ts +0 -18
  200. package/lib/typescript/specs/NativeAudioManagerModule.d.ts.map +0 -1
  201. package/src/specs/NativeAudioManagerModule.ts +0 -53
@@ -4,12 +4,17 @@ import android.content.BroadcastReceiver
4
4
  import android.content.Context
5
5
  import android.content.Intent
6
6
  import android.media.AudioManager
7
+ import android.support.v4.media.session.MediaSessionCompat
7
8
  import android.view.KeyEvent
8
9
  import com.facebook.react.bridge.ReactApplicationContext
10
+ import com.swmansion.audioapi.AudioAPIModule
11
+ import java.lang.ref.WeakReference
9
12
 
10
13
  class MediaReceiver(
11
- val reactContext: ReactApplicationContext,
12
- private val mediaSessionManager: MediaSessionManager,
14
+ private val reactContext: WeakReference<ReactApplicationContext>,
15
+ private val mediaSession: WeakReference<MediaSessionCompat>,
16
+ private val mediaNotificationManager: WeakReference<MediaNotificationManager>,
17
+ private val audioAPIModule: WeakReference<AudioAPIModule>,
13
18
  ) : BroadcastReceiver() {
14
19
  override fun onReceive(
15
20
  context: Context?,
@@ -20,26 +25,31 @@ class MediaReceiver(
20
25
  if (MediaNotificationManager.REMOVE_NOTIFICATION == action) {
21
26
  if (!checkApp(intent)) return
22
27
 
23
- mediaSessionManager.mediaNotificationManager.hide()
24
- mediaSessionManager.mediaSession.isActive = false
28
+ mediaNotificationManager.get()?.hide()
29
+ mediaSession.get()?.isActive = false
25
30
 
26
- mediaSessionManager.eventEmitter.sendEvent("onCloseNotification", null)
31
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("closeNotification", mapOf()) // add to ts events
27
32
  } else if (MediaNotificationManager.MEDIA_BUTTON == action || Intent.ACTION_MEDIA_BUTTON == action) {
28
33
  if (!intent.hasExtra(Intent.EXTRA_KEY_EVENT)) return
29
34
  if (!checkApp(intent)) return
30
35
 
31
36
  val keyEvent = intent.getParcelableExtra<KeyEvent>(Intent.EXTRA_KEY_EVENT)
32
- mediaSessionManager.mediaSession.controller.dispatchMediaButtonEvent(keyEvent)
37
+ mediaSession.get()?.controller?.dispatchMediaButtonEvent(keyEvent)
33
38
  } else if (AudioManager.ACTION_AUDIO_BECOMING_NOISY == action) {
34
- mediaSessionManager.mediaSession.controller.transportControls
35
- .pause()
39
+ mediaSession
40
+ .get()
41
+ ?.controller
42
+ ?.transportControls
43
+ ?.pause()
36
44
  }
37
45
  }
38
46
 
39
47
  private fun checkApp(intent: Intent): Boolean {
40
48
  if (intent.hasExtra(MediaNotificationManager.PACKAGE_NAME)) {
41
49
  val name = intent.getStringExtra(MediaNotificationManager.PACKAGE_NAME)
42
- if (!reactContext.packageName.equals(name)) return false
50
+ if (!reactContext.get()?.packageName.equals(name)) {
51
+ return false
52
+ }
43
53
  }
44
54
  return true
45
55
  }
@@ -1,39 +1,58 @@
1
1
  package com.swmansion.audioapi.system
2
2
 
3
+ import android.content.Intent
4
+ import android.os.Build
3
5
  import android.support.v4.media.session.MediaSessionCompat
4
6
  import android.support.v4.media.session.PlaybackStateCompat
7
+ import androidx.core.app.NotificationManagerCompat
8
+ import com.swmansion.audioapi.AudioAPIModule
9
+ import java.lang.ref.WeakReference
10
+ import java.util.HashMap
5
11
 
6
12
  class MediaSessionCallback(
7
- val eventEmitter: MediaSessionEventEmitter,
8
- private val lockScreenManager: LockScreenManager,
13
+ private val audioAPIModule: WeakReference<AudioAPIModule>,
14
+ private val lockScreenManager: WeakReference<LockScreenManager>,
9
15
  ) : MediaSessionCompat.Callback() {
10
16
  override fun onPlay() {
11
- lockScreenManager.updatePlaybackState(PlaybackStateCompat.STATE_PLAYING)
12
- eventEmitter.onPlay()
17
+ lockScreenManager.get()?.updatePlaybackState(PlaybackStateCompat.STATE_PLAYING)
18
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePlay", mapOf())
13
19
  }
14
20
 
15
21
  override fun onPause() {
16
- lockScreenManager.updatePlaybackState(PlaybackStateCompat.STATE_PAUSED)
17
- eventEmitter.onPause()
22
+ lockScreenManager.get()?.updatePlaybackState(PlaybackStateCompat.STATE_PAUSED)
23
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePause", mapOf())
18
24
  }
19
25
 
20
26
  override fun onStop() {
21
- eventEmitter.onStop()
27
+ val reactContext = audioAPIModule.get()?.reactContext?.get()!!
28
+ NotificationManagerCompat.from(reactContext).cancel(MediaSessionManager.NOTIFICATION_ID)
29
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
30
+ val myIntent =
31
+ Intent(reactContext, MediaNotificationManager.NotificationService::class.java)
32
+ reactContext.stopService(myIntent)
33
+ }
34
+
35
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteStop", mapOf())
22
36
  }
23
37
 
24
38
  override fun onSkipToNext() {
25
- eventEmitter.onSkipToNext()
39
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteNextTrack", mapOf())
26
40
  }
27
41
 
28
42
  override fun onSkipToPrevious() {
29
- eventEmitter.onSkipToPrevious()
43
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePreviousTrack", mapOf())
30
44
  }
31
45
 
32
46
  override fun onFastForward() {
33
- eventEmitter.onFastForward()
47
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteSkipForward", mapOf())
34
48
  }
35
49
 
36
50
  override fun onRewind() {
37
- eventEmitter.onRewind()
51
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteSkipBackward", mapOf())
52
+ }
53
+
54
+ override fun onSeekTo(pos: Long) {
55
+ val body = HashMap<String, Any>().apply { put("value", (pos.toDouble() / 1000)) }
56
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteChangePlaybackPosition", body)
38
57
  }
39
58
  }
@@ -21,17 +21,19 @@ import androidx.core.app.NotificationCompat
21
21
  import androidx.core.content.ContextCompat
22
22
  import com.facebook.react.bridge.ReactApplicationContext
23
23
  import com.facebook.react.bridge.ReadableMap
24
+ import com.swmansion.audioapi.AudioAPIModule
25
+ import java.lang.ref.WeakReference
24
26
 
25
27
  object MediaSessionManager {
26
- lateinit var reactContext: ReactApplicationContext
27
- val notificationId = 100
28
- val channelId = "react-native-audio-api"
28
+ private lateinit var audioAPIModule: WeakReference<AudioAPIModule>
29
+ private lateinit var reactContext: WeakReference<ReactApplicationContext>
30
+ const val NOTIFICATION_ID = 100
31
+ const val CHANNEL_ID = "react-native-audio-api"
29
32
 
30
33
  private lateinit var audioManager: AudioManager
31
- lateinit var mediaSession: MediaSessionCompat
34
+ private lateinit var mediaSession: MediaSessionCompat
32
35
  lateinit var mediaNotificationManager: MediaNotificationManager
33
36
  private lateinit var lockScreenManager: LockScreenManager
34
- lateinit var eventEmitter: MediaSessionEventEmitter
35
37
  private lateinit var audioFocusListener: AudioFocusListener
36
38
  private lateinit var volumeChangeListener: VolumeChangeListener
37
39
  private lateinit var mediaReceiver: MediaReceiver
@@ -46,7 +48,7 @@ object MediaSessionManager {
46
48
  val binder = service as MediaNotificationManager.NotificationService.LocalBinder
47
49
  val notificationService = binder.getService()
48
50
  notificationService?.forceForeground()
49
- reactContext.unbindService(this)
51
+ reactContext.get()?.unbindService(this)
50
52
  }
51
53
 
52
54
  override fun onServiceDisconnected(name: ComponentName) {
@@ -62,20 +64,24 @@ object MediaSessionManager {
62
64
  }
63
65
  }
64
66
 
65
- fun initialize(reactContext: ReactApplicationContext) {
67
+ fun initialize(
68
+ audioAPIModule: WeakReference<AudioAPIModule>,
69
+ reactContext: WeakReference<ReactApplicationContext>,
70
+ ) {
71
+ this.audioAPIModule = audioAPIModule
66
72
  this.reactContext = reactContext
67
- this.audioManager = reactContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
68
- this.mediaSession = MediaSessionCompat(reactContext, "MediaSessionManager")
73
+ this.audioManager = reactContext.get()?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
74
+ this.mediaSession = MediaSessionCompat(reactContext.get()!!, "MediaSessionManager")
69
75
 
70
76
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
71
77
  createChannel()
72
78
  }
73
79
 
74
- this.mediaNotificationManager = MediaNotificationManager(reactContext, notificationId, channelId)
75
- this.lockScreenManager = LockScreenManager(reactContext, mediaSession, mediaNotificationManager, channelId)
76
- this.eventEmitter = MediaSessionEventEmitter(reactContext, notificationId)
77
- this.mediaReceiver = MediaReceiver(reactContext, this)
78
- this.mediaSession.setCallback(MediaSessionCallback(eventEmitter, lockScreenManager))
80
+ this.mediaNotificationManager = MediaNotificationManager(this.reactContext)
81
+ this.lockScreenManager = LockScreenManager(this.reactContext, WeakReference(this.mediaSession), WeakReference(mediaNotificationManager))
82
+ this.mediaReceiver =
83
+ MediaReceiver(this.reactContext, WeakReference(this.mediaSession), WeakReference(mediaNotificationManager), this.audioAPIModule)
84
+ this.mediaSession.setCallback(MediaSessionCallback(this.audioAPIModule, WeakReference(this.lockScreenManager)))
79
85
 
80
86
  val filter = IntentFilter()
81
87
  filter.addAction(MediaNotificationManager.REMOVE_NOTIFICATION)
@@ -84,29 +90,30 @@ object MediaSessionManager {
84
90
  filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
85
91
 
86
92
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
87
- reactContext.registerReceiver(mediaReceiver, filter, Context.RECEIVER_EXPORTED)
93
+ this.reactContext.get()!!.registerReceiver(mediaReceiver, filter, Context.RECEIVER_EXPORTED)
88
94
  } else {
89
95
  ContextCompat.registerReceiver(
90
- reactContext,
96
+ this.reactContext.get()!!,
91
97
  mediaReceiver,
92
98
  filter,
93
99
  ContextCompat.RECEIVER_NOT_EXPORTED,
94
100
  )
95
101
  }
96
102
 
97
- this.audioFocusListener = AudioFocusListener(audioManager, eventEmitter, lockScreenManager)
98
- this.volumeChangeListener = VolumeChangeListener(audioManager, eventEmitter)
103
+ this.audioFocusListener =
104
+ AudioFocusListener(WeakReference(this.audioManager), this.audioAPIModule, WeakReference(this.lockScreenManager))
105
+ this.volumeChangeListener = VolumeChangeListener(WeakReference(this.audioManager), this.audioAPIModule)
99
106
 
100
- val myIntent = Intent(reactContext, MediaNotificationManager.NotificationService::class.java)
107
+ val myIntent = Intent(this.reactContext.get(), MediaNotificationManager.NotificationService::class.java)
101
108
 
102
109
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
103
110
  try {
104
- reactContext.bindService(myIntent, connection, Context.BIND_AUTO_CREATE)
111
+ this.reactContext.get()?.bindService(myIntent, connection, Context.BIND_AUTO_CREATE)
105
112
  } catch (ignored: Exception) {
106
- ContextCompat.startForegroundService(reactContext, myIntent)
113
+ ContextCompat.startForegroundService(this.reactContext.get()!!, myIntent)
107
114
  }
108
115
  } else {
109
- reactContext.startService(myIntent)
116
+ this.reactContext.get()?.startService(myIntent)
110
117
  }
111
118
  }
112
119
 
@@ -141,13 +148,13 @@ object MediaSessionManager {
141
148
  fun observeVolumeChanges(observe: Boolean) {
142
149
  if (observe) {
143
150
  ContextCompat.registerReceiver(
144
- reactContext,
151
+ reactContext.get()!!,
145
152
  volumeChangeListener,
146
153
  volumeChangeListener.getIntentFilter(),
147
154
  ContextCompat.RECEIVER_NOT_EXPORTED,
148
155
  )
149
156
  } else {
150
- reactContext.unregisterReceiver(volumeChangeListener)
157
+ reactContext.get()?.unregisterReceiver(volumeChangeListener)
151
158
  }
152
159
  }
153
160
 
@@ -158,7 +165,7 @@ object MediaSessionManager {
158
165
 
159
166
  fun checkRecordingPermissions(): String =
160
167
  if (ContextCompat.checkSelfPermission(
161
- reactContext,
168
+ reactContext.get()!!,
162
169
  Manifest.permission.RECORD_AUDIO,
163
170
  ) == PackageManager.PERMISSION_GRANTED
164
171
  ) {
@@ -170,10 +177,10 @@ object MediaSessionManager {
170
177
  @RequiresApi(Build.VERSION_CODES.O)
171
178
  private fun createChannel() {
172
179
  val notificationManager =
173
- reactContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
180
+ reactContext.get()?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
174
181
 
175
182
  val mChannel =
176
- NotificationChannel(channelId, "Audio manager", NotificationManager.IMPORTANCE_LOW)
183
+ NotificationChannel(CHANNEL_ID, "Audio manager", NotificationManager.IMPORTANCE_LOW)
177
184
  mChannel.description = "Audio manager"
178
185
  mChannel.setShowBadge(false)
179
186
  mChannel.lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
@@ -5,18 +5,23 @@ import android.content.Context
5
5
  import android.content.Intent
6
6
  import android.content.IntentFilter
7
7
  import android.media.AudioManager
8
+ import com.swmansion.audioapi.AudioAPIModule
9
+ import java.lang.ref.WeakReference
10
+ import java.util.HashMap
8
11
 
9
12
  class VolumeChangeListener(
10
- private val audioManager: AudioManager,
11
- private val eventEmitter: MediaSessionEventEmitter,
13
+ private val audioManager: WeakReference<AudioManager>,
14
+ private val audioAPIModule: WeakReference<AudioAPIModule>,
12
15
  ) : BroadcastReceiver() {
13
16
  override fun onReceive(
14
17
  context: Context?,
15
18
  intent: Intent?,
16
19
  ) {
17
- val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC).toDouble()
18
- val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC).toDouble()
19
- eventEmitter.onVolumeChange(mapOf("value" to currentVolume / maxVolume))
20
+ val currentVolume = audioManager.get()?.getStreamVolume(AudioManager.STREAM_MUSIC)?.toDouble()!!
21
+ val maxVolume = audioManager.get()?.getStreamMaxVolume(AudioManager.STREAM_MUSIC)?.toDouble()!!
22
+
23
+ val body = HashMap<String, Any>().apply { put("value", currentVolume / maxVolume) }
24
+ audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("volumeChange", body)
20
25
  }
21
26
 
22
27
  fun getIntentFilter(): IntentFilter {
@@ -13,9 +13,12 @@
13
13
  package com.swmansion.audioapi;
14
14
 
15
15
  import com.facebook.proguard.annotations.DoNotStrip;
16
+ import com.facebook.react.bridge.Promise;
16
17
  import com.facebook.react.bridge.ReactApplicationContext;
17
18
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
18
19
  import com.facebook.react.bridge.ReactMethod;
20
+ import com.facebook.react.bridge.ReadableArray;
21
+ import com.facebook.react.bridge.ReadableMap;
19
22
  import com.facebook.react.turbomodule.core.interfaces.TurboModule;
20
23
  import javax.annotation.Nonnull;
21
24
 
@@ -34,4 +37,40 @@ public abstract class NativeAudioAPIModuleSpec extends ReactContextBaseJavaModul
34
37
  @ReactMethod(isBlockingSynchronousMethod = true)
35
38
  @DoNotStrip
36
39
  public abstract boolean install();
40
+
41
+ @ReactMethod
42
+ @DoNotStrip
43
+ public abstract void setLockScreenInfo(ReadableMap info);
44
+
45
+ @ReactMethod
46
+ @DoNotStrip
47
+ public abstract void resetLockScreenInfo();
48
+
49
+ @ReactMethod
50
+ @DoNotStrip
51
+ public abstract void enableRemoteCommand(String name, boolean enabled);
52
+
53
+ @ReactMethod
54
+ @DoNotStrip
55
+ public abstract void setAudioSessionOptions(String category, String mode, ReadableArray options);
56
+
57
+ @ReactMethod(isBlockingSynchronousMethod = true)
58
+ @DoNotStrip
59
+ public abstract double getDevicePreferredSampleRate();
60
+
61
+ @ReactMethod
62
+ @DoNotStrip
63
+ public abstract void observeAudioInterruptions(boolean enabled);
64
+
65
+ @ReactMethod
66
+ @DoNotStrip
67
+ public abstract void observeVolumeChanges(boolean enabled);
68
+
69
+ @ReactMethod
70
+ @DoNotStrip
71
+ public abstract void requestRecordingPermissions(Promise promise);
72
+
73
+ @ReactMethod
74
+ @DoNotStrip
75
+ public abstract void checkRecordingPermissions(Promise promise);
37
76
  }
@@ -8,6 +8,9 @@
8
8
  #include <audioapi/HostObjects/OfflineAudioContextHostObject.h>
9
9
  #include <audioapi/HostObjects/AudioRecorderHostObject.h>
10
10
 
11
+ #include <audioapi/events/AudioEventHandlerRegistry.h>
12
+ #include <audioapi/events/AudioEventHandlerRegistryHostObject.h>
13
+
11
14
  #include <memory>
12
15
 
13
16
  namespace audioapi {
@@ -16,30 +19,33 @@ using namespace facebook;
16
19
 
17
20
  class AudioAPIModuleInstaller {
18
21
  public:
19
- static void injectJSIBindings(jsi::Runtime *jsiRuntime, const std::shared_ptr<react::CallInvoker> &jsCallInvoker) {
20
- auto createAudioContext = getCreateAudioContextFunction(jsiRuntime, jsCallInvoker);
21
- auto createAudioRecorder = getCreateAudioRecorderFunction(jsiRuntime, jsCallInvoker);
22
- auto createOfflineAudioContext = getCreateOfflineAudioContextFunction(jsiRuntime, jsCallInvoker);
22
+ static void injectJSIBindings(jsi::Runtime *jsiRuntime, const std::shared_ptr<react::CallInvoker> &jsCallInvoker, const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry) {
23
+ auto createAudioContext = getCreateAudioContextFunction(jsiRuntime, jsCallInvoker, audioEventHandlerRegistry);
24
+ auto createAudioRecorder = getCreateAudioRecorderFunction(jsiRuntime, audioEventHandlerRegistry);
25
+ auto createOfflineAudioContext = getCreateOfflineAudioContextFunction(jsiRuntime, jsCallInvoker, audioEventHandlerRegistry);
23
26
 
24
27
  jsiRuntime->global().setProperty(*jsiRuntime, "createAudioContext", createAudioContext);
25
28
  jsiRuntime->global().setProperty(*jsiRuntime, "createAudioRecorder", createAudioRecorder);
26
29
  jsiRuntime->global().setProperty(*jsiRuntime, "createOfflineAudioContext", createOfflineAudioContext);
30
+
31
+ auto audioEventHandlerRegistryHostObject = std::make_shared<AudioEventHandlerRegistryHostObject>(audioEventHandlerRegistry);
32
+ jsiRuntime->global().setProperty(*jsiRuntime, "AudioEventEmitter", jsi::Object::createFromHostObject(*jsiRuntime, audioEventHandlerRegistryHostObject));
27
33
  }
28
34
 
29
35
  private:
30
- static jsi::Function getCreateAudioContextFunction(jsi::Runtime *jsiRuntime, const std::shared_ptr<react::CallInvoker> &jsCallInvoker) {
36
+ static jsi::Function getCreateAudioContextFunction(jsi::Runtime *jsiRuntime, const std::shared_ptr<react::CallInvoker> &jsCallInvoker, const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry) {
31
37
  return jsi::Function::createFromHostFunction(
32
38
  *jsiRuntime,
33
39
  jsi::PropNameID::forAscii(*jsiRuntime, "createAudioContext"),
34
40
  0,
35
- [jsCallInvoker](
41
+ [jsCallInvoker, audioEventHandlerRegistry](
36
42
  jsi::Runtime &runtime,
37
43
  const jsi::Value &thisValue,
38
44
  const jsi::Value *args,
39
45
  size_t count) -> jsi::Value {
40
46
  std::shared_ptr<AudioContext> audioContext;
41
47
  auto sampleRate = static_cast<float>(args[0].getNumber());
42
- audioContext = std::make_shared<AudioContext>(sampleRate);
48
+ audioContext = std::make_shared<AudioContext>(sampleRate, audioEventHandlerRegistry);
43
49
 
44
50
  auto audioContextHostObject = std::make_shared<AudioContextHostObject>(
45
51
  audioContext, &runtime, jsCallInvoker);
@@ -49,12 +55,12 @@ class AudioAPIModuleInstaller {
49
55
  });
50
56
  }
51
57
 
52
- static jsi::Function getCreateOfflineAudioContextFunction(jsi::Runtime *jsiRuntime, const std::shared_ptr<react::CallInvoker> &jsCallInvoker) {
58
+ static jsi::Function getCreateOfflineAudioContextFunction(jsi::Runtime *jsiRuntime, const std::shared_ptr<react::CallInvoker> &jsCallInvoker, const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry) {
53
59
  return jsi::Function::createFromHostFunction(
54
60
  *jsiRuntime,
55
61
  jsi::PropNameID::forAscii(*jsiRuntime, "createOfflineAudioContext"),
56
62
  0,
57
- [jsiRuntime, jsCallInvoker](
63
+ [jsCallInvoker, audioEventHandlerRegistry](
58
64
  jsi::Runtime &runtime,
59
65
  const jsi::Value &thisValue,
60
66
  const jsi::Value *args,
@@ -63,21 +69,21 @@ class AudioAPIModuleInstaller {
63
69
  auto length = static_cast<size_t>(args[1].getNumber());
64
70
  auto sampleRate = static_cast<float>(args[2].getNumber());
65
71
 
66
- auto offlineAudioContext = std::make_shared<OfflineAudioContext>(numberOfChannels, length, sampleRate);
72
+ auto offlineAudioContext = std::make_shared<OfflineAudioContext>(numberOfChannels, length, sampleRate, audioEventHandlerRegistry);
67
73
  auto audioContextHostObject = std::make_shared<OfflineAudioContextHostObject>(
68
- offlineAudioContext, jsiRuntime, jsCallInvoker);
74
+ offlineAudioContext, &runtime, jsCallInvoker);
69
75
 
70
76
  return jsi::Object::createFromHostObject(
71
77
  runtime, audioContextHostObject);
72
78
  });
73
79
  }
74
80
 
75
- static jsi::Function getCreateAudioRecorderFunction(jsi::Runtime *jsiRuntime, const std::shared_ptr<react::CallInvoker> &jsCallInvoker) {
81
+ static jsi::Function getCreateAudioRecorderFunction(jsi::Runtime *jsiRuntime, const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry) {
76
82
  return jsi::Function::createFromHostFunction(
77
83
  *jsiRuntime,
78
84
  jsi::PropNameID::forAscii(*jsiRuntime, "createAudioRecorder"),
79
85
  0,
80
- [jsCallInvoker](
86
+ [audioEventHandlerRegistry](
81
87
  jsi::Runtime &runtime,
82
88
  const jsi::Value &thisValue,
83
89
  const jsi::Value *args,
@@ -87,7 +93,7 @@ class AudioAPIModuleInstaller {
87
93
  auto sampleRate = static_cast<float>(options.getProperty(runtime, "sampleRate").getNumber());
88
94
  auto bufferLength = static_cast<int>(options.getProperty(runtime, "bufferLengthInSamples").getNumber());
89
95
 
90
- auto audioRecorderHostObject = std::make_shared<AudioRecorderHostObject>(&runtime, jsCallInvoker, sampleRate, bufferLength);
96
+ auto audioRecorderHostObject = std::make_shared<AudioRecorderHostObject>(&runtime, audioEventHandlerRegistry, sampleRate, bufferLength);
91
97
 
92
98
  return jsi::Object::createFromHostObject(runtime, audioRecorderHostObject);
93
99
  });
@@ -15,9 +15,8 @@ class AudioBufferSourceNodeHostObject
15
15
  : public AudioScheduledSourceNodeHostObject {
16
16
  public:
17
17
  explicit AudioBufferSourceNodeHostObject(
18
- const std::shared_ptr<AudioBufferSourceNode> &node,
19
- const std::shared_ptr<react::CallInvoker> &callInvoker)
20
- : AudioScheduledSourceNodeHostObject(node, callInvoker) {
18
+ const std::shared_ptr<AudioBufferSourceNode> &node)
19
+ : AudioScheduledSourceNodeHostObject(node) {
21
20
  addGetters(
22
21
  JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, loop),
23
22
  JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, buffer),
@@ -1,7 +1,8 @@
1
1
  #pragma once
2
2
 
3
- #include <audioapi/jsi/JsiHostObject.h>
3
+ #include <audioapi/HostObjects/AudioParamHostObject.h>
4
4
  #include <audioapi/core/AudioNode.h>
5
+ #include <audioapi/jsi/JsiHostObject.h>
5
6
 
6
7
  #include <jsi/jsi.h>
7
8
  #include <memory>
@@ -47,21 +48,33 @@ class AudioNodeHostObject : public JsiHostObject {
47
48
  }
48
49
 
49
50
  JSI_HOST_FUNCTION(connect) {
50
- auto node =
51
- args[0].getObject(runtime).getHostObject<AudioNodeHostObject>(runtime);
52
- node_->connect(std::shared_ptr<AudioNodeHostObject>(node)->node_);
51
+ auto obj = args[0].getObject(runtime);
52
+ if (obj.isHostObject<AudioNodeHostObject>(runtime)) {
53
+ auto node = obj.getHostObject<AudioNodeHostObject>(runtime);
54
+ node_->connect(std::shared_ptr<AudioNodeHostObject>(node)->node_);
55
+ }
56
+ if (obj.isHostObject<AudioParamHostObject>(runtime)) {
57
+ auto param = obj.getHostObject<AudioParamHostObject>(runtime);
58
+ node_->connect(std::shared_ptr<AudioParamHostObject>(param)->param_);
59
+ }
53
60
  return jsi::Value::undefined();
54
61
  }
55
62
 
56
63
  JSI_HOST_FUNCTION(disconnect) {
57
- if(args[0].isUndefined()) {
58
- node_->disconnect();
59
- return jsi::Value::undefined();
60
- }
64
+ if (args[0].isUndefined()) {
65
+ node_->disconnect();
66
+ return jsi::Value::undefined();
67
+ }
68
+ auto obj = args[0].getObject(runtime);
69
+ if (obj.isHostObject<AudioNodeHostObject>(runtime)) {
70
+ auto node = obj.getHostObject<AudioNodeHostObject>(runtime);
71
+ node_->disconnect(std::shared_ptr<AudioNodeHostObject>(node)->node_);
72
+ }
61
73
 
62
- auto node =
63
- args[0].getObject(runtime).getHostObject<AudioNodeHostObject>(runtime);
64
- node_->disconnect(std::shared_ptr<AudioNodeHostObject>(node)->node_);
74
+ if (obj.isHostObject<AudioParamHostObject>(runtime)) {
75
+ auto param = obj.getHostObject<AudioParamHostObject>(runtime);
76
+ node_->disconnect(std::shared_ptr<AudioParamHostObject>(param)->param_);
77
+ }
65
78
  return jsi::Value::undefined();
66
79
  }
67
80
 
@@ -32,6 +32,7 @@ class AudioParamHostObject : public JsiHostObject {
32
32
 
33
33
  addSetters(JSI_EXPORT_PROPERTY_SETTER(AudioParamHostObject, value));
34
34
  }
35
+ friend class AudioNodeHostObject;
35
36
 
36
37
  JSI_PROPERTY_GETTER(value) {
37
38
  return {param_->getValue()};
@@ -24,42 +24,28 @@ class AudioRecorderHostObject : public JsiHostObject {
24
24
  public:
25
25
  explicit AudioRecorderHostObject(
26
26
  jsi::Runtime *runtime,
27
- const std::shared_ptr<react::CallInvoker> &callInvoker,
27
+ const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry,
28
28
  float sampleRate,
29
- int bufferLength)
30
- : callInvoker_(callInvoker) {
31
- promiseVendor_ = std::make_shared<PromiseVendor>(runtime, callInvoker);
32
-
29
+ int bufferLength) {
33
30
  #ifdef ANDROID
34
31
  audioRecorder_ = std::make_shared<AndroidAudioRecorder>(
35
32
  sampleRate,
36
33
  bufferLength,
37
- this->getOnError(),
38
- this->getOnStatusChange(),
39
- this->getOnAudioReady()
34
+ audioEventHandlerRegistry
40
35
  );
41
36
  #else
42
37
  audioRecorder_ = std::make_shared<IOSAudioRecorder>(
43
38
  sampleRate,
44
39
  bufferLength,
45
- this->getOnError(),
46
- this->getOnStatusChange(),
47
- this->getOnAudioReady()
40
+ audioEventHandlerRegistry
48
41
  );
49
42
  #endif
50
43
 
44
+ addSetters(JSI_EXPORT_PROPERTY_SETTER(AudioRecorderHostObject, onAudioReady));
45
+
51
46
  addFunctions(
52
47
  JSI_EXPORT_FUNCTION(AudioRecorderHostObject, start),
53
- JSI_EXPORT_FUNCTION(AudioRecorderHostObject, stop),
54
- JSI_EXPORT_FUNCTION(AudioRecorderHostObject, onAudioReady),
55
- JSI_EXPORT_FUNCTION(AudioRecorderHostObject, onError),
56
- JSI_EXPORT_FUNCTION(AudioRecorderHostObject, onStatusChange));
57
- }
58
-
59
- ~AudioRecorderHostObject() override {
60
- errorCallback_ = nullptr;
61
- audioReadyCallback_ = nullptr;
62
- statusChangeCallback_ = nullptr;
48
+ JSI_EXPORT_FUNCTION(AudioRecorderHostObject, stop));
63
49
  }
64
50
 
65
51
  JSI_HOST_FUNCTION(start) {
@@ -74,76 +60,11 @@ class AudioRecorderHostObject : public JsiHostObject {
74
60
  return jsi::Value::undefined();
75
61
  }
76
62
 
77
- JSI_HOST_FUNCTION(onAudioReady) {
78
- audioReadyCallback_ = std::make_unique<jsi::Function>(args[0].getObject(runtime).getFunction(runtime));
79
-
80
- return jsi::Value::undefined();
81
- }
82
-
83
- JSI_HOST_FUNCTION(onError) {
84
- errorCallback_ = std::make_unique<jsi::Function>(args[0].getObject(runtime).getFunction(runtime));
85
-
86
- return jsi::Value::undefined();
87
- }
88
-
89
- JSI_HOST_FUNCTION(onStatusChange) {
90
- statusChangeCallback_ = std::make_unique<jsi::Function>(args[0].getObject(runtime).getFunction(runtime));
91
-
92
- return jsi::Value::undefined();
63
+ JSI_PROPERTY_SETTER(onAudioReady) {
64
+ audioRecorder_->setOnAudioReadyCallbackId(std::stoull(value.getString(runtime).utf8(runtime)));
93
65
  }
94
66
 
95
- protected:
67
+ private:
96
68
  std::shared_ptr<AudioRecorder> audioRecorder_;
97
- std::shared_ptr<PromiseVendor> promiseVendor_;
98
- std::shared_ptr<react::CallInvoker> callInvoker_;
99
-
100
- std::unique_ptr<jsi::Function> errorCallback_;
101
- std::unique_ptr<jsi::Function> audioReadyCallback_;
102
- std::unique_ptr<jsi::Function> statusChangeCallback_;
103
-
104
- std::function<void(std::shared_ptr<AudioBus>, int, double)> getOnAudioReady() {
105
- return [this](const std::shared_ptr<AudioBus> &bus, int numFrames, double when) {
106
- if (audioReadyCallback_ == nullptr) {
107
- return;
108
- }
109
-
110
- callInvoker_->invokeAsync([this, bus = bus, numFrames, when](jsi::Runtime &runtime) {
111
- auto buffer = std::make_shared<AudioBuffer>(bus);
112
- auto bufferHostObject = std::make_shared<AudioBufferHostObject>(buffer);
113
-
114
- audioReadyCallback_->call(
115
- runtime,
116
- jsi::Object::createFromHostObject(runtime, bufferHostObject),
117
- jsi::Value(numFrames),
118
- jsi::Value(when)
119
- );
120
- });
121
- };
122
- }
123
-
124
- std::function<void(void)> getOnError() {
125
- return [this]() {
126
- if (errorCallback_ == nullptr) {
127
- return;
128
- }
129
-
130
- callInvoker_->invokeAsync([this](jsi::Runtime &runtime) {
131
- errorCallback_->call(runtime);
132
- });
133
- };
134
- }
135
-
136
- std::function<void(void)> getOnStatusChange() {
137
- return [this]() {
138
- if (statusChangeCallback_ == nullptr) {
139
- return;
140
- }
141
-
142
- callInvoker_->invokeAsync([this](jsi::Runtime &runtime) {
143
- statusChangeCallback_->call(runtime);
144
- });
145
- };
146
- }
147
69
  };
148
-
149
70
  } // namespace audioapi