diff --git a/README.md b/README.md
index ba9481c..b114cf9 100644
--- a/README.md
+++ b/README.md
@@ -9,20 +9,21 @@ Install the npm package and link it to your project:
npm i react-native-sound-level --save
```
-On *iOS* you need to add a usage description to `Info.plist`:
+On _iOS_ you need to add a usage description to `Info.plist`:
```
NSMicrophoneUsageDescription
This sample uses the microphone to analyze sound level.
```
-On *Android* you need to add a permission to `AndroidManifest.xml`:
+On _Android_ you need to add a permission to `AndroidManifest.xml`:
```
```
### Manual installation on iOS
+
```
In XCode, in the project navigator:
@@ -37,64 +38,66 @@ In XCode, in the project navigator, select your project.
```
### Installation on Ubuntu
+
1. Add to package.json: `"desktopExternalModules": [ "node_modules/react-native-sound-level/desktop" ]`
2. You may need to make QT's multimedia library accessible for linker
-`sudo ln -s $YOUR_QT_DIR/5.9.1/gcc_64/lib/libQt5Multimedia.so /usr/local/lib/libQt5Multimedia.so`
-
+ `sudo ln -s $YOUR_QT_DIR/5.9.1/gcc_64/lib/libQt5Multimedia.so /usr/local/lib/libQt5Multimedia.so`
### React Native 0.60+
+
To make it run correctly on iOS you may need the following:
+
1. Add `pod 'react-native-sound-level', :podspec => '../node_modules/react-native-sound-level/RNSoundLevel.podspec'` to your `ios/Podfile` file.
2. Unlink the library if linked before (`react-native unlink react-native-sound-level`).
3. Run `pod install` from within your project `ios` directory
-
### Usage
1. Request permission to access microphone, handle the UI by yourself.
-You may use [react-native-permissions](https://www.npmjs.com/package/react-native-permissions) package or simply
-[PermissionsAndroid](https://reactnative.dev/docs/permissionsandroid) module.
+ You may use [react-native-permissions](https://www.npmjs.com/package/react-native-permissions) package or simply
+ [PermissionsAndroid](https://reactnative.dev/docs/permissionsandroid) module.
2. Configure the monitor and start it.
3. Makes sense to stop it when not used.
```ts
-import RNSoundLevel from 'react-native-sound-level'
+import RNSoundLevel from "react-native-sound-level";
-const MONITOR_INTERVAL = 250 // in ms
+const MONITOR_INTERVAL = 250; // in ms
const requestPermission = async () => {
// request permission to access microphone
// ...
if (success) {
// start monitoring
- RNSoundLevel.start()
-
+ RNSoundLevel.start();
+
// you may also specify a monitor interval (default is 250ms)
- RNSoundLevel.start(MONITOR_INTERVAL)
-
+ RNSoundLevel.start(MONITOR_INTERVAL);
+
// or add even more options
RNSoundLevel.start({
monitorInterval: MONITOR_INTERVAL,
samplingRate: 16000, // default is 22050
- })
+ allowHapticsAndSystemSoundsDuringRecording: true, // Allow Haptic and System sound during recording. Default is false
+ });
}
-}
+};
useEffect(() => {
RNSoundLevel.onNewFrame = (data) => {
// see "Returned data" section below
- console.log('Sound level info', data)
- }
-
+ console.log("Sound level info", data);
+ };
+
return () => {
// don't forget to stop it
- RNSoundLevel.stop()
- }
-}, [])
-
+ RNSoundLevel.stop();
+ };
+}, []);
```
### Returned data
+
```
{
"id", // frame number
diff --git a/index.d.ts b/index.d.ts
index 0c90704..b30ec77 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -14,21 +14,27 @@ export type SoundLevelResult = {
* @description raw level value, OS-depended
*/
rawValue: number;
-}
+};
export type SoundLevelMonitorConfig = {
- monitoringInterval?: number
- samplingRate?: number
-}
+ monitoringInterval?: number;
+ samplingRate?: number;
+};
+
+export type SoundLevelConfigiOS = {
+ allowHapticsAndSystemSoundsDuringRecording?: boolean;
+};
+
+export type SoundLevelConfig = SoundLevelMonitorConfig & SoundLevelConfigiOS;
export type SoundLevelType = {
/**
* @description monitoringInterval is not supported for desktop yet
*/
- start: (config?: number | SoundLevelMonitorConfig) => void;
+ start: (config?: number | SoundLevelConfig) => void;
stop: () => void;
onNewFrame: (result: SoundLevelResult) => void;
-}
+};
declare const SoundLevel: SoundLevelType;
diff --git a/index.js b/index.js
index 8d62ec7..86226f3 100644
--- a/index.js
+++ b/index.js
@@ -1,62 +1,74 @@
-'use strict'
+"use strict";
-import { NativeModules, NativeAppEventEmitter, Platform } from 'react-native'
+import { NativeModules, NativeAppEventEmitter, Platform } from "react-native";
var SoundLevelModule =
- Platform.OS === 'desktop'
+ Platform.OS === "desktop"
? NativeModules.RNSoundLevel
- : NativeModules.RNSoundLevelModule
+ : NativeModules.RNSoundLevelModule;
var SoundLevel = {
timer: null,
start: function (_monitorConfig = 250) {
const monitorConfig = {
- monitorInterval: 250,
- samplingRate: 22050,
- }
+ monitorInterval: _monitorConfig?.monitorInterval ?? 250,
+ samplingRate: _monitorConfig?.samplingRate ?? 22050,
+ allowHapticsAndSystemSoundsDuringRecording:
+ _monitorConfig?.allowHapticsAndSystemSoundsDuringRecording ?? false,
+ };
- if (typeof _monitorConfig === 'number') {
- monitorConfig.monitorInterval = _monitorConfig
+ if (typeof _monitorConfig === "number") {
+ monitorConfig.monitorInterval = _monitorConfig;
}
if (this.frameSubscription) {
- this.frameSubscription.remove()
+ this.frameSubscription.remove();
}
- if (Platform.OS === 'desktop') {
+ if (Platform.OS === "desktop") {
this.timer = setInterval(async () => {
if (this.onNewFrame) {
- const frame = await SoundLevelModule.measure()
- this.onNewFrame(JSON.parse(frame))
+ const frame = await SoundLevelModule.measure();
+ this.onNewFrame(JSON.parse(frame));
}
- }, monitorConfig.monitorInterval)
+ }, monitorConfig.monitorInterval);
} else {
this.frameSubscription = NativeAppEventEmitter.addListener(
- 'frame',
- data => {
+ "frame",
+ (data) => {
if (this.onNewFrame) {
- this.onNewFrame(data)
+ this.onNewFrame(data);
}
}
- )
+ );
}
- // Monitoring interval not supported for Android yet. Feel free to add and do a pull request. :)
- return Platform.OS !== 'desktop' ? SoundLevelModule.start(monitorConfig.monitorInterval, monitorConfig.samplingRate) : SoundLevelModule.start()
+ return Platform.OS === "ios"
+ ? SoundLevelModule.start(
+ monitorConfig.monitorInterval,
+ monitorConfig.samplingRate,
+ monitorConfig.allowHapticsAndSystemSoundsDuringRecording
+ )
+ : Platform.OS === "android"
+ ? SoundLevelModule.start(
+ monitorConfig.monitorInterval,
+ monitorConfig.samplingRate
+ )
+ : SoundLevelModule.start();
},
stop: function () {
if (this.frameSubscription) {
- this.frameSubscription.remove()
+ this.frameSubscription.remove();
}
if (this.timer) {
- clearInterval(this.timer)
+ clearInterval(this.timer);
}
- return SoundLevelModule.stop()
- }
-}
+ return SoundLevelModule.stop();
+ },
+};
-module.exports = SoundLevel
+module.exports = SoundLevel;
diff --git a/ios/RNSoundLevelModule.m b/ios/RNSoundLevelModule.m
index c48631d..f881f88 100644
--- a/ios/RNSoundLevelModule.m
+++ b/ios/RNSoundLevelModule.m
@@ -62,7 +62,7 @@ - (void)startProgressTimer:(int)monitorInterval {
[_progressUpdateTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
-RCT_EXPORT_METHOD(start:(int)monitorInterval samplingRate:(float)sampleRate)
+RCT_EXPORT_METHOD(start:(int)monitorInterval samplingRate:(float)sampleRate allowHapticsAndSystemSoundsDuringRecording:(BOOL)allow)
{
NSLog(@"Start Monitoring");
_prevProgressUpdateTime = nil;
@@ -72,7 +72,7 @@ - (void)startProgressTimer:(int)monitorInterval {
[NSNumber numberWithInt:AVAudioQualityLow], AVEncoderAudioQualityKey,
[NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithInt:1], AVNumberOfChannelsKey,
- [NSNumber numberWithFloat:samplingRate], AVSampleRateKey,
+ [NSNumber numberWithFloat:sampleRate], AVSampleRateKey,
nil];
NSError *error = nil;
@@ -98,6 +98,11 @@ - (void)startProgressTimer:(int)monitorInterval {
_audioRecorder.meteringEnabled = YES;
[self startProgressTimer:monitorInterval];
+ // Allow Haptic and System sound during recording
+ // https://developer.apple.com/documentation/avfaudio/avaudiosession/3240575-allowhapticsandsystemsoundsdurin?language=objc
+ if (@available(iOS 13.0, *)) {
+ [_recordSession setAllowHapticsAndSystemSoundsDuringRecording:allow error:nil];
+ }
[_recordSession setActive:YES error:nil];
[_audioRecorder record];
}