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.
- package/ios/NosniaAudioRecorder.mm +63 -36
- package/package.json +1 -1
|
@@ -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
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
97
|
-
|
|
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
|
|
271
|
+
AVAudioSessionCategoryOptions categoryOptions = AVAudioSessionCategoryOptionDefaultToSpeaker |
|
|
272
|
+
AVAudioSessionCategoryOptionAllowBluetooth |
|
|
273
|
+
AVAudioSessionCategoryOptionAllowAirPlay;
|
|
254
274
|
BOOL categorySuccess = [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
|
|
255
|
-
withOptions:
|
|
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
|
|
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