@siteed/audio-studio 3.2.0-beta.1 โ 3.2.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 +356 -5
- package/android/src/main/java/net/siteed/audiostudio/AudioStreamDecoder.kt +306 -94
- package/android/src/main/java/net/siteed/audiostudio/AudioStudioModule.kt +39 -6
- package/build/cjs/errors/AudioStreamError.js +9 -0
- package/build/cjs/errors/AudioStreamError.js.map +1 -1
- package/build/cjs/errors/AudioStreamError.test.js +22 -1
- package/build/cjs/errors/AudioStreamError.test.js.map +1 -1
- package/build/cjs/streamAudioData.js +99 -32
- package/build/cjs/streamAudioData.js.map +1 -1
- package/build/cjs/utils/audioProcessing.js +14 -10
- package/build/cjs/utils/audioProcessing.js.map +1 -1
- package/build/esm/errors/AudioStreamError.js +9 -0
- package/build/esm/errors/AudioStreamError.js.map +1 -1
- package/build/esm/errors/AudioStreamError.test.js +22 -1
- package/build/esm/errors/AudioStreamError.test.js.map +1 -1
- package/build/esm/streamAudioData.js +99 -32
- package/build/esm/streamAudioData.js.map +1 -1
- package/build/esm/utils/audioProcessing.js +14 -10
- package/build/esm/utils/audioProcessing.js.map +1 -1
- package/build/types/errors/AudioStreamError.d.ts.map +1 -1
- package/build/types/streamAudioData.d.ts +5 -0
- package/build/types/streamAudioData.d.ts.map +1 -1
- package/build/types/utils/audioProcessing.d.ts +2 -2
- package/build/types/utils/audioProcessing.d.ts.map +1 -1
- package/ios/AudioStreamDecoder.swift +191 -100
- package/ios/AudioStudioModule.swift +48 -9
- package/package.json +163 -146
- package/scripts/README.md +58 -0
- package/src/errors/AudioStreamError.test.ts +29 -2
- package/src/errors/AudioStreamError.ts +14 -0
- package/src/streamAudioData.ts +146 -42
- package/src/utils/audioProcessing.ts +25 -14
- package/android/src/androidTest/assets/chorus.wav +0 -0
- package/android/src/androidTest/assets/jfk.wav +0 -0
- package/android/src/androidTest/assets/osr_us_000_0010_8k.wav +0 -0
- package/android/src/androidTest/assets/recorder_hello_world.wav +0 -0
- package/android/src/androidTest/java/net/siteed/audiostudio/AudioFinalMetadataContractInstrumentedTest.kt +0 -190
- package/android/src/androidTest/java/net/siteed/audiostudio/AudioProcessorInstrumentedTest.kt +0 -197
- package/android/src/androidTest/java/net/siteed/audiostudio/AudioRecorderInstrumentedTest.kt +0 -487
- package/android/src/androidTest/java/net/siteed/audiostudio/AudioRecorderPerformanceInstrumentedTest.kt +0 -250
- package/android/src/androidTest/java/net/siteed/audiostudio/OpusRangeDecodeRegressionInstrumentedTest.kt +0 -186
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/AudioFocusStrategyIntegrationTest.kt +0 -332
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/BufferDurationIntegrationTest.kt +0 -324
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/CompressedOnlyOutputTest.kt +0 -253
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/DeviceDisconnectionFallbackTest.kt +0 -218
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/EventEmissionIntervalTest.kt +0 -120
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/M4aFormatTest.kt +0 -345
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/OutputControlIntegrationTest.kt +0 -340
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/PcmStreamingDurationTest.kt +0 -252
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/README.md +0 -95
- package/android/src/androidTest/java/net/siteed/audiostudio/integration/run_integration_tests.sh +0 -43
- package/android/src/test/java/net/siteed/audiostudio/AndroidCallStateTest.kt +0 -37
- package/android/src/test/java/net/siteed/audiostudio/AndroidEventEmitterTest.kt +0 -28
- package/android/src/test/java/net/siteed/audiostudio/AudioFileHandlerTest.kt +0 -279
- package/android/src/test/java/net/siteed/audiostudio/AudioFocusStrategyTest.kt +0 -249
- package/android/src/test/java/net/siteed/audiostudio/AudioFormatTest.kt +0 -151
- package/android/src/test/java/net/siteed/audiostudio/AudioFormatUtilsTest.kt +0 -273
- package/android/src/test/java/net/siteed/audiostudio/DeviceDisconnectionFallbackUnitTest.kt +0 -140
- package/android/src/test/java/net/siteed/audiostudio/InterruptionAutoResumePolicyTest.kt +0 -49
- package/android/src/test/resources/chorus.wav +0 -0
- package/android/src/test/resources/generate_test_audio.py +0 -94
- package/android/src/test/resources/jfk.wav +0 -0
- package/android/src/test/resources/osr_us_000_0010_8k.wav +0 -0
- package/android/src/test/resources/recorder_hello_world.wav +0 -0
- package/ios/AudioStudioTests/AudioFileHandlerTests.swift +0 -338
- package/ios/AudioStudioTests/AudioFormatUtilsTests.swift +0 -331
- package/ios/AudioStudioTests/AudioStreamDecoderTests.swift +0 -128
- package/ios/AudioStudioTests/AudioTestHelpers.swift +0 -130
- package/ios/AudioStudioTests/CompressedOnlyOutputTests.swift +0 -334
- package/ios/AudioStudioTests/EventEmissionIntervalTests.swift +0 -105
- package/ios/AudioStudioTests/Info.plist +0 -22
- package/ios/AudioStudioTests/README.md +0 -39
- package/ios/AudioStudioTests/SimpleAudioTest.swift +0 -98
- package/ios/AudioStudioTests/TestAudioGenerator.swift +0 -75
- package/ios/tests/README.md +0 -41
- package/ios/tests/integration/buffer_and_fallback_test.swift +0 -178
- package/ios/tests/integration/buffer_duration_test.swift +0 -185
- package/ios/tests/integration/compressed_only_output_test.swift +0 -271
- package/ios/tests/integration/output_control_test.swift +0 -322
- package/ios/tests/integration/run_integration_tests.sh +0 -37
- package/ios/tests/opus_support_test_macos.swift +0 -154
- package/ios/tests/standalone/audio_processing_test.swift +0 -144
- package/ios/tests/standalone/audio_recording_test.swift +0 -277
- package/ios/tests/standalone/audio_streaming_test.swift +0 -249
- package/ios/tests/standalone/standalone_test.swift +0 -144
package/package.json
CHANGED
|
@@ -1,147 +1,164 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
2
|
+
"name": "@siteed/audio-studio",
|
|
3
|
+
"version": "3.2.0",
|
|
4
|
+
"description": "Comprehensive audio processing library for React Native and Expo with recording, analysis, visualization, and streaming capabilities across iOS, Android, and web",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"main": "./build/cjs/index.js",
|
|
8
|
+
"module": "./build/esm/index.js",
|
|
9
|
+
"types": "./build/types/index.d.ts",
|
|
10
|
+
"expo": {
|
|
11
|
+
"plugin": "./app.plugin.js"
|
|
12
|
+
},
|
|
13
|
+
"author": "Arthur Breton <abreton@siteed.net> (https://github.com/deeeed)",
|
|
14
|
+
"homepage": "https://github.com/deeeed/audiolab/blob/main/packages/audio-studio/README.md",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/deeeed/audiolab.git",
|
|
18
|
+
"directory": "packages/audio-studio"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/deeeed/audiolab/issues"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"react-native",
|
|
25
|
+
"expo",
|
|
26
|
+
"audio",
|
|
27
|
+
"recording",
|
|
28
|
+
"audio-analysis",
|
|
29
|
+
"audio-processing",
|
|
30
|
+
"audio-visualization",
|
|
31
|
+
"waveform",
|
|
32
|
+
"spectrogram",
|
|
33
|
+
"mel-spectrogram",
|
|
34
|
+
"mfcc",
|
|
35
|
+
"audio-features",
|
|
36
|
+
"audio-compression",
|
|
37
|
+
"opus",
|
|
38
|
+
"aac",
|
|
39
|
+
"pcm",
|
|
40
|
+
"wav",
|
|
41
|
+
"cross-platform",
|
|
42
|
+
"background-recording",
|
|
43
|
+
"audio-trimming",
|
|
44
|
+
"dual-stream"
|
|
45
|
+
],
|
|
46
|
+
"files": [
|
|
47
|
+
"src",
|
|
48
|
+
"android",
|
|
49
|
+
"ios",
|
|
50
|
+
"cpp",
|
|
51
|
+
"plugin",
|
|
52
|
+
"app.plugin.js",
|
|
53
|
+
"LICENSE",
|
|
54
|
+
"CHANGELOG.md",
|
|
55
|
+
"generated",
|
|
56
|
+
"expo-module.config.json",
|
|
57
|
+
"README.md",
|
|
58
|
+
"package.json",
|
|
59
|
+
"*.podspec",
|
|
60
|
+
"prebuilt",
|
|
61
|
+
"build",
|
|
62
|
+
"!ios/build",
|
|
63
|
+
"!android/build",
|
|
64
|
+
"!android/gradle",
|
|
65
|
+
"!android/gradlew",
|
|
66
|
+
"!android/gradlew.bat",
|
|
67
|
+
"!android/local.properties",
|
|
68
|
+
"!ios/AudioStudioTests",
|
|
69
|
+
"!ios/AudioStudioTests/**",
|
|
70
|
+
"!ios/tests",
|
|
71
|
+
"!ios/tests/**",
|
|
72
|
+
"!android/src/androidTest",
|
|
73
|
+
"!android/src/androidTest/**",
|
|
74
|
+
"!android/src/test",
|
|
75
|
+
"!android/src/test/**",
|
|
76
|
+
"!android/src/test/resources",
|
|
77
|
+
"!android/src/test/resources/**",
|
|
78
|
+
"!**/__tests__",
|
|
79
|
+
"!**/__fixtures__",
|
|
80
|
+
"!**/__mocks__",
|
|
81
|
+
"!**/.*"
|
|
82
|
+
],
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build:wasm": "bash scripts/build-wasm.sh",
|
|
85
|
+
"build": "rimraf build && yarn build:types && yarn build:cjs && yarn build:esm && yarn build:plugin && cp -r prebuilt/ build/cjs/prebuilt && cp -r prebuilt/ build/esm/prebuilt",
|
|
86
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
87
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
88
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
89
|
+
"build:plugin": "tsc --project plugin/tsconfig.json && cp plugin/build/index.js plugin/build/index.cjs",
|
|
90
|
+
"build:plugin:dev": "expo-module build plugin",
|
|
91
|
+
"build:dev": "expo-module build",
|
|
92
|
+
"clean": "expo-module clean && rimraf build plugin/build",
|
|
93
|
+
"lint": "expo-module lint",
|
|
94
|
+
"lint:fix": "expo-module lint --fix",
|
|
95
|
+
"test": "expo-module test",
|
|
96
|
+
"test:android": "yarn test:android:unit && yarn test:android:instrumented",
|
|
97
|
+
"test:android:unit": "cd ../../apps/playground/android && ./gradlew :siteed-audio-studio:test",
|
|
98
|
+
"test:android:instrumented": "cd ../../apps/playground/android && ./gradlew :siteed-audio-studio:connectedAndroidTest",
|
|
99
|
+
"test:android:unit:watch": "cd ../../apps/playground/android && ./gradlew :siteed-audio-studio:test --continuous",
|
|
100
|
+
"test:ios": "cd ../../apps/playground/ios && xcodebuild -workspace AudioDevPlayground.xcworkspace -scheme AudioDevPlayground -destination 'generic/platform=iOS Simulator' build",
|
|
101
|
+
"test:coverage": "cd ../../apps/playground/android && ./gradlew :siteed-audio-studio:jacocoTestReport",
|
|
102
|
+
"typecheck": "tsc --noEmit",
|
|
103
|
+
"docgen": "typedoc src/index.ts --plugin typedoc-plugin-markdown --readme none --out ../../documentation_site/docs/api-reference/API && node ../../scripts/escape-mdx-generics.js ../../documentation_site/docs/api-reference",
|
|
104
|
+
"prepare": "yarn build && node -e \"require('fs').renameSync('./plugin/build/index.d.ts', './plugin/build/index.d.cts')\"",
|
|
105
|
+
"prepublishOnly.disabled": "expo-module prepublishOnly",
|
|
106
|
+
"expo-module": "expo-module",
|
|
107
|
+
"open:ios": "open -a \"Xcode\" ../../apps/playground/ios",
|
|
108
|
+
"open:android": "open -a \"Android Studio\" ../../apps/playground/android",
|
|
109
|
+
"size": "bundle-size && size-limit",
|
|
110
|
+
"release": "./publish.sh",
|
|
111
|
+
"agent:test:unit": "yarn test:android:unit",
|
|
112
|
+
"agent:test:integration": "yarn test:android:instrumented",
|
|
113
|
+
"agent:compilation:check": "yarn typecheck && yarn build",
|
|
114
|
+
"android": "cd ../../apps/playground && yarn android",
|
|
115
|
+
"android:launch": "cd ../../apps/playground && yarn android:launch",
|
|
116
|
+
"validate:stream-long": "node scripts/validate-stream-long.mjs",
|
|
117
|
+
"android:device": "cd ../../apps/playground && yarn android:device",
|
|
118
|
+
"android:device:launch": "cd ../../apps/playground && yarn android:device:launch",
|
|
119
|
+
"summarize:stream-long": "node scripts/summarize-stream-long.mjs"
|
|
120
|
+
},
|
|
121
|
+
"devDependencies": {
|
|
122
|
+
"@expo/config-plugins": "~54.0.0",
|
|
123
|
+
"@expo/npm-proofread": "^1.0.1",
|
|
124
|
+
"@siteed/publisher": "^0.4.18",
|
|
125
|
+
"@size-limit/preset-big-lib": "^11.1.4",
|
|
126
|
+
"@types/jest": "^29.5.12",
|
|
127
|
+
"@types/node": "^20.12.7",
|
|
128
|
+
"@types/react": "~19.0.10",
|
|
129
|
+
"@typescript-eslint/eslint-plugin": "^7.7.0",
|
|
130
|
+
"@typescript-eslint/parser": "^7.7.0",
|
|
131
|
+
"bundle-size": "^1.1.5",
|
|
132
|
+
"eslint": "^8.56.0",
|
|
133
|
+
"eslint-config-prettier": "^9.1.0",
|
|
134
|
+
"eslint-config-universe": "^12.0.0",
|
|
135
|
+
"eslint-plugin-import": "^2.29.1",
|
|
136
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
137
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
138
|
+
"eslint-plugin-react": "^7.34.1",
|
|
139
|
+
"expo": "^54.0.0",
|
|
140
|
+
"expo-module-scripts": "^4.1.7",
|
|
141
|
+
"expo-modules-core": "~3.0.0",
|
|
142
|
+
"jest": "^29.7.0",
|
|
143
|
+
"prettier": "^3.2.5",
|
|
144
|
+
"react": "19.2.0",
|
|
145
|
+
"react-native": "0.83.6",
|
|
146
|
+
"rimraf": "^6.0.1",
|
|
147
|
+
"size-limit": "^11.1.4",
|
|
148
|
+
"ts-jest": "^29.2.6",
|
|
149
|
+
"ts-node": "^10.9.2",
|
|
150
|
+
"typedoc": "^0.27.4",
|
|
151
|
+
"typedoc-plugin-markdown": "~4.4.2",
|
|
152
|
+
"typescript": "~5.8.3"
|
|
153
|
+
},
|
|
154
|
+
"peerDependencies": {
|
|
155
|
+
"@expo/config-plugins": ">=7.0.0",
|
|
156
|
+
"expo": ">=52.0.0",
|
|
157
|
+
"react": "*",
|
|
158
|
+
"react-native": "*"
|
|
159
|
+
},
|
|
160
|
+
"publishConfig": {
|
|
161
|
+
"access": "public",
|
|
162
|
+
"registry": "https://registry.npmjs.org"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Test Scripts
|
|
2
|
+
|
|
3
|
+
This directory contains unified test scripts for expo-audio-studio.
|
|
4
|
+
|
|
5
|
+
## run_tests.sh
|
|
6
|
+
|
|
7
|
+
A unified test runner that can execute tests for both Android and iOS platforms.
|
|
8
|
+
|
|
9
|
+
### Usage
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
./scripts/run_tests.sh [platform] [type]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Parameters
|
|
16
|
+
|
|
17
|
+
- **platform**: Which platform to test
|
|
18
|
+
- `all` (default) - Run tests for both platforms
|
|
19
|
+
- `android` - Run Android tests only
|
|
20
|
+
- `ios` - Run iOS tests only
|
|
21
|
+
|
|
22
|
+
- **type**: Which type of tests to run
|
|
23
|
+
- `all` (default) - Run all test types
|
|
24
|
+
- `unit` - Run unit tests (Android only)
|
|
25
|
+
- `instrumented` - Run instrumented tests (Android only)
|
|
26
|
+
- `standalone` - Run standalone Swift tests (iOS only)
|
|
27
|
+
|
|
28
|
+
### Examples
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Run all tests for both platforms
|
|
32
|
+
./scripts/run_tests.sh
|
|
33
|
+
|
|
34
|
+
# Run Android tests only
|
|
35
|
+
./scripts/run_tests.sh android
|
|
36
|
+
|
|
37
|
+
# Run Android unit tests only
|
|
38
|
+
./scripts/run_tests.sh android unit
|
|
39
|
+
|
|
40
|
+
# Run iOS tests only
|
|
41
|
+
./scripts/run_tests.sh ios
|
|
42
|
+
|
|
43
|
+
# Run all tests explicitly
|
|
44
|
+
./scripts/run_tests.sh all all
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Requirements
|
|
48
|
+
|
|
49
|
+
- **Android**: Requires Android SDK and a connected device/emulator for instrumented tests
|
|
50
|
+
- **iOS**: Requires Swift compiler (comes with Xcode)
|
|
51
|
+
|
|
52
|
+
### Output
|
|
53
|
+
|
|
54
|
+
The script provides colored output:
|
|
55
|
+
- ๐งช Test execution progress
|
|
56
|
+
- โ
Success messages in green
|
|
57
|
+
- โ Failure messages in red
|
|
58
|
+
- Summary of tests passed/failed
|
|
@@ -11,13 +11,18 @@ describe('AudioStreamError', () => {
|
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
it('maps native FILE_NOT_FOUND code', () => {
|
|
14
|
-
const mapped = mapStreamError({
|
|
14
|
+
const mapped = mapStreamError({
|
|
15
|
+
code: 'FILE_NOT_FOUND',
|
|
16
|
+
message: 'gone',
|
|
17
|
+
})
|
|
15
18
|
expect(mapped.code).toBe('ERR_AUDIO_STREAM_FILE_NOT_FOUND')
|
|
16
19
|
expect(mapped.recoverable).toBe(false)
|
|
17
20
|
})
|
|
18
21
|
|
|
19
22
|
it('maps unsupported codec text', () => {
|
|
20
|
-
const mapped = mapStreamError(
|
|
23
|
+
const mapped = mapStreamError(
|
|
24
|
+
new Error('No suitable codec for audio/opus')
|
|
25
|
+
)
|
|
21
26
|
expect(mapped.code).toBe('ERR_AUDIO_STREAM_UNSUPPORTED_FORMAT')
|
|
22
27
|
})
|
|
23
28
|
|
|
@@ -30,11 +35,33 @@ describe('AudioStreamError', () => {
|
|
|
30
35
|
expect(mapped.recoverable).toBe(true)
|
|
31
36
|
})
|
|
32
37
|
|
|
38
|
+
it('maps backpressure timeout as recoverable', () => {
|
|
39
|
+
const mapped = mapStreamError({
|
|
40
|
+
code: 'ERR_AUDIO_STREAM_BACKPRESSURE_TIMEOUT',
|
|
41
|
+
message: 'ack timed out',
|
|
42
|
+
})
|
|
43
|
+
expect(mapped.code).toBe('ERR_AUDIO_STREAM_BACKPRESSURE_TIMEOUT')
|
|
44
|
+
expect(mapped.recoverable).toBe(true)
|
|
45
|
+
})
|
|
46
|
+
|
|
33
47
|
it('falls back to UNKNOWN', () => {
|
|
34
48
|
const mapped = mapStreamError({})
|
|
35
49
|
expect(mapped.code).toBe('ERR_AUDIO_STREAM_UNKNOWN')
|
|
36
50
|
})
|
|
37
51
|
|
|
52
|
+
it('warns when native returns an unknown audio stream code', () => {
|
|
53
|
+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
54
|
+
const mapped = mapStreamError({
|
|
55
|
+
code: 'ERR_AUDIO_STREAM_FOOBAR',
|
|
56
|
+
message: 'new native code',
|
|
57
|
+
})
|
|
58
|
+
expect(mapped.code).toBe('ERR_AUDIO_STREAM_UNKNOWN')
|
|
59
|
+
expect(warn).toHaveBeenCalledWith(
|
|
60
|
+
'[AudioStreamError] Unknown native audio stream error code: ERR_AUDIO_STREAM_FOOBAR'
|
|
61
|
+
)
|
|
62
|
+
warn.mockRestore()
|
|
63
|
+
})
|
|
64
|
+
|
|
38
65
|
it('preserves nativeCode and nativeMessage', () => {
|
|
39
66
|
const mapped = mapStreamError({
|
|
40
67
|
code: 'WEIRD_NATIVE_CODE',
|
|
@@ -80,6 +80,14 @@ function getNativeCode(err: unknown): string | undefined {
|
|
|
80
80
|
return undefined
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
function isUnknownAudioStreamCode(raw: string | undefined): boolean {
|
|
84
|
+
if (!raw) return false
|
|
85
|
+
return (
|
|
86
|
+
raw.toUpperCase().startsWith('ERR_AUDIO_STREAM_') &&
|
|
87
|
+
normalizeCode(raw) === null
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
83
91
|
function normalizeCode(raw: string | undefined): AudioStreamErrorCode | null {
|
|
84
92
|
if (!raw) return null
|
|
85
93
|
const upper = raw.toUpperCase()
|
|
@@ -151,6 +159,12 @@ export function mapStreamError(
|
|
|
151
159
|
const nativeCode = getNativeCode(err)
|
|
152
160
|
const lower = nativeMessage.toLowerCase()
|
|
153
161
|
|
|
162
|
+
if (isUnknownAudioStreamCode(nativeCode)) {
|
|
163
|
+
console.warn(
|
|
164
|
+
`[AudioStreamError] Unknown native audio stream error code: ${nativeCode}`
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
154
168
|
let code =
|
|
155
169
|
normalizeCode(nativeCode) ??
|
|
156
170
|
normalizeCode(nativeMessage) ??
|