@siteed/expo-audio-stream 1.15.1 → 1.16.0
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/CHANGELOG.md +7 -1
- package/ios/AudioStreamManager.swift +18 -11
- package/package.json +1 -1
- package/plugin/build/index.js +11 -10
- package/plugin/src/index.ts +16 -13
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
## [1.16.0] - 2025-02-17
|
|
12
|
+
### Changed
|
|
13
|
+
- fix(expo-audio-stream): prevent adding iOS background modes when disabled ([5c9d09c](https://github.com/deeeed/expo-audio-stream/commit/5c9d09c715ce008fe72177431224a10f5fd7a865))
|
|
14
|
+
- fix(ios): replace CallKit with AVAudioSession for phone call detection ([e3b664b](https://github.com/deeeed/expo-audio-stream/commit/e3b664ba6925c379b323ded5fc408154e5f092c6))
|
|
15
|
+
- chore(expo-audio-stream): release @siteed/expo-audio-stream@1.15.1 ([cbc3d10](https://github.com/deeeed/expo-audio-stream/commit/cbc3d10661a415811f1fe46cb3acaf63451a9df9))
|
|
11
16
|
## [1.15.1] - 2025-02-17
|
|
12
17
|
### Changed
|
|
13
18
|
- fix: restore Opus compression support on iOS (#122) ([06614e6](https://github.com/deeeed/expo-audio-stream/commit/06614e6d96fa2a6af56edf0fd2e2b3966e13c8f7))
|
|
@@ -124,7 +129,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
124
129
|
- Feature: Audio features extraction during recording.
|
|
125
130
|
- Feature: Consistent WAV PCM recording format across all platforms.
|
|
126
131
|
|
|
127
|
-
[unreleased]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-stream@1.
|
|
132
|
+
[unreleased]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-stream@1.16.0...HEAD
|
|
133
|
+
[1.16.0]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-stream@1.15.1...@siteed/expo-audio-stream@1.16.0
|
|
128
134
|
[1.15.1]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-stream@1.15.0...@siteed/expo-audio-stream@1.15.1
|
|
129
135
|
[1.15.0]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-stream@1.14.2...@siteed/expo-audio-stream@1.15.0
|
|
130
136
|
[1.14.2]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-stream@1.14.1...@siteed/expo-audio-stream@1.14.2
|
|
@@ -11,7 +11,6 @@ import Accelerate
|
|
|
11
11
|
import UIKit
|
|
12
12
|
import MediaPlayer
|
|
13
13
|
import UserNotifications
|
|
14
|
-
import CallKit
|
|
15
14
|
|
|
16
15
|
// Helper to convert to little-endian byte array
|
|
17
16
|
extension UInt32 {
|
|
@@ -566,17 +565,26 @@ class AudioStreamManager: NSObject {
|
|
|
566
565
|
return status
|
|
567
566
|
}
|
|
568
567
|
|
|
568
|
+
/// Detects if a phone call is active without using CallKit.
|
|
569
|
+
/// We avoid CallKit because its usage prevents apps from being available in China's App Store.
|
|
570
|
+
/// This is a workaround that uses AVAudioSession to detect phone calls instead.
|
|
571
|
+
private func isPhoneCallActive() -> Bool {
|
|
572
|
+
let audioSession = AVAudioSession.sharedInstance()
|
|
573
|
+
return audioSession.isOtherAudioPlaying &&
|
|
574
|
+
audioSession.secondaryAudioShouldBeSilencedHint &&
|
|
575
|
+
audioSession.currentRoute.outputs.contains { $0.portType == .builtInReceiver }
|
|
576
|
+
}
|
|
577
|
+
|
|
569
578
|
/// Starts a new audio recording with the specified settings and interval.
|
|
570
579
|
/// - Parameters:
|
|
571
580
|
/// - settings: The recording settings to use.
|
|
572
581
|
/// - intervalMilliseconds: The interval in milliseconds for emitting audio data.
|
|
573
582
|
/// - Returns: A StartRecordingResult object if recording starts successfully, or nil otherwise.
|
|
574
583
|
func startRecording(settings: RecordingSettings, intervalMilliseconds: Int) -> StartRecordingResult? {
|
|
575
|
-
// Check for active call
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
delegate?.audioStreamManager(self, didFailWithError: "Cannot start recording during an active call")
|
|
584
|
+
// Check for active call using the new method
|
|
585
|
+
if isPhoneCallActive() {
|
|
586
|
+
Logger.debug("Cannot start recording during an active phone call")
|
|
587
|
+
delegate?.audioStreamManager(self, didFailWithError: "Cannot start recording during an active phone call")
|
|
580
588
|
return nil
|
|
581
589
|
}
|
|
582
590
|
|
|
@@ -922,11 +930,10 @@ class AudioStreamManager: NSObject {
|
|
|
922
930
|
|
|
923
931
|
/// Resumes the current audio recording.
|
|
924
932
|
func resumeRecording() {
|
|
925
|
-
// Check for active call
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
delegate?.audioStreamManager(self, didFailWithError: "Cannot resume recording during an active call")
|
|
933
|
+
// Check for active call using the new method
|
|
934
|
+
if isPhoneCallActive() {
|
|
935
|
+
Logger.debug("Cannot resume recording during an active phone call")
|
|
936
|
+
delegate?.audioStreamManager(self, didFailWithError: "Cannot resume recording during an active phone call")
|
|
930
937
|
return
|
|
931
938
|
}
|
|
932
939
|
|
package/package.json
CHANGED
package/plugin/build/index.js
CHANGED
|
@@ -37,13 +37,14 @@ const withRecordingPermission = (config, props) => {
|
|
|
37
37
|
config.modResults['NSUserNotificationAlertStyle'] = 'alert';
|
|
38
38
|
}
|
|
39
39
|
const existingBackgroundModes = config.modResults.UIBackgroundModes || [];
|
|
40
|
-
// Only add background modes if explicitly enabled
|
|
41
|
-
if (options.iosBackgroundModes?.useAudio &&
|
|
42
|
-
enableBackgroundAudio &&
|
|
40
|
+
// Only add background modes if explicitly enabled and set to true
|
|
41
|
+
if (options.iosBackgroundModes?.useAudio === true &&
|
|
42
|
+
enableBackgroundAudio === true &&
|
|
43
43
|
!existingBackgroundModes.includes('audio')) {
|
|
44
44
|
existingBackgroundModes.push('audio');
|
|
45
45
|
}
|
|
46
|
-
if (options.iosBackgroundModes?.useVoIP
|
|
46
|
+
if (options.iosBackgroundModes?.useVoIP === true &&
|
|
47
|
+
enablePhoneStateHandling === true) {
|
|
47
48
|
if (!existingBackgroundModes.includes('voip')) {
|
|
48
49
|
existingBackgroundModes.push('voip');
|
|
49
50
|
}
|
|
@@ -55,22 +56,22 @@ const withRecordingPermission = (config, props) => {
|
|
|
55
56
|
config.modResults.UIRequiredDeviceCapabilities =
|
|
56
57
|
existingCapabilities;
|
|
57
58
|
}
|
|
58
|
-
// Add additional background modes if
|
|
59
|
-
if (options.iosBackgroundModes?.useProcessing) {
|
|
59
|
+
// Add additional background modes only if explicitly set to true
|
|
60
|
+
if (options.iosBackgroundModes?.useProcessing === true) {
|
|
60
61
|
if (!existingBackgroundModes.includes('processing')) {
|
|
61
62
|
existingBackgroundModes.push('processing');
|
|
62
63
|
}
|
|
63
64
|
// Add processing info if enabled
|
|
64
65
|
config.modResults.BGTaskSchedulerPermittedIdentifiers = [
|
|
65
|
-
'com.siteed.audiostream.processing'
|
|
66
|
+
'com.siteed.audiostream.processing',
|
|
66
67
|
];
|
|
67
68
|
}
|
|
68
|
-
if (options.iosBackgroundModes?.useLocation) {
|
|
69
|
+
if (options.iosBackgroundModes?.useLocation === true) {
|
|
69
70
|
if (!existingBackgroundModes.includes('location')) {
|
|
70
71
|
existingBackgroundModes.push('location');
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
|
-
if (options.iosBackgroundModes?.useExternalAccessory) {
|
|
74
|
+
if (options.iosBackgroundModes?.useExternalAccessory === true) {
|
|
74
75
|
if (!existingBackgroundModes.includes('external-accessory')) {
|
|
75
76
|
existingBackgroundModes.push('external-accessory');
|
|
76
77
|
}
|
|
@@ -84,7 +85,7 @@ const withRecordingPermission = (config, props) => {
|
|
|
84
85
|
if (options.iosConfig?.allowBackgroundAudioControls) {
|
|
85
86
|
config.modResults.UIBackgroundModes = [
|
|
86
87
|
...existingBackgroundModes,
|
|
87
|
-
'remote-notification'
|
|
88
|
+
'remote-notification',
|
|
88
89
|
];
|
|
89
90
|
config.modResults.MPNowPlayingInfoPropertyPlaybackRate = true;
|
|
90
91
|
}
|
package/plugin/src/index.ts
CHANGED
|
@@ -17,7 +17,7 @@ function debugLog(message: string, ...args: unknown[]): void {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
interface AudioStreamPluginOptions {
|
|
20
|
-
enablePhoneStateHandling?: boolean
|
|
20
|
+
enablePhoneStateHandling?: boolean // Controls READ_PHONE_STATE permission
|
|
21
21
|
enableNotifications?: boolean
|
|
22
22
|
enableBackgroundAudio?: boolean
|
|
23
23
|
iosBackgroundModes?: {
|
|
@@ -38,7 +38,7 @@ const withRecordingPermission: ConfigPlugin<AudioStreamPluginOptions> = (
|
|
|
38
38
|
props: AudioStreamPluginOptions | void
|
|
39
39
|
) => {
|
|
40
40
|
const options: AudioStreamPluginOptions = {
|
|
41
|
-
enablePhoneStateHandling: true,
|
|
41
|
+
enablePhoneStateHandling: true, // Default to true for backward compatibility
|
|
42
42
|
enableNotifications: true,
|
|
43
43
|
enableBackgroundAudio: true,
|
|
44
44
|
iosBackgroundModes: {
|
|
@@ -75,16 +75,19 @@ const withRecordingPermission: ConfigPlugin<AudioStreamPluginOptions> = (
|
|
|
75
75
|
const existingBackgroundModes =
|
|
76
76
|
config.modResults.UIBackgroundModes || []
|
|
77
77
|
|
|
78
|
-
// Only add background modes if explicitly enabled
|
|
78
|
+
// Only add background modes if explicitly enabled and set to true
|
|
79
79
|
if (
|
|
80
|
-
options.iosBackgroundModes?.useAudio &&
|
|
81
|
-
enableBackgroundAudio &&
|
|
80
|
+
options.iosBackgroundModes?.useAudio === true &&
|
|
81
|
+
enableBackgroundAudio === true &&
|
|
82
82
|
!existingBackgroundModes.includes('audio')
|
|
83
83
|
) {
|
|
84
84
|
existingBackgroundModes.push('audio')
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
if (
|
|
87
|
+
if (
|
|
88
|
+
options.iosBackgroundModes?.useVoIP === true &&
|
|
89
|
+
enablePhoneStateHandling === true
|
|
90
|
+
) {
|
|
88
91
|
if (!existingBackgroundModes.includes('voip')) {
|
|
89
92
|
existingBackgroundModes.push('voip')
|
|
90
93
|
}
|
|
@@ -97,24 +100,24 @@ const withRecordingPermission: ConfigPlugin<AudioStreamPluginOptions> = (
|
|
|
97
100
|
existingCapabilities
|
|
98
101
|
}
|
|
99
102
|
|
|
100
|
-
// Add additional background modes if
|
|
101
|
-
if (options.iosBackgroundModes?.useProcessing) {
|
|
103
|
+
// Add additional background modes only if explicitly set to true
|
|
104
|
+
if (options.iosBackgroundModes?.useProcessing === true) {
|
|
102
105
|
if (!existingBackgroundModes.includes('processing')) {
|
|
103
106
|
existingBackgroundModes.push('processing')
|
|
104
107
|
}
|
|
105
108
|
// Add processing info if enabled
|
|
106
109
|
config.modResults.BGTaskSchedulerPermittedIdentifiers = [
|
|
107
|
-
'com.siteed.audiostream.processing'
|
|
110
|
+
'com.siteed.audiostream.processing',
|
|
108
111
|
]
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
if (options.iosBackgroundModes?.useLocation) {
|
|
114
|
+
if (options.iosBackgroundModes?.useLocation === true) {
|
|
112
115
|
if (!existingBackgroundModes.includes('location')) {
|
|
113
116
|
existingBackgroundModes.push('location')
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
119
|
|
|
117
|
-
if (options.iosBackgroundModes?.useExternalAccessory) {
|
|
120
|
+
if (options.iosBackgroundModes?.useExternalAccessory === true) {
|
|
118
121
|
if (!existingBackgroundModes.includes('external-accessory')) {
|
|
119
122
|
existingBackgroundModes.push('external-accessory')
|
|
120
123
|
}
|
|
@@ -122,7 +125,7 @@ const withRecordingPermission: ConfigPlugin<AudioStreamPluginOptions> = (
|
|
|
122
125
|
|
|
123
126
|
// Configure background processing info if enabled
|
|
124
127
|
if (options.iosConfig?.backgroundProcessingTitle) {
|
|
125
|
-
config.modResults.BGProcessingTaskTitle =
|
|
128
|
+
config.modResults.BGProcessingTaskTitle =
|
|
126
129
|
options.iosConfig.backgroundProcessingTitle
|
|
127
130
|
}
|
|
128
131
|
|
|
@@ -130,7 +133,7 @@ const withRecordingPermission: ConfigPlugin<AudioStreamPluginOptions> = (
|
|
|
130
133
|
if (options.iosConfig?.allowBackgroundAudioControls) {
|
|
131
134
|
config.modResults.UIBackgroundModes = [
|
|
132
135
|
...existingBackgroundModes,
|
|
133
|
-
'remote-notification'
|
|
136
|
+
'remote-notification',
|
|
134
137
|
]
|
|
135
138
|
config.modResults.MPNowPlayingInfoPropertyPlaybackRate = true
|
|
136
139
|
}
|