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.
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +35 -2
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +4 -0
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +31 -17
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +1 -3
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +56 -2
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +0 -12
- package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +35 -12
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +30 -29
- package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +20 -22
- package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +19 -9
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +30 -11
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +34 -27
- package/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt +10 -5
- package/android/src/oldarch/NativeAudioAPIModuleSpec.java +39 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +20 -14
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +2 -3
- package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +24 -11
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +1 -0
- package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +10 -89
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +3 -24
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +2 -2
- package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +2 -3
- package/common/cpp/audioapi/core/AudioContext.cpp +4 -1
- package/common/cpp/audioapi/core/AudioContext.h +1 -1
- package/common/cpp/audioapi/core/AudioNode.cpp +31 -2
- package/common/cpp/audioapi/core/AudioNode.h +7 -1
- package/common/cpp/audioapi/core/AudioParam.cpp +84 -2
- package/common/cpp/audioapi/core/AudioParam.h +14 -1
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +6 -1
- package/common/cpp/audioapi/core/BaseAudioContext.h +7 -1
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +3 -2
- package/common/cpp/audioapi/core/OfflineAudioContext.h +1 -1
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +28 -26
- package/common/cpp/audioapi/core/effects/GainNode.cpp +9 -9
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +5 -2
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +56 -0
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +13 -13
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +14 -10
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +1 -1
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +7 -6
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +5 -3
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +15 -10
- package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +35 -1
- package/common/cpp/audioapi/core/utils/AudioNodeManager.h +15 -1
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +108 -0
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +62 -0
- package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +48 -0
- package/common/cpp/audioapi/jsi/JsiPromise.cpp +3 -4
- package/ios/audioapi/ios/AudioAPIModule.h +13 -0
- package/ios/audioapi/ios/AudioAPIModule.mm +115 -6
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +2 -10
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +6 -17
- package/ios/audioapi/ios/core/NativeAudioPlayer.m +2 -0
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +7 -3
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +7 -0
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +12 -0
- package/ios/audioapi/ios/system/AudioEngine.h +5 -0
- package/ios/audioapi/ios/system/AudioEngine.mm +7 -15
- package/ios/audioapi/ios/system/AudioSessionManager.h +1 -1
- package/ios/audioapi/ios/system/AudioSessionManager.mm +2 -18
- package/ios/audioapi/ios/system/LockScreenManager.h +3 -3
- package/ios/audioapi/ios/system/LockScreenManager.mm +36 -48
- package/ios/audioapi/ios/system/NotificationManager.h +3 -3
- package/ios/audioapi/ios/system/NotificationManager.mm +21 -29
- package/lib/commonjs/api.js +4 -4
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/AudioBufferSourceNode.js +2 -2
- package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/commonjs/core/AudioNode.js +8 -2
- package/lib/commonjs/core/AudioNode.js.map +1 -1
- package/lib/commonjs/core/AudioParam.js +2 -1
- package/lib/commonjs/core/AudioParam.js.map +1 -1
- package/lib/commonjs/core/AudioRecorder.js +11 -28
- package/lib/commonjs/core/AudioRecorder.js.map +1 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/commonjs/core/BiquadFilterNode.js +4 -4
- package/lib/commonjs/core/BiquadFilterNode.js.map +1 -1
- package/lib/commonjs/core/GainNode.js +1 -1
- package/lib/commonjs/core/GainNode.js.map +1 -1
- package/lib/commonjs/core/OscillatorNode.js +2 -2
- package/lib/commonjs/core/OscillatorNode.js.map +1 -1
- package/lib/commonjs/core/StereoPannerNode.js +1 -1
- package/lib/commonjs/core/StereoPannerNode.js.map +1 -1
- package/lib/commonjs/events/AudioEventEmitter.js +22 -0
- package/lib/commonjs/events/AudioEventEmitter.js.map +1 -0
- package/lib/commonjs/events/AudioEventSubscription.js +20 -0
- package/lib/commonjs/events/AudioEventSubscription.js.map +1 -0
- package/lib/commonjs/events/index.js +21 -0
- package/lib/commonjs/events/index.js.map +1 -0
- package/lib/commonjs/events/types.js +6 -0
- package/lib/commonjs/events/types.js.map +1 -0
- package/lib/commonjs/hooks/useSytemVolume.js +1 -1
- package/lib/commonjs/hooks/useSytemVolume.js.map +1 -1
- package/lib/commonjs/specs/NativeAudioAPIModule.js +3 -3
- package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/commonjs/specs/index.js +2 -16
- package/lib/commonjs/specs/index.js.map +1 -1
- package/lib/commonjs/system/AudioManager.js +22 -28
- package/lib/commonjs/system/AudioManager.js.map +1 -1
- package/lib/module/api.js +2 -2
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +2 -2
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioNode.js +7 -2
- package/lib/module/core/AudioNode.js.map +1 -1
- package/lib/module/core/AudioParam.js +2 -1
- package/lib/module/core/AudioParam.js.map +1 -1
- package/lib/module/core/AudioRecorder.js +11 -28
- package/lib/module/core/AudioRecorder.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +4 -1
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BiquadFilterNode.js +4 -4
- package/lib/module/core/BiquadFilterNode.js.map +1 -1
- package/lib/module/core/GainNode.js +1 -1
- package/lib/module/core/GainNode.js.map +1 -1
- package/lib/module/core/OscillatorNode.js +2 -2
- package/lib/module/core/OscillatorNode.js.map +1 -1
- package/lib/module/core/StereoPannerNode.js +1 -1
- package/lib/module/core/StereoPannerNode.js.map +1 -1
- package/lib/module/events/AudioEventEmitter.js +16 -0
- package/lib/module/events/AudioEventEmitter.js.map +1 -0
- package/lib/module/events/AudioEventSubscription.js +15 -0
- package/lib/module/events/AudioEventSubscription.js.map +1 -0
- package/lib/module/events/index.js +6 -0
- package/lib/module/events/index.js.map +1 -0
- package/lib/module/events/types.js +4 -0
- package/lib/module/events/types.js.map +1 -0
- package/lib/module/hooks/useSytemVolume.js +1 -1
- package/lib/module/hooks/useSytemVolume.js.map +1 -1
- package/lib/module/specs/NativeAudioAPIModule.js +3 -2
- package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/module/specs/index.js +2 -3
- package/lib/module/specs/index.js.map +1 -1
- package/lib/module/system/AudioManager.js +23 -29
- package/lib/module/system/AudioManager.js.map +1 -1
- package/lib/typescript/api.d.ts +2 -1
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioNode.d.ts +2 -1
- package/lib/typescript/core/AudioNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioParam.d.ts +4 -2
- package/lib/typescript/core/AudioParam.d.ts.map +1 -1
- package/lib/typescript/core/AudioRecorder.d.ts +4 -14
- package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +3 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/events/AudioEventEmitter.d.ts +10 -0
- package/lib/typescript/events/AudioEventEmitter.d.ts.map +1 -0
- package/lib/typescript/events/AudioEventSubscription.d.ts +11 -0
- package/lib/typescript/events/AudioEventSubscription.d.ts.map +1 -0
- package/lib/typescript/events/index.d.ts +4 -0
- package/lib/typescript/events/index.d.ts.map +1 -0
- package/lib/typescript/events/types.d.ts +50 -0
- package/lib/typescript/events/types.d.ts.map +1 -0
- package/lib/typescript/hooks/useSytemVolume.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +10 -10
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts +15 -3
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
- package/lib/typescript/specs/index.d.ts +2 -3
- package/lib/typescript/specs/index.d.ts.map +1 -1
- package/lib/typescript/system/AudioManager.d.ts +6 -4
- package/lib/typescript/system/AudioManager.d.ts.map +1 -1
- package/lib/typescript/system/types.d.ts +0 -34
- package/lib/typescript/system/types.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +0 -1
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/api.ts +6 -3
- package/src/core/AudioBufferSourceNode.ts +2 -2
- package/src/core/AudioNode.ts +8 -3
- package/src/core/AudioParam.ts +5 -2
- package/src/core/AudioRecorder.ts +22 -62
- package/src/core/AudioScheduledSourceNode.ts +13 -2
- package/src/core/BiquadFilterNode.ts +4 -4
- package/src/core/GainNode.ts +1 -1
- package/src/core/OscillatorNode.ts +2 -2
- package/src/core/StereoPannerNode.ts +1 -1
- package/src/events/AudioEventEmitter.ts +29 -0
- package/src/events/AudioEventSubscription.ts +26 -0
- package/src/events/index.ts +4 -0
- package/src/events/types.ts +64 -0
- package/src/hooks/useSytemVolume.ts +2 -1
- package/src/interfaces.ts +19 -20
- package/src/specs/NativeAudioAPIModule.ts +23 -2
- package/src/specs/index.ts +2 -4
- package/src/system/AudioManager.ts +35 -43
- package/src/system/types.ts +0 -42
- package/src/types.ts +0 -8
- package/android/src/main/java/com/swmansion/audioapi/AudioManagerModule.kt +0 -77
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionEventEmitter.kt +0 -88
- package/android/src/oldarch/NativeAudioManagerModuleSpec.java +0 -99
- package/ios/audioapi/ios/AudioManagerModule.h +0 -18
- package/ios/audioapi/ios/AudioManagerModule.mm +0 -108
- package/lib/commonjs/specs/NativeAudioManagerModule.js +0 -42
- package/lib/commonjs/specs/NativeAudioManagerModule.js.map +0 -1
- package/lib/module/specs/NativeAudioManagerModule.js +0 -39
- package/lib/module/specs/NativeAudioManagerModule.js.map +0 -1
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts +0 -18
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts.map +0 -1
- 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
|
|
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
|
-
|
|
24
|
-
|
|
28
|
+
mediaNotificationManager.get()?.hide()
|
|
29
|
+
mediaSession.get()?.isActive = false
|
|
25
30
|
|
|
26
|
-
|
|
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
|
-
|
|
37
|
+
mediaSession.get()?.controller?.dispatchMediaButtonEvent(keyEvent)
|
|
33
38
|
} else if (AudioManager.ACTION_AUDIO_BECOMING_NOISY == action) {
|
|
34
|
-
|
|
35
|
-
.
|
|
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))
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
22
|
+
lockScreenManager.get()?.updatePlaybackState(PlaybackStateCompat.STATE_PAUSED)
|
|
23
|
+
audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePause", mapOf())
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
override fun onStop() {
|
|
21
|
-
|
|
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
|
-
|
|
39
|
+
audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteNextTrack", mapOf())
|
|
26
40
|
}
|
|
27
41
|
|
|
28
42
|
override fun onSkipToPrevious() {
|
|
29
|
-
|
|
43
|
+
audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePreviousTrack", mapOf())
|
|
30
44
|
}
|
|
31
45
|
|
|
32
46
|
override fun onFastForward() {
|
|
33
|
-
|
|
47
|
+
audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteSkipForward", mapOf())
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
override fun onRewind() {
|
|
37
|
-
|
|
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
|
|
27
|
-
|
|
28
|
-
val
|
|
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(
|
|
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
|
|
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
|
|
75
|
-
this.lockScreenManager = LockScreenManager(reactContext, mediaSession, mediaNotificationManager
|
|
76
|
-
this.
|
|
77
|
-
|
|
78
|
-
this.mediaSession.setCallback(MediaSessionCallback(
|
|
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 =
|
|
98
|
-
|
|
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
|
|
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(
|
|
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
|
|
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)
|
|
18
|
-
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
|
19
|
-
|
|
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,
|
|
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
|
-
[
|
|
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,
|
|
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<
|
|
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
|
-
[
|
|
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,
|
|
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
|
-
|
|
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/
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
|
|
@@ -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<
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
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
|
-
|
|
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
|