react-native-audio-api 0.6.1-rc.8 → 0.6.1
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/core/AudioPlayer.cpp +12 -1
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +2 -0
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +6 -6
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +6 -1
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +0 -4
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +8 -8
- package/android/src/main/java/com/swmansion/audioapi/system/PermissionRequestListener.kt +33 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +2 -1
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +10 -0
- package/common/cpp/audioapi/core/AudioContext.cpp +30 -5
- package/common/cpp/audioapi/core/AudioContext.h +2 -1
- package/common/cpp/audioapi/core/AudioParam.cpp +5 -4
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +6 -10
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +1 -1
- package/ios/audioapi/ios/AudioAPIModule.mm +11 -11
- package/ios/audioapi/ios/core/IOSAudioPlayer.h +2 -0
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +16 -0
- package/ios/audioapi/ios/core/NativeAudioPlayer.h +4 -0
- package/ios/audioapi/ios/core/NativeAudioPlayer.m +15 -0
- package/ios/audioapi/ios/system/AudioEngine.h +2 -3
- package/ios/audioapi/ios/system/AudioEngine.mm +32 -1
- package/ios/audioapi/ios/system/AudioSessionManager.h +3 -2
- package/ios/audioapi/ios/system/AudioSessionManager.mm +55 -4
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/AudioContext.js +2 -2
- package/lib/commonjs/core/AudioContext.js.map +1 -1
- package/lib/commonjs/plugin/withAudioAPI.js +4 -4
- package/lib/commonjs/plugin/withAudioAPI.js.map +1 -1
- package/lib/commonjs/web-core/AudioContext.js +5 -3
- package/lib/commonjs/web-core/AudioContext.js.map +1 -1
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioContext.js +2 -2
- package/lib/module/core/AudioContext.js.map +1 -1
- package/lib/module/plugin/withAudioAPI.js +4 -4
- package/lib/module/plugin/withAudioAPI.js.map +1 -1
- package/lib/module/web-core/AudioContext.js +5 -3
- package/lib/module/web-core/AudioContext.js.map +1 -1
- package/lib/typescript/api.d.ts +1 -1
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioContext.d.ts.map +1 -1
- package/lib/typescript/plugin/withAudioAPI.d.ts +1 -1
- package/lib/typescript/plugin/withAudioAPI.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +2 -1
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioContext.d.ts +1 -1
- package/lib/typescript/web-core/AudioContext.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api.ts +4 -1
- package/src/core/AudioContext.ts +7 -2
- package/src/plugin/withAudioAPI.ts +7 -9
- package/src/types.ts +2 -1
- package/src/web-core/AudioContext.tsx +7 -3
|
@@ -34,6 +34,18 @@ void AudioPlayer::start() {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
void AudioPlayer::stop() {
|
|
37
|
+
if (mStream_) {
|
|
38
|
+
mStream_->requestStop();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void AudioPlayer::resume() {
|
|
43
|
+
if (mStream_) {
|
|
44
|
+
mStream_->requestStart();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
void AudioPlayer::suspend() {
|
|
37
49
|
if (mStream_) {
|
|
38
50
|
mStream_->requestPause();
|
|
39
51
|
}
|
|
@@ -43,7 +55,6 @@ void AudioPlayer::cleanup() {
|
|
|
43
55
|
isInitialized_ = false;
|
|
44
56
|
|
|
45
57
|
if (mStream_) {
|
|
46
|
-
mStream_->requestStop();
|
|
47
58
|
mStream_->close();
|
|
48
59
|
mStream_.reset();
|
|
49
60
|
}
|
|
@@ -9,6 +9,7 @@ import com.facebook.react.common.annotations.FrameworkAPI
|
|
|
9
9
|
import com.facebook.react.module.annotations.ReactModule
|
|
10
10
|
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
|
|
11
11
|
import com.swmansion.audioapi.system.MediaSessionManager
|
|
12
|
+
import com.swmansion.audioapi.system.PermissionRequestListener
|
|
12
13
|
import java.lang.ref.WeakReference
|
|
13
14
|
|
|
14
15
|
@OptIn(FrameworkAPI::class)
|
|
@@ -93,13 +94,12 @@ class AudioAPIModule(
|
|
|
93
94
|
MediaSessionManager.observeVolumeChanges(enabled)
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
override fun requestRecordingPermissions(promise: Promise
|
|
97
|
-
val
|
|
98
|
-
|
|
97
|
+
override fun requestRecordingPermissions(promise: Promise) {
|
|
98
|
+
val permissionRequestListener = PermissionRequestListener(promise)
|
|
99
|
+
MediaSessionManager.requestRecordingPermissions(permissionRequestListener)
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
override fun checkRecordingPermissions(promise: Promise
|
|
102
|
-
|
|
103
|
-
promise!!.resolve(res)
|
|
102
|
+
override fun checkRecordingPermissions(promise: Promise) {
|
|
103
|
+
promise.resolve(MediaSessionManager.checkRecordingPermissions())
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -254,7 +254,7 @@ class LockScreenManager(
|
|
|
254
254
|
return bitmap
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
fun updatePlaybackState(playbackState: Int) {
|
|
257
|
+
private fun updatePlaybackState(playbackState: Int) {
|
|
258
258
|
isPlaying = playbackState == PlaybackStateCompat.STATE_PLAYING
|
|
259
259
|
|
|
260
260
|
pb.setState(playbackState, elapsedTime, speed)
|
|
@@ -289,6 +289,11 @@ class LockScreenManager(
|
|
|
289
289
|
if (hasControl(PlaybackStateCompat.ACTION_REWIND)) {
|
|
290
290
|
controlCount += 1
|
|
291
291
|
}
|
|
292
|
+
|
|
293
|
+
if (hasControl(PlaybackStateCompat.ACTION_SEEK_TO)) {
|
|
294
|
+
controlCount += 1
|
|
295
|
+
}
|
|
296
|
+
|
|
292
297
|
val actions = IntArray(controlCount)
|
|
293
298
|
for (i in actions.indices) {
|
|
294
299
|
actions[i] = i
|
|
@@ -3,7 +3,6 @@ package com.swmansion.audioapi.system
|
|
|
3
3
|
import android.content.Intent
|
|
4
4
|
import android.os.Build
|
|
5
5
|
import android.support.v4.media.session.MediaSessionCompat
|
|
6
|
-
import android.support.v4.media.session.PlaybackStateCompat
|
|
7
6
|
import androidx.core.app.NotificationManagerCompat
|
|
8
7
|
import com.swmansion.audioapi.AudioAPIModule
|
|
9
8
|
import java.lang.ref.WeakReference
|
|
@@ -11,15 +10,12 @@ import java.util.HashMap
|
|
|
11
10
|
|
|
12
11
|
class MediaSessionCallback(
|
|
13
12
|
private val audioAPIModule: WeakReference<AudioAPIModule>,
|
|
14
|
-
private val lockScreenManager: WeakReference<LockScreenManager>,
|
|
15
13
|
) : MediaSessionCompat.Callback() {
|
|
16
14
|
override fun onPlay() {
|
|
17
|
-
lockScreenManager.get()?.updatePlaybackState(PlaybackStateCompat.STATE_PLAYING)
|
|
18
15
|
audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePlay", mapOf())
|
|
19
16
|
}
|
|
20
17
|
|
|
21
18
|
override fun onPause() {
|
|
22
|
-
lockScreenManager.get()?.updatePlaybackState(PlaybackStateCompat.STATE_PAUSED)
|
|
23
19
|
audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePause", mapOf())
|
|
24
20
|
}
|
|
25
21
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package com.swmansion.audioapi.system
|
|
2
2
|
|
|
3
3
|
import android.Manifest
|
|
4
|
-
import android.app.Activity
|
|
5
4
|
import android.app.NotificationChannel
|
|
6
5
|
import android.app.NotificationManager
|
|
7
6
|
import android.content.ComponentName
|
|
@@ -16,12 +15,14 @@ import android.os.IBinder
|
|
|
16
15
|
import android.support.v4.media.session.MediaSessionCompat
|
|
17
16
|
import android.util.Log
|
|
18
17
|
import androidx.annotation.RequiresApi
|
|
19
|
-
import androidx.core.app.ActivityCompat
|
|
20
18
|
import androidx.core.app.NotificationCompat
|
|
21
19
|
import androidx.core.content.ContextCompat
|
|
22
20
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
23
21
|
import com.facebook.react.bridge.ReadableMap
|
|
22
|
+
import com.facebook.react.modules.core.PermissionAwareActivity
|
|
23
|
+
import com.facebook.react.modules.core.PermissionListener
|
|
24
24
|
import com.swmansion.audioapi.AudioAPIModule
|
|
25
|
+
import com.swmansion.audioapi.system.PermissionRequestListener.Companion.RECORDING_REQUEST_CODE
|
|
25
26
|
import java.lang.ref.WeakReference
|
|
26
27
|
|
|
27
28
|
object MediaSessionManager {
|
|
@@ -81,7 +82,7 @@ object MediaSessionManager {
|
|
|
81
82
|
this.lockScreenManager = LockScreenManager(this.reactContext, WeakReference(this.mediaSession), WeakReference(mediaNotificationManager))
|
|
82
83
|
this.mediaReceiver =
|
|
83
84
|
MediaReceiver(this.reactContext, WeakReference(this.mediaSession), WeakReference(mediaNotificationManager), this.audioAPIModule)
|
|
84
|
-
this.mediaSession.setCallback(MediaSessionCallback(this.audioAPIModule
|
|
85
|
+
this.mediaSession.setCallback(MediaSessionCallback(this.audioAPIModule))
|
|
85
86
|
|
|
86
87
|
val filter = IntentFilter()
|
|
87
88
|
filter.addAction(MediaNotificationManager.REMOVE_NOTIFICATION)
|
|
@@ -158,14 +159,13 @@ object MediaSessionManager {
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
fun requestRecordingPermissions(
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
fun requestRecordingPermissions(permissionListener: PermissionListener) {
|
|
163
|
+
val permissionAwareActivity = reactContext.get()!!.currentActivity as PermissionAwareActivity
|
|
164
|
+
permissionAwareActivity.requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), RECORDING_REQUEST_CODE, permissionListener)
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
fun checkRecordingPermissions(): String =
|
|
167
|
-
if (
|
|
168
|
-
reactContext.get()!!,
|
|
168
|
+
if (reactContext.get()!!.checkSelfPermission(
|
|
169
169
|
Manifest.permission.RECORD_AUDIO,
|
|
170
170
|
) == PackageManager.PERMISSION_GRANTED
|
|
171
171
|
) {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.swmansion.audioapi.system
|
|
2
|
+
|
|
3
|
+
import android.content.pm.PackageManager
|
|
4
|
+
import com.facebook.react.bridge.Promise
|
|
5
|
+
import com.facebook.react.modules.core.PermissionListener
|
|
6
|
+
|
|
7
|
+
class PermissionRequestListener(
|
|
8
|
+
private val promise: Promise,
|
|
9
|
+
) : PermissionListener {
|
|
10
|
+
companion object {
|
|
11
|
+
const val RECORDING_REQUEST_CODE = 1234
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
override fun onRequestPermissionsResult(
|
|
15
|
+
requestCode: Int,
|
|
16
|
+
permissions: Array<String>,
|
|
17
|
+
grantResults: IntArray,
|
|
18
|
+
): Boolean {
|
|
19
|
+
if (requestCode == RECORDING_REQUEST_CODE) {
|
|
20
|
+
if (grantResults.isEmpty()) {
|
|
21
|
+
this.promise.resolve("Undetermined")
|
|
22
|
+
} else {
|
|
23
|
+
val granted = grantResults[0] == PackageManager.PERMISSION_GRANTED
|
|
24
|
+
if (granted) {
|
|
25
|
+
this.promise.resolve("Granted")
|
|
26
|
+
} else {
|
|
27
|
+
this.promise.resolve("Denied")
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -45,7 +45,8 @@ class AudioAPIModuleInstaller {
|
|
|
45
45
|
size_t count) -> jsi::Value {
|
|
46
46
|
std::shared_ptr<AudioContext> audioContext;
|
|
47
47
|
auto sampleRate = static_cast<float>(args[0].getNumber());
|
|
48
|
-
|
|
48
|
+
auto initSuspended = args[1].getBool();
|
|
49
|
+
audioContext = std::make_shared<AudioContext>(sampleRate, initSuspended, audioEventHandlerRegistry);
|
|
49
50
|
|
|
50
51
|
auto audioContextHostObject = std::make_shared<AudioContextHostObject>(
|
|
51
52
|
audioContext, &runtime, jsCallInvoker);
|
|
@@ -45,6 +45,11 @@ class AudioContextHostObject : public BaseAudioContextHostObject {
|
|
|
45
45
|
auto audioContext = std::static_pointer_cast<AudioContext>(context_);
|
|
46
46
|
auto result = audioContext->resume();
|
|
47
47
|
|
|
48
|
+
if (!result) {
|
|
49
|
+
promise->reject("Failed to resume audio context because it is already closed.");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
promise->resolve([result](jsi::Runtime &runtime) {
|
|
49
54
|
return jsi::Value(result);
|
|
50
55
|
});
|
|
@@ -60,6 +65,11 @@ class AudioContextHostObject : public BaseAudioContextHostObject {
|
|
|
60
65
|
auto audioContext = std::static_pointer_cast<AudioContext>(context_);
|
|
61
66
|
auto result = audioContext->suspend();
|
|
62
67
|
|
|
68
|
+
if (!result) {
|
|
69
|
+
promise->reject("Failed to suspend audio context because it is already closed.");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
63
73
|
promise->resolve([result](jsi::Runtime &runtime) {
|
|
64
74
|
return jsi::Value(result);
|
|
65
75
|
});
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
namespace audioapi {
|
|
13
13
|
AudioContext::AudioContext(
|
|
14
14
|
float sampleRate,
|
|
15
|
+
bool initSuspended,
|
|
15
16
|
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
|
|
16
17
|
: BaseAudioContext(audioEventHandlerRegistry) {
|
|
17
18
|
#ifdef ANDROID
|
|
@@ -24,8 +25,16 @@ AudioContext::AudioContext(
|
|
|
24
25
|
sampleRate_ = sampleRate;
|
|
25
26
|
audioDecoder_ = std::make_shared<AudioDecoder>(sampleRate);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
if (initSuspended) {
|
|
29
|
+
playerHasBeenStarted_ = false;
|
|
30
|
+
state_ = ContextState::SUSPENDED;
|
|
31
|
+
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
playerHasBeenStarted_ = true;
|
|
28
36
|
audioPlayer_->start();
|
|
37
|
+
state_ = ContextState::RUNNING;
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
AudioContext::~AudioContext() {
|
|
@@ -37,27 +46,43 @@ AudioContext::~AudioContext() {
|
|
|
37
46
|
void AudioContext::close() {
|
|
38
47
|
state_ = ContextState::CLOSED;
|
|
39
48
|
|
|
49
|
+
audioPlayer_->stop();
|
|
40
50
|
audioPlayer_->cleanup();
|
|
41
51
|
nodeManager_->cleanup();
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
bool AudioContext::resume() {
|
|
45
|
-
if (isClosed()
|
|
55
|
+
if (isClosed()) {
|
|
46
56
|
return false;
|
|
47
57
|
}
|
|
48
58
|
|
|
59
|
+
if (isRunning()) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!playerHasBeenStarted_) {
|
|
64
|
+
playerHasBeenStarted_ = true;
|
|
65
|
+
audioPlayer_->start();
|
|
66
|
+
} else {
|
|
67
|
+
audioPlayer_->resume();
|
|
68
|
+
}
|
|
69
|
+
|
|
49
70
|
state_ = ContextState::RUNNING;
|
|
50
|
-
audioPlayer_->start();
|
|
51
71
|
return true;
|
|
52
72
|
}
|
|
53
73
|
|
|
54
74
|
bool AudioContext::suspend() {
|
|
55
|
-
if (isClosed()
|
|
75
|
+
if (isClosed()) {
|
|
56
76
|
return false;
|
|
57
77
|
}
|
|
58
78
|
|
|
79
|
+
if (isSuspended()) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
audioPlayer_->suspend();
|
|
84
|
+
|
|
59
85
|
state_ = ContextState::SUSPENDED;
|
|
60
|
-
audioPlayer_->stop();
|
|
61
86
|
return true;
|
|
62
87
|
}
|
|
63
88
|
|
|
@@ -14,7 +14,7 @@ class IOSAudioPlayer;
|
|
|
14
14
|
|
|
15
15
|
class AudioContext : public BaseAudioContext {
|
|
16
16
|
public:
|
|
17
|
-
explicit AudioContext(float sampleRate, const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
17
|
+
explicit AudioContext(float sampleRate, bool initSuspended, const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
18
18
|
~AudioContext() override;
|
|
19
19
|
|
|
20
20
|
void close();
|
|
@@ -27,6 +27,7 @@ class AudioContext : public BaseAudioContext {
|
|
|
27
27
|
#else
|
|
28
28
|
std::shared_ptr<IOSAudioPlayer> audioPlayer_;
|
|
29
29
|
#endif
|
|
30
|
+
bool playerHasBeenStarted_;
|
|
30
31
|
|
|
31
32
|
std::function<void(std::shared_ptr<AudioBus>, int)> renderAudio();
|
|
32
33
|
};
|
|
@@ -17,10 +17,11 @@ AudioParam::AudioParam(
|
|
|
17
17
|
minValue_(minValue),
|
|
18
18
|
maxValue_(maxValue),
|
|
19
19
|
context_(context),
|
|
20
|
-
audioBus_(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
audioBus_(
|
|
21
|
+
std::make_shared<AudioBus>(
|
|
22
|
+
RENDER_QUANTUM_SIZE,
|
|
23
|
+
1,
|
|
24
|
+
context->getSampleRate())) {
|
|
24
25
|
startTime_ = 0;
|
|
25
26
|
endTime_ = 0;
|
|
26
27
|
startValue_ = value_;
|
|
@@ -152,7 +152,11 @@ void AudioBufferQueueSourceNode::processWithPitchCorrection(
|
|
|
152
152
|
|
|
153
153
|
playbackRateBus_->zero();
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
auto framesNeededToStretch =
|
|
156
|
+
static_cast<int>(playbackRate * static_cast<float>(framesToProcess));
|
|
157
|
+
|
|
158
|
+
updatePlaybackInfo(
|
|
159
|
+
playbackRateBus_, framesNeededToStretch, startOffset, offsetLength);
|
|
156
160
|
|
|
157
161
|
if (playbackRate == 0.0f || (!isPlaying() && !isStopScheduled())) {
|
|
158
162
|
processingBus->zero();
|
|
@@ -162,15 +166,7 @@ void AudioBufferQueueSourceNode::processWithPitchCorrection(
|
|
|
162
166
|
// Send position changed event
|
|
163
167
|
sendOnPositionChangedEvent();
|
|
164
168
|
|
|
165
|
-
|
|
166
|
-
static_cast<int>(playbackRate * static_cast<float>(framesToProcess));
|
|
167
|
-
auto stretchedStartOffset =
|
|
168
|
-
static_cast<size_t>(static_cast<float>(startOffset) * playbackRate);
|
|
169
|
-
auto stretchedOffsetLength =
|
|
170
|
-
static_cast<size_t>(static_cast<float>(offsetLength) * playbackRate);
|
|
171
|
-
|
|
172
|
-
processWithoutInterpolation(
|
|
173
|
-
playbackRateBus_, stretchedStartOffset, stretchedOffsetLength);
|
|
169
|
+
processWithoutInterpolation(playbackRateBus_, startOffset, offsetLength);
|
|
174
170
|
|
|
175
171
|
stretch_->process(
|
|
176
172
|
playbackRateBus_.get()[0],
|
|
@@ -100,7 +100,7 @@ void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
|
100
100
|
assert(nonSilentFramesToProcess <= framesToProcess);
|
|
101
101
|
|
|
102
102
|
// stop will happen in the same render quantum
|
|
103
|
-
if (stopFrame
|
|
103
|
+
if (stopFrame <= lastFrame && stopFrame >= firstFrame) {
|
|
104
104
|
playbackState_ = PlaybackState::STOP_SCHEDULED;
|
|
105
105
|
processingBus->zero(stopFrame - firstFrame, lastFrame - stopFrame);
|
|
106
106
|
}
|
|
@@ -85,8 +85,9 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getDevicePreferredSampleRate)
|
|
|
85
85
|
return [self.audioSessionManager getDevicePreferredSampleRate];
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
RCT_EXPORT_METHOD(
|
|
89
|
-
|
|
88
|
+
RCT_EXPORT_METHOD(
|
|
89
|
+
setAudioSessionActivity : (BOOL)enabled resolve : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)
|
|
90
|
+
reject)
|
|
90
91
|
{
|
|
91
92
|
if ([self.audioSessionManager setActive:enabled]) {
|
|
92
93
|
resolve(@"true");
|
|
@@ -126,18 +127,17 @@ RCT_EXPORT_METHOD(observeVolumeChanges : (BOOL)enabled)
|
|
|
126
127
|
[self.notificationManager observeVolumeChanges:(BOOL)enabled];
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
RCT_EXPORT_METHOD(
|
|
130
|
-
|
|
130
|
+
RCT_EXPORT_METHOD(
|
|
131
|
+
requestRecordingPermissions : (nonnull RCTPromiseResolveBlock)resolve reject : (nonnull RCTPromiseRejectBlock)
|
|
132
|
+
reject)
|
|
131
133
|
{
|
|
132
|
-
|
|
133
|
-
resolve(res);
|
|
134
|
+
[self.audioSessionManager requestRecordingPermissions:resolve reject:reject];
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
RCT_EXPORT_METHOD(
|
|
137
|
-
|
|
137
|
+
RCT_EXPORT_METHOD(
|
|
138
|
+
checkRecordingPermissions : (nonnull RCTPromiseResolveBlock)resolve reject : (nonnull RCTPromiseRejectBlock)reject)
|
|
138
139
|
{
|
|
139
|
-
|
|
140
|
-
resolve(res);
|
|
140
|
+
[self.audioSessionManager checkRecordingPermissions:resolve reject:reject];
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
@@ -169,7 +169,7 @@ RCT_EXPORT_METHOD(checkRecordingPermissions : (nonnull RCTPromiseResolveBlock)
|
|
|
169
169
|
body[stdKey] = EventValue([value doubleValue]);
|
|
170
170
|
} else if (strcmp(type, @encode(float)) == 0) {
|
|
171
171
|
body[stdKey] = EventValue([value floatValue]);
|
|
172
|
-
} else
|
|
172
|
+
} else {
|
|
173
173
|
body[stdKey] = EventValue([value boolValue]);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -62,6 +62,22 @@ void IOSAudioPlayer::stop()
|
|
|
62
62
|
[audioPlayer_ stop];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
void IOSAudioPlayer::resume()
|
|
66
|
+
{
|
|
67
|
+
if (isRunning_.load()) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[audioPlayer_ resume];
|
|
72
|
+
isRunning_.store(true);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void IOSAudioPlayer::suspend()
|
|
76
|
+
{
|
|
77
|
+
isRunning_.store(false);
|
|
78
|
+
[audioPlayer_ suspend];
|
|
79
|
+
}
|
|
80
|
+
|
|
65
81
|
void IOSAudioPlayer::cleanup()
|
|
66
82
|
{
|
|
67
83
|
stop();
|
|
@@ -51,6 +51,21 @@
|
|
|
51
51
|
self.sourceNodeId = nil;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
- (void)resume
|
|
55
|
+
{
|
|
56
|
+
NSLog(@"[AudioPlayer] resume");
|
|
57
|
+
AudioEngine *audioEngine = [AudioEngine sharedInstance];
|
|
58
|
+
assert(audioEngine != nil);
|
|
59
|
+
[audioEngine startEngine];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (void)suspend
|
|
63
|
+
{
|
|
64
|
+
AudioEngine *audioEngine = [AudioEngine sharedInstance];
|
|
65
|
+
assert(audioEngine != nil);
|
|
66
|
+
[audioEngine pauseEngine:self.sourceNodeId];
|
|
67
|
+
}
|
|
68
|
+
|
|
54
69
|
- (void)cleanup
|
|
55
70
|
{
|
|
56
71
|
self.renderAudio = nil;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
@property (nonatomic, strong) AVAudioEngine *audioEngine;
|
|
11
11
|
@property (nonatomic, strong) NSMutableDictionary *sourceNodes;
|
|
12
12
|
@property (nonatomic, strong) NSMutableDictionary *sourceFormats;
|
|
13
|
+
@property (nonatomic, strong) NSMutableDictionary *sourceStates;
|
|
13
14
|
@property (nonatomic, strong) AVAudioSinkNode *inputNode;
|
|
14
15
|
@property (nonatomic, weak) AudioSessionManager *sessionManager;
|
|
15
16
|
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
- (bool)rebuildAudioEngine;
|
|
21
22
|
- (void)startEngine;
|
|
22
23
|
- (void)stopEngine;
|
|
24
|
+
- (void)pauseEngine:(NSString *)sourceNodeId;
|
|
23
25
|
- (bool)isRunning;
|
|
24
26
|
|
|
25
27
|
- (NSString *)attachSourceNode:(AVAudioSourceNode *)sourceNode format:(AVAudioFormat *)format;
|
|
@@ -28,7 +30,4 @@
|
|
|
28
30
|
- (void)attachInputNode:(AVAudioSinkNode *)inputNode;
|
|
29
31
|
- (void)detachInputNode;
|
|
30
32
|
|
|
31
|
-
- (void)startIfNecessary;
|
|
32
|
-
- (void)stopIfNecessary;
|
|
33
|
-
|
|
34
33
|
@end
|
|
@@ -18,9 +18,9 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
18
18
|
|
|
19
19
|
self.sourceNodes = [[NSMutableDictionary alloc] init];
|
|
20
20
|
self.sourceFormats = [[NSMutableDictionary alloc] init];
|
|
21
|
+
self.sourceStates = [[NSMutableDictionary alloc] init];
|
|
21
22
|
|
|
22
23
|
self.sessionManager = sessionManager;
|
|
23
|
-
[self.sessionManager setActive:true];
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
_sharedInstance = self;
|
|
@@ -38,6 +38,7 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
38
38
|
self.audioEngine = nil;
|
|
39
39
|
self.sourceNodes = nil;
|
|
40
40
|
self.sourceFormats = nil;
|
|
41
|
+
self.sourceStates = nil;
|
|
41
42
|
self.inputNode = nil;
|
|
42
43
|
|
|
43
44
|
[self.sessionManager setActive:false];
|
|
@@ -75,6 +76,7 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
75
76
|
return;
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
[self.sessionManager setActive:true];
|
|
78
80
|
[self.audioEngine startAndReturnError:&error];
|
|
79
81
|
|
|
80
82
|
if (error != nil) {
|
|
@@ -92,6 +94,16 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
92
94
|
[self.audioEngine stop];
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
- (void)pauseEngine:(NSString *)sourceNodeId
|
|
98
|
+
{
|
|
99
|
+
if (![self.audioEngine isRunning]) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
[self.sourceStates setValue:@false forKey:sourceNodeId];
|
|
104
|
+
[self pauseIfNecessary];
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
- (bool)isRunning
|
|
96
108
|
{
|
|
97
109
|
return [self.audioEngine isRunning];
|
|
@@ -104,6 +116,7 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
104
116
|
|
|
105
117
|
[self.sourceNodes setValue:sourceNode forKey:sourceNodeId];
|
|
106
118
|
[self.sourceFormats setValue:format forKey:sourceNodeId];
|
|
119
|
+
[self.sourceStates setValue:@true forKey:sourceNodeId];
|
|
107
120
|
|
|
108
121
|
[self.audioEngine attachNode:sourceNode];
|
|
109
122
|
[self.audioEngine connect:sourceNode to:self.audioEngine.mainMixerNode format:format];
|
|
@@ -123,6 +136,7 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
123
136
|
|
|
124
137
|
[self.sourceNodes removeObjectForKey:sourceNodeId];
|
|
125
138
|
[self.sourceFormats removeObjectForKey:sourceNodeId];
|
|
139
|
+
[self.sourceStates removeObjectForKey:sourceNodeId];
|
|
126
140
|
}
|
|
127
141
|
|
|
128
142
|
[self stopIfNecessary];
|
|
@@ -170,4 +184,21 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
170
184
|
}
|
|
171
185
|
}
|
|
172
186
|
|
|
187
|
+
- (void)pauseIfNecessary
|
|
188
|
+
{
|
|
189
|
+
if (![self isRunning]) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
for (NSString *sourceId in self.sourceStates) {
|
|
194
|
+
if ([self.sourceStates[sourceId] boolValue]) {
|
|
195
|
+
NSLog(@"state %c", self.sourceStates[sourceId]);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
NSLog(@"[AudioEngine] pauseEngine");
|
|
201
|
+
[self.audioEngine pause];
|
|
202
|
+
}
|
|
203
|
+
|
|
173
204
|
@end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#import <AVFoundation/AVFoundation.h>
|
|
4
4
|
#import <Foundation/Foundation.h>
|
|
5
|
+
#import <React/RCTBridgeModule.h>
|
|
5
6
|
|
|
6
7
|
@interface AudioSessionManager : NSObject
|
|
7
8
|
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
- (NSNumber *)getDevicePreferredSampleRate;
|
|
21
22
|
- (void)setAudioSessionOptions:(NSString *)category mode:(NSString *)mode options:(NSArray *)options;
|
|
22
23
|
- (bool)setActive:(bool)active;
|
|
23
|
-
- (
|
|
24
|
-
- (
|
|
24
|
+
- (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
|
|
25
|
+
- (void)checkRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
|
|
25
26
|
|
|
26
27
|
@end
|
|
@@ -175,11 +175,62 @@
|
|
|
175
175
|
return true;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
- (
|
|
178
|
+
- (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject
|
|
179
179
|
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
if (@available(iOS 17, *)) {
|
|
181
|
+
[AVAudioSession.sharedInstance requestRecordPermission:^(BOOL granted) {
|
|
182
|
+
if (granted) {
|
|
183
|
+
resolve(@"Granted");
|
|
184
|
+
} else {
|
|
185
|
+
resolve(@"Denied");
|
|
186
|
+
}
|
|
187
|
+
}];
|
|
188
|
+
} else {
|
|
189
|
+
[self.audioSession requestRecordPermission:^(BOOL granted) {
|
|
190
|
+
if (granted) {
|
|
191
|
+
resolve(@"Granted");
|
|
192
|
+
} else {
|
|
193
|
+
resolve(@"Denied");
|
|
194
|
+
}
|
|
195
|
+
}];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
- (void)checkRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject
|
|
200
|
+
{
|
|
201
|
+
if (@available(iOS 17, *)) {
|
|
202
|
+
NSInteger res = [[AVAudioApplication sharedInstance] recordPermission];
|
|
203
|
+
switch (res) {
|
|
204
|
+
case AVAudioApplicationRecordPermissionUndetermined:
|
|
205
|
+
resolve(@"Undetermined");
|
|
206
|
+
break;
|
|
207
|
+
case AVAudioApplicationRecordPermissionGranted:
|
|
208
|
+
resolve(@"Granted");
|
|
209
|
+
break;
|
|
210
|
+
case AVAudioApplicationRecordPermissionDenied:
|
|
211
|
+
resolve(@"Denied");
|
|
212
|
+
break;
|
|
213
|
+
default:
|
|
214
|
+
resolve(@"Undetermined");
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
NSInteger res = [self.audioSession recordPermission];
|
|
219
|
+
switch (res) {
|
|
220
|
+
case AVAudioSessionRecordPermissionUndetermined:
|
|
221
|
+
resolve(@"Undetermined");
|
|
222
|
+
break;
|
|
223
|
+
case AVAudioSessionRecordPermissionGranted:
|
|
224
|
+
resolve(@"Granted");
|
|
225
|
+
break;
|
|
226
|
+
case AVAudioSessionRecordPermissionDenied:
|
|
227
|
+
resolve(@"Denied");
|
|
228
|
+
break;
|
|
229
|
+
default:
|
|
230
|
+
resolve(@"Undetermined");
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
183
234
|
}
|
|
184
235
|
|
|
185
236
|
- (NSString *)checkRecordingPermissions
|
package/lib/commonjs/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_specs","require","_AudioBuffer","_interopRequireDefault","_AudioBufferSourceNode","_AudioBufferQueueSourceNode","_AudioContext","_OfflineAudioContext","_AudioDestinationNode","_AudioNode","_AnalyserNode","_AudioParam","_AudioScheduledSourceNode","_BaseAudioContext","_BiquadFilterNode","_GainNode","_OscillatorNode","_StereoPannerNode","_AudioRecorder","_system","_useSytemVolume","_types","_errors","e","__esModule","default","global","createAudioContext","createOfflineAudioContext","createAudioRecorder","AudioEventEmitter","NativeAudioAPIModule","Error","install"],"sourceRoot":"../../src","sources":["api.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;
|
|
1
|
+
{"version":3,"names":["_specs","require","_AudioBuffer","_interopRequireDefault","_AudioBufferSourceNode","_AudioBufferQueueSourceNode","_AudioContext","_OfflineAudioContext","_AudioDestinationNode","_AudioNode","_AnalyserNode","_AudioParam","_AudioScheduledSourceNode","_BaseAudioContext","_BiquadFilterNode","_GainNode","_OscillatorNode","_StereoPannerNode","_AudioRecorder","_system","_useSytemVolume","_types","_errors","e","__esModule","default","global","createAudioContext","createOfflineAudioContext","createAudioRecorder","AudioEventEmitter","NativeAudioAPIModule","Error","install"],"sourceRoot":"../../src","sources":["api.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AA0CA,IAAAC,YAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,sBAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,2BAAA,GAAAF,sBAAA,CAAAF,OAAA;AACA,IAAAK,aAAA,GAAAH,sBAAA,CAAAF,OAAA;AACA,IAAAM,oBAAA,GAAAJ,sBAAA,CAAAF,OAAA;AACA,IAAAO,qBAAA,GAAAL,sBAAA,CAAAF,OAAA;AACA,IAAAQ,UAAA,GAAAN,sBAAA,CAAAF,OAAA;AACA,IAAAS,aAAA,GAAAP,sBAAA,CAAAF,OAAA;AACA,IAAAU,WAAA,GAAAR,sBAAA,CAAAF,OAAA;AACA,IAAAW,yBAAA,GAAAT,sBAAA,CAAAF,OAAA;AACA,IAAAY,iBAAA,GAAAV,sBAAA,CAAAF,OAAA;AACA,IAAAa,iBAAA,GAAAX,sBAAA,CAAAF,OAAA;AACA,IAAAc,SAAA,GAAAZ,sBAAA,CAAAF,OAAA;AACA,IAAAe,eAAA,GAAAb,sBAAA,CAAAF,OAAA;AACA,IAAAgB,iBAAA,GAAAd,sBAAA,CAAAF,OAAA;AACA,IAAAiB,cAAA,GAAAf,sBAAA,CAAAF,OAAA;AACA,IAAAkB,OAAA,GAAAhB,sBAAA,CAAAF,OAAA;AACA,IAAAmB,eAAA,GAAAjB,sBAAA,CAAAF,OAAA;AAEA,IAAAoB,MAAA,GAAApB,OAAA;AAUA,IAAAqB,OAAA,GAAArB,OAAA;AAMkB,SAAAE,uBAAAoB,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AApElB;;AAgBA;;AAEA,IACEG,MAAM,CAACC,kBAAkB,IAAI,IAAI,IACjCD,MAAM,CAACE,yBAAyB,IAAI,IAAI,IACxCF,MAAM,CAACG,mBAAmB,IAAI,IAAI,IAClCH,MAAM,CAACI,iBAAiB,IAAI,IAAI,EAChC;EACA,IAAI,CAACC,2BAAoB,EAAE;IACzB,MAAM,IAAIC,KAAK,CACb,iFACF,CAAC;EACH;EAEAD,2BAAoB,CAACE,OAAO,CAAC,CAAC;AAChC","ignoreList":[]}
|
|
@@ -10,10 +10,10 @@ var _errors = require("../errors");
|
|
|
10
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
11
|
class AudioContext extends _BaseAudioContext.default {
|
|
12
12
|
constructor(options) {
|
|
13
|
-
if (options && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
13
|
+
if (options && options.sampleRate && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
14
14
|
throw new _errors.NotSupportedError(`The provided sampleRate is not supported: ${options.sampleRate}`);
|
|
15
15
|
}
|
|
16
|
-
super(global.createAudioContext(options?.sampleRate || _system.default.getDevicePreferredSampleRate()));
|
|
16
|
+
super(global.createAudioContext(options?.sampleRate || _system.default.getDevicePreferredSampleRate(), options?.initSuspended || false));
|
|
17
17
|
}
|
|
18
18
|
async close() {
|
|
19
19
|
await this.context.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_BaseAudioContext","_interopRequireDefault","require","_system","_errors","e","__esModule","default","AudioContext","BaseAudioContext","constructor","options","sampleRate","NotSupportedError","global","createAudioContext","AudioManager","getDevicePreferredSampleRate","close","context","resume","suspend","exports"],"sourceRoot":"../../../src","sources":["core/AudioContext.ts"],"mappings":";;;;;;AACA,IAAAA,iBAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,OAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEA,IAAAE,OAAA,GAAAF,OAAA;AAA8C,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE/B,MAAMG,YAAY,SAASC,yBAAgB,CAAC;EACzDC,WAAWA,CAACC,OAA6B,EAAE;IACzC,
|
|
1
|
+
{"version":3,"names":["_BaseAudioContext","_interopRequireDefault","require","_system","_errors","e","__esModule","default","AudioContext","BaseAudioContext","constructor","options","sampleRate","NotSupportedError","global","createAudioContext","AudioManager","getDevicePreferredSampleRate","initSuspended","close","context","resume","suspend","exports"],"sourceRoot":"../../../src","sources":["core/AudioContext.ts"],"mappings":";;;;;;AACA,IAAAA,iBAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,OAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEA,IAAAE,OAAA,GAAAF,OAAA;AAA8C,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE/B,MAAMG,YAAY,SAASC,yBAAgB,CAAC;EACzDC,WAAWA,CAACC,OAA6B,EAAE;IACzC,IACEA,OAAO,IACPA,OAAO,CAACC,UAAU,KACjBD,OAAO,CAACC,UAAU,GAAG,IAAI,IAAID,OAAO,CAACC,UAAU,GAAG,KAAK,CAAC,EACzD;MACA,MAAM,IAAIC,yBAAiB,CACzB,6CAA6CF,OAAO,CAACC,UAAU,EACjE,CAAC;IACH;IAEA,KAAK,CACHE,MAAM,CAACC,kBAAkB,CACvBJ,OAAO,EAAEC,UAAU,IAAII,eAAY,CAACC,4BAA4B,CAAC,CAAC,EAClEN,OAAO,EAAEO,aAAa,IAAI,KAC5B,CACF,CAAC;EACH;EAEA,MAAMC,KAAKA,CAAA,EAAuB;IAChC,MAAO,IAAI,CAACC,OAAO,CAAmBD,KAAK,CAAC,CAAC;EAC/C;EAEA,MAAME,MAAMA,CAAA,EAAuB;IACjC,MAAO,IAAI,CAACD,OAAO,CAAmBC,MAAM,CAAC,CAAC;EAChD;EAEA,MAAMC,OAAOA,CAAA,EAAuB;IAClC,MAAO,IAAI,CAACF,OAAO,CAAmBE,OAAO,CAAC,CAAC;EACjD;AACF;AAACC,OAAA,CAAAhB,OAAA,GAAAC,YAAA","ignoreList":[]}
|
|
@@ -9,8 +9,8 @@ const pkg = require('react-native-audio-api/package.json');
|
|
|
9
9
|
const withDefaultOptions = options => {
|
|
10
10
|
return {
|
|
11
11
|
iosBackgroundMode: true,
|
|
12
|
+
androidPermissions: ['android.permission.FOREGROUND_SERVICE', 'android.permission.WAKE_LOCK'],
|
|
12
13
|
androidForegroundService: true,
|
|
13
|
-
androidFSPermissions: ['android.permission.FOREGROUND_SERVICE', 'android.permission.WAKE_LOCK'],
|
|
14
14
|
androidFSTypes: ['mediaPlayback'],
|
|
15
15
|
...options
|
|
16
16
|
};
|
|
@@ -22,9 +22,9 @@ const withBackgroundAudio = config => {
|
|
|
22
22
|
});
|
|
23
23
|
};
|
|
24
24
|
const withAndroidPermissions = (config, {
|
|
25
|
-
|
|
25
|
+
androidPermissions
|
|
26
26
|
}) => {
|
|
27
|
-
return _configPlugins.AndroidConfig.Permissions.withPermissions(config,
|
|
27
|
+
return _configPlugins.AndroidConfig.Permissions.withPermissions(config, androidPermissions);
|
|
28
28
|
};
|
|
29
29
|
const withForegroundService = (config, {
|
|
30
30
|
androidFSTypes
|
|
@@ -53,8 +53,8 @@ const withAudioAPI = (config, optionsIn) => {
|
|
|
53
53
|
if (options.iosBackgroundMode) {
|
|
54
54
|
config = withBackgroundAudio(config);
|
|
55
55
|
}
|
|
56
|
+
config = withAndroidPermissions(config, options);
|
|
56
57
|
if (options.androidForegroundService) {
|
|
57
|
-
config = withAndroidPermissions(config, options);
|
|
58
58
|
config = withForegroundService(config, options);
|
|
59
59
|
}
|
|
60
60
|
return config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_configPlugins","require","pkg","withDefaultOptions","options","iosBackgroundMode","
|
|
1
|
+
{"version":3,"names":["_configPlugins","require","pkg","withDefaultOptions","options","iosBackgroundMode","androidPermissions","androidForegroundService","androidFSTypes","withBackgroundAudio","config","withInfoPlist","iosConfig","modResults","UIBackgroundModes","Array","from","Set","withAndroidPermissions","AndroidConfig","Permissions","withPermissions","withForegroundService","withAndroidManifest","mod","manifest","mainApplication","Manifest","getMainApplicationOrThrow","SFTypes","join","serviceElement","$","intentFilter","service","push","withAudioAPI","optionsIn","_default","exports","default","createRunOncePlugin","name","version"],"sourceRoot":"../../../src","sources":["plugin/withAudioAPI.ts"],"mappings":";;;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AAOA,MAAMC,GAAG,GAAGD,OAAO,CAAC,qCAAqC,CAAC;AAS1D,MAAME,kBAAkB,GAAIC,OAAyB,IAAc;EACjE,OAAO;IACLC,iBAAiB,EAAE,IAAI;IACvBC,kBAAkB,EAAE,CAClB,uCAAuC,EACvC,8BAA8B,CAC/B;IACDC,wBAAwB,EAAE,IAAI;IAC9BC,cAAc,EAAE,CAAC,eAAe,CAAC;IACjC,GAAGJ;EACL,CAAC;AACH,CAAC;AAED,MAAMK,mBAAiC,GAAIC,MAAM,IAAK;EACpD,OAAO,IAAAC,4BAAa,EAACD,MAAM,EAAGE,SAAS,IAAK;IAC1CA,SAAS,CAACC,UAAU,CAACC,iBAAiB,GAAG,CACvC,GAAGC,KAAK,CAACC,IAAI,CACX,IAAIC,GAAG,CAAC,CAAC,IAAIL,SAAS,CAACC,UAAU,CAACC,iBAAiB,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CACtE,CAAC,CACF;IAED,OAAOF,SAAS;EAClB,CAAC,CAAC;AACJ,CAAC;AAED,MAAMM,sBAA6C,GAAGA,CACpDR,MAAM,EACN;EAAEJ;AAA4B,CAAC,KAC5B;EACH,OAAOa,4BAAa,CAACC,WAAW,CAACC,eAAe,CAACX,MAAM,EAAEJ,kBAAkB,CAAC;AAC9E,CAAC;AAED,MAAMgB,qBAA4C,GAAGA,CACnDZ,MAAM,EACN;EAAEF;AAAwB,CAAC,KACxB;EACH,OAAO,IAAAe,kCAAmB,EAACb,MAAM,EAAGc,GAAG,IAAK;IAC1C,MAAMC,QAAQ,GAAGD,GAAG,CAACX,UAAU;IAC/B,MAAMa,eAAe,GACnBP,4BAAa,CAACQ,QAAQ,CAACC,yBAAyB,CAACH,QAAQ,CAAC;IAE5D,MAAMI,OAAO,GAAGrB,cAAc,CAACsB,IAAI,CAAC,GAAG,CAAC;IAExC,MAAMC,cAAc,GAAG;MACrBC,CAAC,EAAE;QACD,cAAc,EACZ,4EAA4E;QAC9E,sBAAsB,EAAE,MAAM;QAC9B,+BAA+B,EAAEH;MACnC,CAAC;MACDI,YAAY,EAAE;IAChB,CAAC;IAED,IAAI,CAACP,eAAe,CAACQ,OAAO,EAAE;MAC5BR,eAAe,CAACQ,OAAO,GAAG,EAAE;IAC9B;IAEAR,eAAe,CAACQ,OAAO,CAACC,IAAI,CAACJ,cAAc,CAAC;IAE5C,OAAOP,GAAG;EACZ,CAAC,CAAC;AACJ,CAAC;AAED,MAAMY,YAAmC,GAAGA,CAAC1B,MAAM,EAAE2B,SAAS,KAAK;EACjE,MAAMjC,OAAO,GAAGD,kBAAkB,CAACkC,SAAS,IAAI,CAAC,CAAC,CAAC;EAEnD,IAAIjC,OAAO,CAACC,iBAAiB,EAAE;IAC7BK,MAAM,GAAGD,mBAAmB,CAACC,MAAM,CAAC;EACtC;EAEAA,MAAM,GAAGQ,sBAAsB,CAACR,MAAM,EAAEN,OAAO,CAAC;EAEhD,IAAIA,OAAO,CAACG,wBAAwB,EAAE;IACpCG,MAAM,GAAGY,qBAAqB,CAACZ,MAAM,EAAEN,OAAO,CAAC;EACjD;EAEA,OAAOM,MAAM;AACf,CAAC;AAAC,IAAA4B,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEa,IAAAC,kCAAmB,EAACL,YAAY,EAAElC,GAAG,CAACwC,IAAI,EAAExC,GAAG,CAACyC,OAAO,CAAC","ignoreList":[]}
|
|
@@ -17,11 +17,13 @@ var _StereoPannerNode = _interopRequireDefault(require("./StereoPannerNode"));
|
|
|
17
17
|
var _LoadCustomWasm = require("./custom/LoadCustomWasm");
|
|
18
18
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
19
|
class AudioContext {
|
|
20
|
-
constructor(options) {
|
|
21
|
-
if (options && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
20
|
+
constructor(options, _initSuspended = false) {
|
|
21
|
+
if (options && options.sampleRate && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
22
22
|
throw new _errors.NotSupportedError(`The provided sampleRate is not supported: ${options.sampleRate}`);
|
|
23
23
|
}
|
|
24
|
-
this.context = new window.AudioContext(
|
|
24
|
+
this.context = new window.AudioContext({
|
|
25
|
+
sampleRate: options?.sampleRate
|
|
26
|
+
});
|
|
25
27
|
this.sampleRate = this.context.sampleRate;
|
|
26
28
|
this.destination = new _AudioDestinationNode.default(this, this.context.destination);
|
|
27
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_errors","require","_AnalyserNode","_interopRequireDefault","_AudioDestinationNode","_AudioBuffer","_AudioBufferSourceNode","_BiquadFilterNode","_GainNode","_OscillatorNode","_PeriodicWave","_StereoPannerNode","_LoadCustomWasm","e","__esModule","default","AudioContext","constructor","options","sampleRate","NotSupportedError","context","window","destination","AudioDestinationNode","currentTime","state","createOscillator","OscillatorNode","createGain","GainNode","createStereoPanner","StereoPannerNode","createBiquadFilter","BiquadFilterNode","createBufferSource","pitchCorrection","AudioBufferSourceNode","globalWasmPromise","wasmStretch","globalTag","createBuffer","numOfChannels","length","AudioBuffer","createPeriodicWave","real","imag","constraints","InvalidAccessError","PeriodicWave","createAnalyser","AnalyserNode","decodeAudioDataSource","source","arrayBuffer","fetch","then","response","decodeAudioData","close","resume","suspend","exports"],"sourceRoot":"../../../src","sources":["web-core/AudioContext.tsx"],"mappings":";;;;;;AAMA,IAAAA,OAAA,GAAAC,OAAA;AAEA,IAAAC,aAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,qBAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,YAAA,GAAAF,sBAAA,CAAAF,OAAA;AACA,IAAAK,sBAAA,GAAAH,sBAAA,CAAAF,OAAA;AACA,IAAAM,iBAAA,GAAAJ,sBAAA,CAAAF,OAAA;AACA,IAAAO,SAAA,GAAAL,sBAAA,CAAAF,OAAA;AACA,IAAAQ,eAAA,GAAAN,sBAAA,CAAAF,OAAA;AACA,IAAAS,aAAA,GAAAP,sBAAA,CAAAF,OAAA;AACA,IAAAU,iBAAA,GAAAR,sBAAA,CAAAF,OAAA;AAEA,IAAAW,eAAA,GAAAX,OAAA;AAAuE,SAAAE,uBAAAU,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAExD,MAAMG,YAAY,CAA6B;EAM5DC,WAAWA,CAACC,OAA6B,EAAE;
|
|
1
|
+
{"version":3,"names":["_errors","require","_AnalyserNode","_interopRequireDefault","_AudioDestinationNode","_AudioBuffer","_AudioBufferSourceNode","_BiquadFilterNode","_GainNode","_OscillatorNode","_PeriodicWave","_StereoPannerNode","_LoadCustomWasm","e","__esModule","default","AudioContext","constructor","options","_initSuspended","sampleRate","NotSupportedError","context","window","destination","AudioDestinationNode","currentTime","state","createOscillator","OscillatorNode","createGain","GainNode","createStereoPanner","StereoPannerNode","createBiquadFilter","BiquadFilterNode","createBufferSource","pitchCorrection","AudioBufferSourceNode","globalWasmPromise","wasmStretch","globalTag","createBuffer","numOfChannels","length","AudioBuffer","createPeriodicWave","real","imag","constraints","InvalidAccessError","PeriodicWave","createAnalyser","AnalyserNode","decodeAudioDataSource","source","arrayBuffer","fetch","then","response","decodeAudioData","close","resume","suspend","exports"],"sourceRoot":"../../../src","sources":["web-core/AudioContext.tsx"],"mappings":"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","ignoreList":[]}
|
package/lib/module/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeAudioAPIModule","global","createAudioContext","createOfflineAudioContext","createAudioRecorder","AudioEventEmitter","Error","install","default","AudioBuffer","AudioBufferSourceNode","AudioBufferQueueSourceNode","AudioContext","OfflineAudioContext","AudioDestinationNode","AudioNode","AnalyserNode","AudioParam","AudioScheduledSourceNode","BaseAudioContext","BiquadFilterNode","GainNode","OscillatorNode","StereoPannerNode","AudioRecorder","AudioManager","useSystemVolume","OscillatorType","BiquadFilterType","ChannelCountMode","ChannelInterpretation","ContextState","WindowType","PeriodicWaveConstraints","IndexSizeError","InvalidAccessError","InvalidStateError","RangeError","NotSupportedError"],"sourceRoot":"../../src","sources":["api.ts"],"mappings":";;AAAA,SAASA,oBAAoB,QAAQ,kBAAS;;AAS9C;;
|
|
1
|
+
{"version":3,"names":["NativeAudioAPIModule","global","createAudioContext","createOfflineAudioContext","createAudioRecorder","AudioEventEmitter","Error","install","default","AudioBuffer","AudioBufferSourceNode","AudioBufferQueueSourceNode","AudioContext","OfflineAudioContext","AudioDestinationNode","AudioNode","AnalyserNode","AudioParam","AudioScheduledSourceNode","BaseAudioContext","BiquadFilterNode","GainNode","OscillatorNode","StereoPannerNode","AudioRecorder","AudioManager","useSystemVolume","OscillatorType","BiquadFilterType","ChannelCountMode","ChannelInterpretation","ContextState","WindowType","PeriodicWaveConstraints","IndexSizeError","InvalidAccessError","InvalidStateError","RangeError","NotSupportedError"],"sourceRoot":"../../src","sources":["api.ts"],"mappings":";;AAAA,SAASA,oBAAoB,QAAQ,kBAAS;;AAS9C;;AAgBA;;AAEA,IACEC,MAAM,CAACC,kBAAkB,IAAI,IAAI,IACjCD,MAAM,CAACE,yBAAyB,IAAI,IAAI,IACxCF,MAAM,CAACG,mBAAmB,IAAI,IAAI,IAClCH,MAAM,CAACI,iBAAiB,IAAI,IAAI,EAChC;EACA,IAAI,CAACL,oBAAoB,EAAE;IACzB,MAAM,IAAIM,KAAK,CACb,iFACF,CAAC;EACH;EAEAN,oBAAoB,CAACO,OAAO,CAAC,CAAC;AAChC;AAEA,SAASC,OAAO,IAAIC,WAAW,QAAQ,uBAAoB;AAC3D,SAASD,OAAO,IAAIE,qBAAqB,QAAQ,iCAA8B;AAC/E,SAASF,OAAO,IAAIG,0BAA0B,QAAQ,sCAAmC;AACzF,SAASH,OAAO,IAAII,YAAY,QAAQ,wBAAqB;AAC7D,SAASJ,OAAO,IAAIK,mBAAmB,QAAQ,+BAA4B;AAC3E,SAASL,OAAO,IAAIM,oBAAoB,QAAQ,gCAA6B;AAC7E,SAASN,OAAO,IAAIO,SAAS,QAAQ,qBAAkB;AACvD,SAASP,OAAO,IAAIQ,YAAY,QAAQ,wBAAqB;AAC7D,SAASR,OAAO,IAAIS,UAAU,QAAQ,sBAAmB;AACzD,SAAST,OAAO,IAAIU,wBAAwB,QAAQ,oCAAiC;AACrF,SAASV,OAAO,IAAIW,gBAAgB,QAAQ,4BAAyB;AACrE,SAASX,OAAO,IAAIY,gBAAgB,QAAQ,4BAAyB;AACrE,SAASZ,OAAO,IAAIa,QAAQ,QAAQ,oBAAiB;AACrD,SAASb,OAAO,IAAIc,cAAc,QAAQ,0BAAuB;AACjE,SAASd,OAAO,IAAIe,gBAAgB,QAAQ,4BAAyB;AACrE,SAASf,OAAO,IAAIgB,aAAa,QAAQ,yBAAsB;AAC/D,SAAShB,OAAO,IAAIiB,YAAY,QAAQ,mBAAU;AAClD,SAASjB,OAAO,IAAIkB,eAAe,QAAQ,2BAAwB;AAEnE,SACEC,cAAc,EACdC,gBAAgB,EAChBC,gBAAgB,EAChBC,qBAAqB,EACrBC,YAAY,EACZC,UAAU,EACVC,uBAAuB,QAClB,YAAS;AAEhB,SACEC,cAAc,EACdC,kBAAkB,EAClBC,iBAAiB,EACjBC,UAAU,EACVC,iBAAiB,QACZ,mBAAU","ignoreList":[]}
|
|
@@ -5,10 +5,10 @@ import AudioManager from "../system/index.js";
|
|
|
5
5
|
import { NotSupportedError } from "../errors/index.js";
|
|
6
6
|
export default class AudioContext extends BaseAudioContext {
|
|
7
7
|
constructor(options) {
|
|
8
|
-
if (options && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
8
|
+
if (options && options.sampleRate && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
9
9
|
throw new NotSupportedError(`The provided sampleRate is not supported: ${options.sampleRate}`);
|
|
10
10
|
}
|
|
11
|
-
super(global.createAudioContext(options?.sampleRate || AudioManager.getDevicePreferredSampleRate()));
|
|
11
|
+
super(global.createAudioContext(options?.sampleRate || AudioManager.getDevicePreferredSampleRate(), options?.initSuspended || false));
|
|
12
12
|
}
|
|
13
13
|
async close() {
|
|
14
14
|
await this.context.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BaseAudioContext","AudioManager","NotSupportedError","AudioContext","constructor","options","sampleRate","global","createAudioContext","getDevicePreferredSampleRate","close","context","resume","suspend"],"sourceRoot":"../../../src","sources":["core/AudioContext.ts"],"mappings":";;AACA,OAAOA,gBAAgB,MAAM,uBAAoB;AACjD,OAAOC,YAAY,MAAM,oBAAW;AAEpC,SAASC,iBAAiB,QAAQ,oBAAW;AAE7C,eAAe,MAAMC,YAAY,SAASH,gBAAgB,CAAC;EACzDI,WAAWA,CAACC,OAA6B,EAAE;IACzC,
|
|
1
|
+
{"version":3,"names":["BaseAudioContext","AudioManager","NotSupportedError","AudioContext","constructor","options","sampleRate","global","createAudioContext","getDevicePreferredSampleRate","initSuspended","close","context","resume","suspend"],"sourceRoot":"../../../src","sources":["core/AudioContext.ts"],"mappings":";;AACA,OAAOA,gBAAgB,MAAM,uBAAoB;AACjD,OAAOC,YAAY,MAAM,oBAAW;AAEpC,SAASC,iBAAiB,QAAQ,oBAAW;AAE7C,eAAe,MAAMC,YAAY,SAASH,gBAAgB,CAAC;EACzDI,WAAWA,CAACC,OAA6B,EAAE;IACzC,IACEA,OAAO,IACPA,OAAO,CAACC,UAAU,KACjBD,OAAO,CAACC,UAAU,GAAG,IAAI,IAAID,OAAO,CAACC,UAAU,GAAG,KAAK,CAAC,EACzD;MACA,MAAM,IAAIJ,iBAAiB,CACzB,6CAA6CG,OAAO,CAACC,UAAU,EACjE,CAAC;IACH;IAEA,KAAK,CACHC,MAAM,CAACC,kBAAkB,CACvBH,OAAO,EAAEC,UAAU,IAAIL,YAAY,CAACQ,4BAA4B,CAAC,CAAC,EAClEJ,OAAO,EAAEK,aAAa,IAAI,KAC5B,CACF,CAAC;EACH;EAEA,MAAMC,KAAKA,CAAA,EAAuB;IAChC,MAAO,IAAI,CAACC,OAAO,CAAmBD,KAAK,CAAC,CAAC;EAC/C;EAEA,MAAME,MAAMA,CAAA,EAAuB;IACjC,MAAO,IAAI,CAACD,OAAO,CAAmBC,MAAM,CAAC,CAAC;EAChD;EAEA,MAAMC,OAAOA,CAAA,EAAuB;IAClC,MAAO,IAAI,CAACF,OAAO,CAAmBE,OAAO,CAAC,CAAC;EACjD;AACF","ignoreList":[]}
|
|
@@ -5,8 +5,8 @@ const pkg = require('react-native-audio-api/package.json');
|
|
|
5
5
|
const withDefaultOptions = options => {
|
|
6
6
|
return {
|
|
7
7
|
iosBackgroundMode: true,
|
|
8
|
+
androidPermissions: ['android.permission.FOREGROUND_SERVICE', 'android.permission.WAKE_LOCK'],
|
|
8
9
|
androidForegroundService: true,
|
|
9
|
-
androidFSPermissions: ['android.permission.FOREGROUND_SERVICE', 'android.permission.WAKE_LOCK'],
|
|
10
10
|
androidFSTypes: ['mediaPlayback'],
|
|
11
11
|
...options
|
|
12
12
|
};
|
|
@@ -18,9 +18,9 @@ const withBackgroundAudio = config => {
|
|
|
18
18
|
});
|
|
19
19
|
};
|
|
20
20
|
const withAndroidPermissions = (config, {
|
|
21
|
-
|
|
21
|
+
androidPermissions
|
|
22
22
|
}) => {
|
|
23
|
-
return AndroidConfig.Permissions.withPermissions(config,
|
|
23
|
+
return AndroidConfig.Permissions.withPermissions(config, androidPermissions);
|
|
24
24
|
};
|
|
25
25
|
const withForegroundService = (config, {
|
|
26
26
|
androidFSTypes
|
|
@@ -49,8 +49,8 @@ const withAudioAPI = (config, optionsIn) => {
|
|
|
49
49
|
if (options.iosBackgroundMode) {
|
|
50
50
|
config = withBackgroundAudio(config);
|
|
51
51
|
}
|
|
52
|
+
config = withAndroidPermissions(config, options);
|
|
52
53
|
if (options.androidForegroundService) {
|
|
53
|
-
config = withAndroidPermissions(config, options);
|
|
54
54
|
config = withForegroundService(config, options);
|
|
55
55
|
}
|
|
56
56
|
return config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["AndroidConfig","createRunOncePlugin","withInfoPlist","withAndroidManifest","pkg","require","withDefaultOptions","options","iosBackgroundMode","
|
|
1
|
+
{"version":3,"names":["AndroidConfig","createRunOncePlugin","withInfoPlist","withAndroidManifest","pkg","require","withDefaultOptions","options","iosBackgroundMode","androidPermissions","androidForegroundService","androidFSTypes","withBackgroundAudio","config","iosConfig","modResults","UIBackgroundModes","Array","from","Set","withAndroidPermissions","Permissions","withPermissions","withForegroundService","mod","manifest","mainApplication","Manifest","getMainApplicationOrThrow","SFTypes","join","serviceElement","$","intentFilter","service","push","withAudioAPI","optionsIn","name","version"],"sourceRoot":"../../../src","sources":["plugin/withAudioAPI.ts"],"mappings":";;AAAA,SACEA,aAAa,EACbC,mBAAmB,EAEnBC,aAAa,EACbC,mBAAmB,QACd,sBAAsB;AAC7B,MAAMC,GAAG,GAAGC,OAAO,CAAC,qCAAqC,CAAC;AAS1D,MAAMC,kBAAkB,GAAIC,OAAyB,IAAc;EACjE,OAAO;IACLC,iBAAiB,EAAE,IAAI;IACvBC,kBAAkB,EAAE,CAClB,uCAAuC,EACvC,8BAA8B,CAC/B;IACDC,wBAAwB,EAAE,IAAI;IAC9BC,cAAc,EAAE,CAAC,eAAe,CAAC;IACjC,GAAGJ;EACL,CAAC;AACH,CAAC;AAED,MAAMK,mBAAiC,GAAIC,MAAM,IAAK;EACpD,OAAOX,aAAa,CAACW,MAAM,EAAGC,SAAS,IAAK;IAC1CA,SAAS,CAACC,UAAU,CAACC,iBAAiB,GAAG,CACvC,GAAGC,KAAK,CAACC,IAAI,CACX,IAAIC,GAAG,CAAC,CAAC,IAAIL,SAAS,CAACC,UAAU,CAACC,iBAAiB,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CACtE,CAAC,CACF;IAED,OAAOF,SAAS;EAClB,CAAC,CAAC;AACJ,CAAC;AAED,MAAMM,sBAA6C,GAAGA,CACpDP,MAAM,EACN;EAAEJ;AAA4B,CAAC,KAC5B;EACH,OAAOT,aAAa,CAACqB,WAAW,CAACC,eAAe,CAACT,MAAM,EAAEJ,kBAAkB,CAAC;AAC9E,CAAC;AAED,MAAMc,qBAA4C,GAAGA,CACnDV,MAAM,EACN;EAAEF;AAAwB,CAAC,KACxB;EACH,OAAOR,mBAAmB,CAACU,MAAM,EAAGW,GAAG,IAAK;IAC1C,MAAMC,QAAQ,GAAGD,GAAG,CAACT,UAAU;IAC/B,MAAMW,eAAe,GACnB1B,aAAa,CAAC2B,QAAQ,CAACC,yBAAyB,CAACH,QAAQ,CAAC;IAE5D,MAAMI,OAAO,GAAGlB,cAAc,CAACmB,IAAI,CAAC,GAAG,CAAC;IAExC,MAAMC,cAAc,GAAG;MACrBC,CAAC,EAAE;QACD,cAAc,EACZ,4EAA4E;QAC9E,sBAAsB,EAAE,MAAM;QAC9B,+BAA+B,EAAEH;MACnC,CAAC;MACDI,YAAY,EAAE;IAChB,CAAC;IAED,IAAI,CAACP,eAAe,CAACQ,OAAO,EAAE;MAC5BR,eAAe,CAACQ,OAAO,GAAG,EAAE;IAC9B;IAEAR,eAAe,CAACQ,OAAO,CAACC,IAAI,CAACJ,cAAc,CAAC;IAE5C,OAAOP,GAAG;EACZ,CAAC,CAAC;AACJ,CAAC;AAED,MAAMY,YAAmC,GAAGA,CAACvB,MAAM,EAAEwB,SAAS,KAAK;EACjE,MAAM9B,OAAO,GAAGD,kBAAkB,CAAC+B,SAAS,IAAI,CAAC,CAAC,CAAC;EAEnD,IAAI9B,OAAO,CAACC,iBAAiB,EAAE;IAC7BK,MAAM,GAAGD,mBAAmB,CAACC,MAAM,CAAC;EACtC;EAEAA,MAAM,GAAGO,sBAAsB,CAACP,MAAM,EAAEN,OAAO,CAAC;EAEhD,IAAIA,OAAO,CAACG,wBAAwB,EAAE;IACpCG,MAAM,GAAGU,qBAAqB,CAACV,MAAM,EAAEN,OAAO,CAAC;EACjD;EAEA,OAAOM,MAAM;AACf,CAAC;AAED,eAAeZ,mBAAmB,CAACmC,YAAY,EAAEhC,GAAG,CAACkC,IAAI,EAAElC,GAAG,CAACmC,OAAO,CAAC","ignoreList":[]}
|
|
@@ -12,11 +12,13 @@ import PeriodicWave from "./PeriodicWave.js";
|
|
|
12
12
|
import StereoPannerNode from "./StereoPannerNode.js";
|
|
13
13
|
import { globalWasmPromise, globalTag } from "./custom/LoadCustomWasm.js";
|
|
14
14
|
export default class AudioContext {
|
|
15
|
-
constructor(options) {
|
|
16
|
-
if (options && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
15
|
+
constructor(options, _initSuspended = false) {
|
|
16
|
+
if (options && options.sampleRate && (options.sampleRate < 8000 || options.sampleRate > 96000)) {
|
|
17
17
|
throw new NotSupportedError(`The provided sampleRate is not supported: ${options.sampleRate}`);
|
|
18
18
|
}
|
|
19
|
-
this.context = new window.AudioContext(
|
|
19
|
+
this.context = new window.AudioContext({
|
|
20
|
+
sampleRate: options?.sampleRate
|
|
21
|
+
});
|
|
20
22
|
this.sampleRate = this.context.sampleRate;
|
|
21
23
|
this.destination = new AudioDestinationNode(this, this.context.destination);
|
|
22
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["InvalidAccessError","NotSupportedError","AnalyserNode","AudioDestinationNode","AudioBuffer","AudioBufferSourceNode","BiquadFilterNode","GainNode","OscillatorNode","PeriodicWave","StereoPannerNode","globalWasmPromise","globalTag","AudioContext","constructor","options","sampleRate","context","window","destination","currentTime","state","createOscillator","createGain","createStereoPanner","createBiquadFilter","createBufferSource","pitchCorrection","wasmStretch","createBuffer","numOfChannels","length","createPeriodicWave","real","imag","constraints","createAnalyser","decodeAudioDataSource","source","arrayBuffer","fetch","then","response","decodeAudioData","close","resume","suspend"],"sourceRoot":"../../../src","sources":["web-core/AudioContext.tsx"],"mappings":";;AAMA,SAASA,kBAAkB,EAAEC,iBAAiB,QAAQ,oBAAW;AAEjE,OAAOC,YAAY,MAAM,mBAAgB;AACzC,OAAOC,oBAAoB,MAAM,2BAAwB;AACzD,OAAOC,WAAW,MAAM,kBAAe;AACvC,OAAOC,qBAAqB,MAAM,4BAAyB;AAC3D,OAAOC,gBAAgB,MAAM,uBAAoB;AACjD,OAAOC,QAAQ,MAAM,eAAY;AACjC,OAAOC,cAAc,MAAM,qBAAkB;AAC7C,OAAOC,YAAY,MAAM,mBAAgB;AACzC,OAAOC,gBAAgB,MAAM,uBAAoB;AAEjD,SAASC,iBAAiB,EAAEC,SAAS,QAAQ,4BAAyB;AAEtE,eAAe,MAAMC,YAAY,CAA6B;EAM5DC,WAAWA,CAACC,OAA6B,EAAE;
|
|
1
|
+
{"version":3,"names":["InvalidAccessError","NotSupportedError","AnalyserNode","AudioDestinationNode","AudioBuffer","AudioBufferSourceNode","BiquadFilterNode","GainNode","OscillatorNode","PeriodicWave","StereoPannerNode","globalWasmPromise","globalTag","AudioContext","constructor","options","_initSuspended","sampleRate","context","window","destination","currentTime","state","createOscillator","createGain","createStereoPanner","createBiquadFilter","createBufferSource","pitchCorrection","wasmStretch","createBuffer","numOfChannels","length","createPeriodicWave","real","imag","constraints","createAnalyser","decodeAudioDataSource","source","arrayBuffer","fetch","then","response","decodeAudioData","close","resume","suspend"],"sourceRoot":"../../../src","sources":["web-core/AudioContext.tsx"],"mappings":"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","ignoreList":[]}
|
package/lib/typescript/api.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AudioRecorderOptions } from './types';
|
|
2
2
|
import type { IAudioContext, IAudioRecorder, IOfflineAudioContext, IAudioEventEmitter } from './interfaces';
|
|
3
3
|
declare global {
|
|
4
|
-
var createAudioContext: (sampleRate
|
|
4
|
+
var createAudioContext: (sampleRate: number, initSuspended: boolean) => IAudioContext;
|
|
5
5
|
var createOfflineAudioContext: (numberOfChannels: number, length: number, sampleRate: number) => IOfflineAudioContext;
|
|
6
6
|
var createAudioRecorder: (options: AudioRecorderOptions) => IAudioRecorder;
|
|
7
7
|
var AudioEventEmitter: IAudioEventEmitter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,kBAAkB,EAAE,CACtB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,OAAO,KACnB,aAAa,CAAC;IACnB,IAAI,yBAAyB,EAAE,CAC7B,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,KACf,oBAAoB,CAAC;IAE1B,IAAI,mBAAmB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,cAAc,CAAC;IAE3E,IAAI,iBAAiB,EAAE,kBAAkB,CAAC;CAC3C;AAkBD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC1F,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,iBAAiB,GAClB,MAAM,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioContext.d.ts","sourceRoot":"","sources":["../../../src/core/AudioContext.ts"],"names":[],"mappings":"AACA,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,gBAAgB;gBAC5C,OAAO,CAAC,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"AudioContext.d.ts","sourceRoot":"","sources":["../../../src/core/AudioContext.ts"],"names":[],"mappings":"AACA,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,gBAAgB;gBAC5C,OAAO,CAAC,EAAE,mBAAmB;IAmBnC,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC;IAI3B,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC;IAI5B,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;CAGpC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
2
|
interface Options {
|
|
3
3
|
iosBackgroundMode: boolean;
|
|
4
|
+
androidPermissions: string[];
|
|
4
5
|
androidForegroundService: boolean;
|
|
5
|
-
androidFSPermissions: string[];
|
|
6
6
|
androidFSTypes: string[];
|
|
7
7
|
}
|
|
8
8
|
declare const _default: ConfigPlugin<Options>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withAudioAPI.d.ts","sourceRoot":"","sources":["../../../src/plugin/withAudioAPI.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EAGb,MAAM,sBAAsB,CAAC;AAG9B,UAAU,OAAO;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,
|
|
1
|
+
{"version":3,"file":"withAudioAPI.d.ts","sourceRoot":"","sources":["../../../src/plugin/withAudioAPI.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EAGb,MAAM,sBAAsB,CAAC;AAG9B,UAAU,OAAO;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,wBAAwB,EAAE,OAAO,CAAC;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;;AAiFD,wBAAwE"}
|
|
@@ -7,7 +7,8 @@ export interface PeriodicWaveConstraints {
|
|
|
7
7
|
disableNormalization: boolean;
|
|
8
8
|
}
|
|
9
9
|
export interface AudioContextOptions {
|
|
10
|
-
sampleRate
|
|
10
|
+
sampleRate?: number;
|
|
11
|
+
initSuspended?: boolean;
|
|
11
12
|
}
|
|
12
13
|
export interface OfflineAudioContextOptions {
|
|
13
14
|
numberOfChannels: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,aAAa,GAAG,UAAU,CAAC;AAElE,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,UAAU,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GACX,SAAS,GACT,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,QAAQ,GACR,UAAU,GACV,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,uBAAuB;IACtC,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,aAAa,GAAG,UAAU,CAAC;AAElE,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,UAAU,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GACX,SAAS,GACT,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,QAAQ,GACR,UAAU,GACV,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,uBAAuB;IACtC,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,4BAA4B;IAC3C,eAAe,EAAE,OAAO,CAAC;CAC1B"}
|
|
@@ -13,7 +13,7 @@ export default class AudioContext implements BaseAudioContext {
|
|
|
13
13
|
readonly context: globalThis.AudioContext;
|
|
14
14
|
readonly destination: AudioDestinationNode;
|
|
15
15
|
readonly sampleRate: number;
|
|
16
|
-
constructor(options?: AudioContextOptions);
|
|
16
|
+
constructor(options?: AudioContextOptions, _initSuspended?: boolean);
|
|
17
17
|
get currentTime(): number;
|
|
18
18
|
get state(): ContextState;
|
|
19
19
|
createOscillator(): OscillatorNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioContext.d.ts","sourceRoot":"","sources":["../../../src/web-core/AudioContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,4BAA4B,EAC7B,MAAM,UAAU,CAAC;AAElB,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,qBAAqB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAIlD,MAAM,CAAC,OAAO,OAAO,YAAa,YAAW,gBAAgB;IAC3D,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC;IAE1C,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,OAAO,CAAC,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"AudioContext.d.ts","sourceRoot":"","sources":["../../../src/web-core/AudioContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,4BAA4B,EAC7B,MAAM,UAAU,CAAC;AAElB,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,qBAAqB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAIlD,MAAM,CAAC,OAAO,OAAO,YAAa,YAAW,gBAAgB;IAC3D,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC;IAE1C,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,OAAO,CAAC,EAAE,mBAAmB,EAAE,cAAc,GAAE,OAAe;IAiB1E,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,KAAK,IAAI,YAAY,CAE/B;IAED,gBAAgB,IAAI,cAAc;IAIlC,UAAU,IAAI,QAAQ;IAItB,kBAAkB,IAAI,gBAAgB;IAItC,kBAAkB,IAAI,gBAAgB;IAIhC,kBAAkB,CACtB,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,qBAAqB,CAAC;IAgBjC,YAAY,CACV,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,WAAW;IAwBd,kBAAkB,CAChB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,YAAY,EAClB,WAAW,CAAC,EAAE,uBAAuB,GACpC,YAAY;IAYf,cAAc,IAAI,YAAY;IAIxB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAQ3D,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAI/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-audio-api",
|
|
3
|
-
"version": "0.6.1
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification",
|
|
5
5
|
"bin": {
|
|
6
6
|
"setup-rn-audio-api-web": "./scripts/setup-rn-audio-api-web.js"
|
package/src/api.ts
CHANGED
|
@@ -9,7 +9,10 @@ import type {
|
|
|
9
9
|
|
|
10
10
|
/* eslint-disable no-var */
|
|
11
11
|
declare global {
|
|
12
|
-
var createAudioContext: (
|
|
12
|
+
var createAudioContext: (
|
|
13
|
+
sampleRate: number,
|
|
14
|
+
initSuspended: boolean
|
|
15
|
+
) => IAudioContext;
|
|
13
16
|
var createOfflineAudioContext: (
|
|
14
17
|
numberOfChannels: number,
|
|
15
18
|
length: number,
|
package/src/core/AudioContext.ts
CHANGED
|
@@ -6,7 +6,11 @@ import { NotSupportedError } from '../errors';
|
|
|
6
6
|
|
|
7
7
|
export default class AudioContext extends BaseAudioContext {
|
|
8
8
|
constructor(options?: AudioContextOptions) {
|
|
9
|
-
if (
|
|
9
|
+
if (
|
|
10
|
+
options &&
|
|
11
|
+
options.sampleRate &&
|
|
12
|
+
(options.sampleRate < 8000 || options.sampleRate > 96000)
|
|
13
|
+
) {
|
|
10
14
|
throw new NotSupportedError(
|
|
11
15
|
`The provided sampleRate is not supported: ${options.sampleRate}`
|
|
12
16
|
);
|
|
@@ -14,7 +18,8 @@ export default class AudioContext extends BaseAudioContext {
|
|
|
14
18
|
|
|
15
19
|
super(
|
|
16
20
|
global.createAudioContext(
|
|
17
|
-
options?.sampleRate || AudioManager.getDevicePreferredSampleRate()
|
|
21
|
+
options?.sampleRate || AudioManager.getDevicePreferredSampleRate(),
|
|
22
|
+
options?.initSuspended || false
|
|
18
23
|
)
|
|
19
24
|
);
|
|
20
25
|
}
|
|
@@ -9,19 +9,19 @@ const pkg = require('react-native-audio-api/package.json');
|
|
|
9
9
|
|
|
10
10
|
interface Options {
|
|
11
11
|
iosBackgroundMode: boolean;
|
|
12
|
+
androidPermissions: string[];
|
|
12
13
|
androidForegroundService: boolean;
|
|
13
|
-
androidFSPermissions: string[];
|
|
14
14
|
androidFSTypes: string[];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const withDefaultOptions = (options: Partial<Options>): Options => {
|
|
18
18
|
return {
|
|
19
19
|
iosBackgroundMode: true,
|
|
20
|
-
|
|
21
|
-
androidFSPermissions: [
|
|
20
|
+
androidPermissions: [
|
|
22
21
|
'android.permission.FOREGROUND_SERVICE',
|
|
23
22
|
'android.permission.WAKE_LOCK',
|
|
24
23
|
],
|
|
24
|
+
androidForegroundService: true,
|
|
25
25
|
androidFSTypes: ['mediaPlayback'],
|
|
26
26
|
...options,
|
|
27
27
|
};
|
|
@@ -41,12 +41,9 @@ const withBackgroundAudio: ConfigPlugin = (config) => {
|
|
|
41
41
|
|
|
42
42
|
const withAndroidPermissions: ConfigPlugin<Options> = (
|
|
43
43
|
config,
|
|
44
|
-
{
|
|
44
|
+
{ androidPermissions }: Options
|
|
45
45
|
) => {
|
|
46
|
-
return AndroidConfig.Permissions.withPermissions(
|
|
47
|
-
config,
|
|
48
|
-
androidFSPermissions
|
|
49
|
-
);
|
|
46
|
+
return AndroidConfig.Permissions.withPermissions(config, androidPermissions);
|
|
50
47
|
};
|
|
51
48
|
|
|
52
49
|
const withForegroundService: ConfigPlugin<Options> = (
|
|
@@ -87,8 +84,9 @@ const withAudioAPI: ConfigPlugin<Options> = (config, optionsIn) => {
|
|
|
87
84
|
config = withBackgroundAudio(config);
|
|
88
85
|
}
|
|
89
86
|
|
|
87
|
+
config = withAndroidPermissions(config, options);
|
|
88
|
+
|
|
90
89
|
if (options.androidForegroundService) {
|
|
91
|
-
config = withAndroidPermissions(config, options);
|
|
92
90
|
config = withForegroundService(config, options);
|
|
93
91
|
}
|
|
94
92
|
|
package/src/types.ts
CHANGED
|
@@ -24,14 +24,18 @@ export default class AudioContext implements BaseAudioContext {
|
|
|
24
24
|
readonly destination: AudioDestinationNode;
|
|
25
25
|
readonly sampleRate: number;
|
|
26
26
|
|
|
27
|
-
constructor(options?: AudioContextOptions) {
|
|
28
|
-
if (
|
|
27
|
+
constructor(options?: AudioContextOptions, _initSuspended: boolean = false) {
|
|
28
|
+
if (
|
|
29
|
+
options &&
|
|
30
|
+
options.sampleRate &&
|
|
31
|
+
(options.sampleRate < 8000 || options.sampleRate > 96000)
|
|
32
|
+
) {
|
|
29
33
|
throw new NotSupportedError(
|
|
30
34
|
`The provided sampleRate is not supported: ${options.sampleRate}`
|
|
31
35
|
);
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
this.context = new window.AudioContext(options);
|
|
38
|
+
this.context = new window.AudioContext({ sampleRate: options?.sampleRate });
|
|
35
39
|
|
|
36
40
|
this.sampleRate = this.context.sampleRate;
|
|
37
41
|
this.destination = new AudioDestinationNode(this, this.context.destination);
|