diff --git a/android/src/main/java/com/dooboolab/RNAudioRecorderPlayerModule.java b/android/src/main/java/com/dooboolab/RNAudioRecorderPlayerModule.java index fee75f0c..ac8752be 100644 --- a/android/src/main/java/com/dooboolab/RNAudioRecorderPlayerModule.java +++ b/android/src/main/java/com/dooboolab/RNAudioRecorderPlayerModule.java @@ -42,6 +42,7 @@ public class RNAudioRecorderPlayerModule extends ReactContextBaseJavaModule impl private String audioFileURL = ""; private int subsDurationMillis = 100; + private boolean _meteringEnabled = false; private final ReactApplicationContext reactContext; private MediaRecorder mediaRecorder; @@ -63,7 +64,7 @@ public String getName() { } @ReactMethod - public void startRecorder(final String path, final ReadableMap audioSet, Promise promise) { + public void startRecorder(final String path, final Boolean meteringEnabled, final ReadableMap audioSet, Promise promise) { try { if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && @@ -86,6 +87,7 @@ public void startRecorder(final String path, final ReadableMap audioSet, Promise } audioFileURL = (path.equals("DEFAULT")) ? FILE_LOCATION : path; + _meteringEnabled = meteringEnabled; if (mediaRecorder == null) { mediaRecorder = new MediaRecorder(); @@ -116,6 +118,18 @@ public void run() { long time = SystemClock.elapsedRealtime() - systemTime; WritableMap obj = Arguments.createMap(); obj.putDouble("current_position", time); + int maxAmplitude = 0; + if (mediaRecorder != null) { + maxAmplitude = mediaRecorder.getMaxAmplitude(); + + } + double dB = -160; + double maxAudioSize = 32767; + if (maxAmplitude > 0){ + dB = 20 * Math.log10(maxAmplitude / maxAudioSize); + } + + obj.putInt("current_metering", (int) dB); sendEvent(reactContext, "rn-recordback", obj); recordHandler.postDelayed(this, subsDurationMillis); } diff --git a/index.ts b/index.ts index 170333ad..2f767418 100644 --- a/index.ts +++ b/index.ts @@ -185,15 +185,19 @@ class AudioRecorderPlayer { */ startRecorder = async ( uri?: string, + meteringEnabled?: boolean, audioSets?: AudioSet, ): Promise => { if (!uri) { uri = 'DEFAULT'; } + if (!meteringEnabled) { + meteringEnabled = false; + } if (!this._isRecording) { this._isRecording = true; - return RNAudioRecorderPlayer.startRecorder(uri, audioSets); + return RNAudioRecorderPlayer.startRecorder(uri, meteringEnabled, audioSets); } return 'Already recording'; }; diff --git a/ios/RNAudioRecorderPlayer.m b/ios/RNAudioRecorderPlayer.m index 72db4fb3..3cca565f 100644 --- a/ios/RNAudioRecorderPlayer.m +++ b/ios/RNAudioRecorderPlayer.m @@ -21,13 +21,13 @@ @implementation RNAudioRecorderPlayer { AVAudioPlayer *audioPlayer; NSTimer *recordTimer; NSTimer *playTimer; + BOOL _meteringEnabled; } double subscriptionDuration = 0.1; - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { NSLog(@"audioPlayerDidFinishPlaying"); NSNumber *duration = [NSNumber numberWithDouble:audioPlayer.duration * 1000]; - NSNumber *currentTime = [NSNumber numberWithDouble:audioPlayer.duration * 1000]; // Send last event then finish it. // NSString* status = [NSString stringWithFormat:@"{\"duration\": \"%@\", \"current_position\": \"%@\"}", [duration stringValue], [currentTime stringValue]]; @@ -46,8 +46,15 @@ - (void)updateRecorderProgress:(NSTimer*) timer { NSNumber *currentTime = [NSNumber numberWithDouble:audioRecorder.currentTime * 1000]; // NSString* status = [NSString stringWithFormat:@"{\"current_position\": \"%@\"}", [currentTime stringValue]]; + NSNumber *currentMetering = [NSNumber numberWithDouble:0]; + if (_meteringEnabled) { + [audioRecorder updateMeters]; + currentMetering = [NSNumber numberWithDouble:[audioRecorder averagePowerForChannel: 0]]; + } + NSDictionary *status = @{ @"current_position" : [currentTime stringValue], + @"current_metering" : [currentMetering stringValue], }; [self sendEventWithName:@"rn-recordback" body:status]; } @@ -64,7 +71,7 @@ - (void)updateProgress:(NSTimer*) timer [audioPlayer stop]; return; } - + // NSString* status = [NSString stringWithFormat:@"{\"duration\": \"%@\", \"current_position\": \"%@\"}", [duration stringValue], [currentTime stringValue]]; NSDictionary *status = @{ @"duration" : [duration stringValue], @@ -116,6 +123,7 @@ - (dispatch_queue_t)methodQueue } RCT_EXPORT_METHOD(startRecorder:(NSString*)path + meteringEnabled:(BOOL)meteringEnabled audioSets: (NSDictionary*)audioSets resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { @@ -125,6 +133,7 @@ - (dispatch_queue_t)methodQueue NSNumber *numberOfChannel = [RCTConvert NSNumber:audioSets[@"AVNumberOfChannelsKeyIOS"]]; NSNumber *avFormat; NSNumber *audioQuality = [RCTConvert NSNumber:audioSets[@"AVEncoderAudioQualityKeyIOS"]]; + _meteringEnabled = meteringEnabled; if ([path isEqualToString:@"DEFAULT"]) { audioFileURL = [NSURL fileURLWithPath:[GetDirectoryOfType_Sound(NSCachesDirectory) stringByAppendingString:@"sound.m4a"]]; @@ -196,11 +205,12 @@ - (dispatch_queue_t)methodQueue initWithURL:audioFileURL settings:audioSettings error:nil]; - + audioRecorder.meteringEnabled = _meteringEnabled; + [audioRecorder setDelegate:self]; [audioRecorder record]; [self startRecorderTimer]; - + NSString *filePath = self->audioFileURL.absoluteString; resolve(filePath); } @@ -271,7 +281,7 @@ - (dispatch_queue_t)methodQueue audioFileURL = [NSURL URLWithString:path]; } } - + NSLog(@"Error %@",error); if (!audioPlayer) { @@ -333,7 +343,7 @@ - (dispatch_queue_t)methodQueue if (playTimer != nil) { [playTimer invalidate]; playTimer = nil; - } + } resolve(@"pause play"); } else { reject(@"audioPlayer pause", @"audioPlayer is not playing", nil); diff --git a/package.json b/package.json index 35d6b5a2..ee95c186 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "2.5.1", "description": "React Native Audio Recorder and Player.", "homepage": "https://github.com/dooboolab/react-native-audio-recorder-player", - "main": "index.js", + "main": "index.ts", "types": "index.d.ts", "postinstall": "dooboolab-welcome postinstall", "scripts": {