@scr2em/capacitor-plugin-recorder 0.0.7 → 0.0.8
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.
|
@@ -3,7 +3,6 @@ package com.capacitor.recorderplayer;
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.media.AudioAttributes;
|
|
5
5
|
import android.media.AudioManager;
|
|
6
|
-
import android.media.AudioRecordingConfiguration;
|
|
7
6
|
import android.media.MediaPlayer;
|
|
8
7
|
import android.media.MediaRecorder;
|
|
9
8
|
import android.os.Build;
|
|
@@ -11,8 +10,6 @@ import android.os.Handler;
|
|
|
11
10
|
import android.os.Looper;
|
|
12
11
|
import android.util.Log;
|
|
13
12
|
|
|
14
|
-
import java.util.List;
|
|
15
|
-
|
|
16
13
|
import java.io.File;
|
|
17
14
|
import java.io.IOException;
|
|
18
15
|
import java.util.HashMap;
|
|
@@ -219,22 +216,13 @@ public class RecorderPlayer {
|
|
|
219
216
|
}
|
|
220
217
|
|
|
221
218
|
private boolean isMicrophoneInUse() {
|
|
222
|
-
// Check if device is in a call mode
|
|
219
|
+
// Check if device is in a call mode (phone call or VoIP like Zoom)
|
|
223
220
|
int audioMode = audioManager.getMode();
|
|
224
221
|
if (audioMode == AudioManager.MODE_IN_CALL || audioMode == AudioManager.MODE_IN_COMMUNICATION) {
|
|
225
222
|
Log.d(TAG, "Microphone in use: device is in call mode (" + audioMode + ")");
|
|
226
223
|
return true;
|
|
227
224
|
}
|
|
228
225
|
|
|
229
|
-
// On Android 7.0+, check for active recording configurations from other apps
|
|
230
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
231
|
-
List<AudioRecordingConfiguration> activeConfigs = audioManager.getActiveRecordingConfigurations();
|
|
232
|
-
if (activeConfigs != null && !activeConfigs.isEmpty()) {
|
|
233
|
-
Log.d(TAG, "Microphone in use: " + activeConfigs.size() + " active recording configuration(s) found");
|
|
234
|
-
return true;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
226
|
return false;
|
|
239
227
|
}
|
|
240
228
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import AVFoundation
|
|
3
|
+
import CallKit
|
|
3
4
|
|
|
4
5
|
public enum RecordingStatus: String {
|
|
5
6
|
case recording = "recording"
|
|
@@ -137,6 +138,7 @@ public struct PreparePlayResult {
|
|
|
137
138
|
|
|
138
139
|
@objc public class RecorderPlayer: NSObject {
|
|
139
140
|
private var recordingSession: AVAudioSession?
|
|
141
|
+
private let callObserver = CXCallObserver()
|
|
140
142
|
|
|
141
143
|
// Multiple recorders support
|
|
142
144
|
private var recorders: [String: RecorderState] = [:]
|
|
@@ -173,7 +175,40 @@ public struct PreparePlayResult {
|
|
|
173
175
|
return "player-\(playerIdCounter)-\(Int(Date().timeIntervalSince1970 * 1000))"
|
|
174
176
|
}
|
|
175
177
|
|
|
178
|
+
private func isMicrophoneInUse() -> Bool {
|
|
179
|
+
// Check for active phone or VoIP calls using CallKit
|
|
180
|
+
let activeCalls = callObserver.calls.filter { !$0.hasEnded }
|
|
181
|
+
if !activeCalls.isEmpty {
|
|
182
|
+
print("Microphone in use: \(activeCalls.count) active call(s) detected")
|
|
183
|
+
return true
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Check if another app is using the microphone by examining audio session
|
|
187
|
+
if let session = recordingSession {
|
|
188
|
+
// Check if another app is playing audio (might indicate a call)
|
|
189
|
+
if session.isOtherAudioPlaying {
|
|
190
|
+
// Only block if the current route suggests a call is happening
|
|
191
|
+
let currentRoute = session.currentRoute
|
|
192
|
+
for output in currentRoute.outputs {
|
|
193
|
+
// These port types typically indicate a call is active
|
|
194
|
+
if output.portType == .builtInReceiver ||
|
|
195
|
+
output.portType == .bluetoothHFP {
|
|
196
|
+
print("Microphone in use: audio route suggests active call")
|
|
197
|
+
return true
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return false
|
|
204
|
+
}
|
|
205
|
+
|
|
176
206
|
public func startRecord(path: String?) throws -> StartRecordResult {
|
|
207
|
+
// Check if microphone is already in use by another app
|
|
208
|
+
if isMicrophoneInUse() {
|
|
209
|
+
throw NSError(domain: "RecorderPlayer", code: 1, userInfo: [NSLocalizedDescriptionKey: "Microphone is currently in use by another application"])
|
|
210
|
+
}
|
|
211
|
+
|
|
177
212
|
// Use Documents directory (matches Capacitor's Directory.Data on iOS)
|
|
178
213
|
let dataDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
|
179
214
|
|