react-native-audio-api 0.6.1-rc.9 → 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/java/com/swmansion/audioapi/AudioAPIModule.kt +6 -16
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +7 -7
- package/android/src/main/java/com/swmansion/audioapi/system/PermissionRequestListener.kt +33 -0
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +1 -1
- package/ios/audioapi/ios/AudioAPIModule.mm +2 -4
- package/ios/audioapi/ios/core/NativeAudioPlayer.m +1 -1
- package/ios/audioapi/ios/system/AudioEngine.h +2 -4
- package/ios/audioapi/ios/system/AudioEngine.mm +25 -4
- package/ios/audioapi/ios/system/AudioSessionManager.h +3 -2
- package/ios/audioapi/ios/system/AudioSessionManager.mm +55 -4
- package/lib/commonjs/plugin/withAudioAPI.js +4 -4
- package/lib/commonjs/plugin/withAudioAPI.js.map +1 -1
- package/lib/module/plugin/withAudioAPI.js +4 -4
- package/lib/module/plugin/withAudioAPI.js.map +1 -1
- package/lib/typescript/plugin/withAudioAPI.d.ts +1 -1
- package/lib/typescript/plugin/withAudioAPI.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/plugin/withAudioAPI.ts +7 -9
|
@@ -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)
|
|
@@ -53,10 +54,8 @@ class AudioAPIModule(
|
|
|
53
54
|
return true
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
@Synchronized
|
|
57
57
|
override fun getDevicePreferredSampleRate(): Double = MediaSessionManager.getDevicePreferredSampleRate()
|
|
58
58
|
|
|
59
|
-
@Synchronized
|
|
60
59
|
override fun setAudioSessionActivity(
|
|
61
60
|
enabled: Boolean,
|
|
62
61
|
promise: Promise?,
|
|
@@ -64,7 +63,6 @@ class AudioAPIModule(
|
|
|
64
63
|
// noting to do here
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
@Synchronized
|
|
68
66
|
override fun setAudioSessionOptions(
|
|
69
67
|
category: String?,
|
|
70
68
|
mode: String?,
|
|
@@ -73,17 +71,14 @@ class AudioAPIModule(
|
|
|
73
71
|
// noting to do here
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
@Synchronized
|
|
77
74
|
override fun setLockScreenInfo(info: ReadableMap?) {
|
|
78
75
|
MediaSessionManager.setLockScreenInfo(info)
|
|
79
76
|
}
|
|
80
77
|
|
|
81
|
-
@Synchronized
|
|
82
78
|
override fun resetLockScreenInfo() {
|
|
83
79
|
MediaSessionManager.resetLockScreenInfo()
|
|
84
80
|
}
|
|
85
81
|
|
|
86
|
-
@Synchronized
|
|
87
82
|
override fun enableRemoteCommand(
|
|
88
83
|
name: String?,
|
|
89
84
|
enabled: Boolean,
|
|
@@ -91,25 +86,20 @@ class AudioAPIModule(
|
|
|
91
86
|
MediaSessionManager.enableRemoteCommand(name!!, enabled)
|
|
92
87
|
}
|
|
93
88
|
|
|
94
|
-
@Synchronized
|
|
95
89
|
override fun observeAudioInterruptions(enabled: Boolean) {
|
|
96
90
|
MediaSessionManager.observeAudioInterruptions(enabled)
|
|
97
91
|
}
|
|
98
92
|
|
|
99
|
-
@Synchronized
|
|
100
93
|
override fun observeVolumeChanges(enabled: Boolean) {
|
|
101
94
|
MediaSessionManager.observeVolumeChanges(enabled)
|
|
102
95
|
}
|
|
103
96
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
promise!!.resolve(res)
|
|
97
|
+
override fun requestRecordingPermissions(promise: Promise) {
|
|
98
|
+
val permissionRequestListener = PermissionRequestListener(promise)
|
|
99
|
+
MediaSessionManager.requestRecordingPermissions(permissionRequestListener)
|
|
108
100
|
}
|
|
109
101
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
val res = MediaSessionManager.checkRecordingPermissions()
|
|
113
|
-
promise!!.resolve(res)
|
|
102
|
+
override fun checkRecordingPermissions(promise: Promise) {
|
|
103
|
+
promise.resolve(MediaSessionManager.checkRecordingPermissions())
|
|
114
104
|
}
|
|
115
105
|
}
|
|
@@ -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 {
|
|
@@ -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
|
+
}
|
|
@@ -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
|
}
|
|
@@ -131,15 +131,13 @@ RCT_EXPORT_METHOD(
|
|
|
131
131
|
requestRecordingPermissions : (nonnull RCTPromiseResolveBlock)resolve reject : (nonnull RCTPromiseRejectBlock)
|
|
132
132
|
reject)
|
|
133
133
|
{
|
|
134
|
-
|
|
135
|
-
resolve(res);
|
|
134
|
+
[self.audioSessionManager requestRecordingPermissions:resolve reject:reject];
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
RCT_EXPORT_METHOD(
|
|
139
138
|
checkRecordingPermissions : (nonnull RCTPromiseResolveBlock)resolve reject : (nonnull RCTPromiseRejectBlock)reject)
|
|
140
139
|
{
|
|
141
|
-
|
|
142
|
-
resolve(res);
|
|
140
|
+
[self.audioSessionManager checkRecordingPermissions:resolve reject:reject];
|
|
143
141
|
}
|
|
144
142
|
|
|
145
143
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
@@ -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,7 +21,7 @@
|
|
|
20
21
|
- (bool)rebuildAudioEngine;
|
|
21
22
|
- (void)startEngine;
|
|
22
23
|
- (void)stopEngine;
|
|
23
|
-
- (void)pauseEngine;
|
|
24
|
+
- (void)pauseEngine:(NSString *)sourceNodeId;
|
|
24
25
|
- (bool)isRunning;
|
|
25
26
|
|
|
26
27
|
- (NSString *)attachSourceNode:(AVAudioSourceNode *)sourceNode format:(AVAudioFormat *)format;
|
|
@@ -29,7 +30,4 @@
|
|
|
29
30
|
- (void)attachInputNode:(AVAudioSinkNode *)inputNode;
|
|
30
31
|
- (void)detachInputNode;
|
|
31
32
|
|
|
32
|
-
- (void)startIfNecessary;
|
|
33
|
-
- (void)stopIfNecessary;
|
|
34
|
-
|
|
35
33
|
@end
|
|
@@ -18,6 +18,7 @@ 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
24
|
}
|
|
@@ -37,6 +38,7 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
37
38
|
self.audioEngine = nil;
|
|
38
39
|
self.sourceNodes = nil;
|
|
39
40
|
self.sourceFormats = nil;
|
|
41
|
+
self.sourceStates = nil;
|
|
40
42
|
self.inputNode = nil;
|
|
41
43
|
|
|
42
44
|
[self.sessionManager setActive:false];
|
|
@@ -74,8 +76,8 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
74
76
|
return;
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
[self.audioEngine startAndReturnError:&error];
|
|
78
79
|
[self.sessionManager setActive:true];
|
|
80
|
+
[self.audioEngine startAndReturnError:&error];
|
|
79
81
|
|
|
80
82
|
if (error != nil) {
|
|
81
83
|
NSLog(@"Error while starting the audio engine: %@", [error debugDescription]);
|
|
@@ -92,14 +94,14 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
92
94
|
[self.audioEngine stop];
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
- (void)pauseEngine
|
|
97
|
+
- (void)pauseEngine:(NSString *)sourceNodeId
|
|
96
98
|
{
|
|
97
|
-
NSLog(@"[AudioEngine] pauseEngine");
|
|
98
99
|
if (![self.audioEngine isRunning]) {
|
|
99
100
|
return;
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
[self.
|
|
103
|
+
[self.sourceStates setValue:@false forKey:sourceNodeId];
|
|
104
|
+
[self pauseIfNecessary];
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
- (bool)isRunning
|
|
@@ -114,6 +116,7 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
114
116
|
|
|
115
117
|
[self.sourceNodes setValue:sourceNode forKey:sourceNodeId];
|
|
116
118
|
[self.sourceFormats setValue:format forKey:sourceNodeId];
|
|
119
|
+
[self.sourceStates setValue:@true forKey:sourceNodeId];
|
|
117
120
|
|
|
118
121
|
[self.audioEngine attachNode:sourceNode];
|
|
119
122
|
[self.audioEngine connect:sourceNode to:self.audioEngine.mainMixerNode format:format];
|
|
@@ -133,6 +136,7 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
133
136
|
|
|
134
137
|
[self.sourceNodes removeObjectForKey:sourceNodeId];
|
|
135
138
|
[self.sourceFormats removeObjectForKey:sourceNodeId];
|
|
139
|
+
[self.sourceStates removeObjectForKey:sourceNodeId];
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
[self stopIfNecessary];
|
|
@@ -180,4 +184,21 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
180
184
|
}
|
|
181
185
|
}
|
|
182
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
|
+
|
|
183
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
|
|
@@ -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":[]}
|
|
@@ -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":[]}
|
|
@@ -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"}
|
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"
|
|
@@ -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
|
|