nosnia-audio-recorder 0.9.11 → 0.9.14

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.
@@ -50,51 +50,69 @@ RCT_EXPORT_MODULE(NosniaAudioRecorder)
50
50
  }
51
51
 
52
52
  - (void)startProgressTimer {
53
+ // Invalidate existing timer
53
54
  if (_progressTimer) {
54
55
  [_progressTimer invalidate];
56
+ _progressTimer = nil;
55
57
  }
56
58
 
57
59
  NSLog(@"[NosniaAudioRecorder] Starting progress timer");
58
60
 
59
- // Send initial duration event immediately
60
- if (_audioRecorder && _isRecording) {
61
- dispatch_async(dispatch_get_main_queue(), ^{
62
- [self sendEventWithName:@"onRecordingProgress"
63
- body:@{
64
- @"duration": @(0.0),
65
- @"isRecording": @(self->_audioRecorder.isRecording)
66
- }];
67
- });
61
+ // Ensure timer is created on main thread and added to main run loop
62
+ dispatch_async(dispatch_get_main_queue(), ^{
63
+ // Send initial duration event
64
+ [self sendEventWithName:@"onRecordingProgress"
65
+ body:@{
66
+ @"duration": @(0.0),
67
+ @"isRecording": @(self->_audioRecorder && self->_audioRecorder.isRecording)
68
+ }];
69
+
70
+ // Create and schedule timer on main run loop
71
+ self->_progressTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
72
+ target:self
73
+ selector:@selector(onProgressTimerTick:)
74
+ userInfo:nil
75
+ repeats:YES];
76
+
77
+ // Ensure timer fires on main run loop
78
+ [[NSRunLoop mainRunLoop] addTimer:self->_progressTimer forMode:NSRunLoopCommonModes];
79
+
80
+ NSLog(@"[NosniaAudioRecorder] Progress timer scheduled on main thread");
81
+ });
82
+ }
83
+
84
+ - (void)onProgressTimerTick:(NSTimer *)timer {
85
+ if (!_audioRecorder || !_isRecording) {
86
+ [self stopProgressTimer];
87
+ return;
68
88
  }
69
89
 
70
- _progressTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
71
- repeats:YES
72
- block:^(NSTimer * _Nonnull timer) {
73
- if (self->_audioRecorder && self->_isRecording) {
74
- // Update meters to ensure accurate currentTime reading
75
- [self->_audioRecorder updateMeters];
76
-
77
- // Use the recorder's currentTime directly - this is the reliable way
78
- double durationMs = self->_audioRecorder.currentTime * 1000.0;
79
-
80
- NSLog(@"[NosniaAudioRecorder] Duration: %.0f ms (currentTime: %.4f seconds)",
81
- durationMs, self->_audioRecorder.currentTime);
82
-
83
- dispatch_async(dispatch_get_main_queue(), ^{
84
- [self sendEventWithName:@"onRecordingProgress"
85
- body:@{
86
- @"duration": @(durationMs),
87
- @"isRecording": @(self->_audioRecorder.isRecording)
88
- }];
89
- });
90
- }
91
- }];
90
+ // Update meters to ensure accurate currentTime reading
91
+ [_audioRecorder updateMeters];
92
+
93
+ // Use the recorder's currentTime directly
94
+ double durationMs = _audioRecorder.currentTime * 1000.0;
95
+
96
+ NSLog(@"[NosniaAudioRecorder] Duration: %.0f ms (currentTime: %.4f seconds)",
97
+ durationMs, _audioRecorder.currentTime);
98
+
99
+ dispatch_async(dispatch_get_main_queue(), ^{
100
+ [self sendEventWithName:@"onRecordingProgress"
101
+ body:@{
102
+ @"duration": @(durationMs),
103
+ @"isRecording": @(self->_audioRecorder.isRecording)
104
+ }];
105
+ });
92
106
  }
93
107
 
94
108
  - (void)stopProgressTimer {
95
109
  if (_progressTimer) {
96
- [_progressTimer invalidate];
97
- _progressTimer = nil;
110
+ dispatch_async(dispatch_get_main_queue(), ^{
111
+ if (self->_progressTimer) {
112
+ [self->_progressTimer invalidate];
113
+ self->_progressTimer = nil;
114
+ }
115
+ });
98
116
  }
99
117
  }
100
118
 
@@ -250,9 +268,11 @@ RCT_EXPORT_METHOD(startRecording:(NSDictionary *)options
250
268
  // Set audio category - use PlayAndRecord for better simulator/device compatibility
251
269
  // This works reliably on both real devices and simulators
252
270
  NSError *categoryError = nil;
253
- AVAudioSessionCategoryOptions options = AVAudioSessionCategoryOptionDefaultToSpeaker;
271
+ AVAudioSessionCategoryOptions categoryOptions = AVAudioSessionCategoryOptionDefaultToSpeaker |
272
+ AVAudioSessionCategoryOptionAllowBluetooth |
273
+ AVAudioSessionCategoryOptionAllowAirPlay;
254
274
  BOOL categorySuccess = [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
255
- withOptions:options
275
+ withOptions:categoryOptions
256
276
  error:&categoryError];
257
277
  if (!categorySuccess || categoryError) {
258
278
  NSString *msg = categoryError ? categoryError.description : @"Failed to set audio category";
@@ -260,7 +280,7 @@ RCT_EXPORT_METHOD(startRecording:(NSDictionary *)options
260
280
  reject(@"AUDIO_SESSION_ERROR", msg, categoryError);
261
281
  return;
262
282
  }
263
- NSLog(@"[NosniaAudioRecorder] Audio category set to PlayAndRecord with DefaultToSpeaker");
283
+ NSLog(@"[NosniaAudioRecorder] Audio category set to PlayAndRecord with multiple options");
264
284
 
265
285
  // Set audio mode to default for recording
266
286
  NSError *modeError = nil;
@@ -336,6 +356,13 @@ RCT_EXPORT_METHOD(startRecording:(NSDictionary *)options
336
356
  NSError *recordStartError = nil;
337
357
  BOOL recordStarted = NO;
338
358
 
359
+ // CRITICAL: Ensure audio session is active BEFORE attempting to record
360
+ // In Release builds, this is NOT automatically done by the system
361
+ AVAudioSession *audioSession = [AVAudioSession sharedInstance];
362
+ NSError *preActivateError = nil;
363
+ BOOL preActivateSuccess = [audioSession setActive:YES error:&preActivateError];
364
+ NSLog(@"[NosniaAudioRecorder] Pre-activation check: success=%d, error=%@", preActivateSuccess, preActivateError);
365
+
339
366
  // Try to prepare recorder first
340
367
  NSLog(@"[NosniaAudioRecorder] Preparing to record with settings: %@", _audioRecorder.settings);
341
368
  NSLog(@"[NosniaAudioRecorder] Recording URL: %@", _recordingURL);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nosnia-audio-recorder",
3
- "version": "0.9.11",
3
+ "version": "0.9.14",
4
4
  "description": "This is a modern audio recorder which actually works cross platform",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",