@corti/dictation-web 0.0.0-test.571 → 0.0.0-test.571.2
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/dist/bundle.js +37 -12
- package/dist/components/recording-button.d.ts +2 -1
- package/dist/components/recording-button.js +24 -13
- package/dist/components/recording-button.js.map +1 -1
- package/dist/controllers/keybinding-controller.d.ts +1 -0
- package/dist/controllers/keybinding-controller.js +7 -1
- package/dist/controllers/keybinding-controller.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +87 -7
- package/dist/styles/mode-selector.js +3 -1
- package/dist/styles/mode-selector.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/events.d.ts +4 -0
- package/dist/utils/events.js +8 -0
- package/dist/utils/events.js.map +1 -1
- package/dist/utils/keybinding.d.ts +0 -13
- package/dist/utils/keybinding.js +0 -15
- package/dist/utils/keybinding.js.map +1 -1
- package/package.json +1 -1
- package/dist/CortiDictation.d.ts +0 -55
- package/dist/CortiDictation.js +0 -303
- package/dist/CortiDictation.js.map +0 -1
- package/dist/DictationService.d.ts +0 -16
- package/dist/DictationService.js +0 -88
- package/dist/DictationService.js.map +0 -1
- package/dist/RecorderManager.d.ts +0 -25
- package/dist/RecorderManager.js +0 -145
- package/dist/RecorderManager.js.map +0 -1
- package/dist/audioService.d.ts +0 -6
- package/dist/audioService.js +0 -21
- package/dist/audioService.js.map +0 -1
- package/dist/controllers/DictationController.d.ts +0 -35
- package/dist/controllers/DictationController.js +0 -130
- package/dist/controllers/DictationController.js.map +0 -1
- package/dist/controllers/MediaController.d.ts +0 -31
- package/dist/controllers/MediaController.js +0 -99
- package/dist/controllers/MediaController.js.map +0 -1
- package/dist/src/components/audio-visualiser.d.ts +0 -14
- package/dist/src/components/audio-visualiser.js +0 -57
- package/dist/src/components/audio-visualiser.js.map +0 -1
- package/dist/src/components/corti-dictation.d.ts +0 -123
- package/dist/src/components/corti-dictation.js +0 -224
- package/dist/src/components/corti-dictation.js.map +0 -1
- package/dist/src/components/device-selector.d.ts +0 -24
- package/dist/src/components/device-selector.js +0 -106
- package/dist/src/components/device-selector.js.map +0 -1
- package/dist/src/components/language-selector.d.ts +0 -24
- package/dist/src/components/language-selector.js +0 -100
- package/dist/src/components/language-selector.js.map +0 -1
- package/dist/src/components/recording-button.d.ts +0 -37
- package/dist/src/components/recording-button.js +0 -203
- package/dist/src/components/recording-button.js.map +0 -1
- package/dist/src/components/settings-menu.d.ts +0 -16
- package/dist/src/components/settings-menu.js +0 -80
- package/dist/src/components/settings-menu.js.map +0 -1
- package/dist/src/constants.d.ts +0 -4
- package/dist/src/constants.js +0 -37
- package/dist/src/constants.js.map +0 -1
- package/dist/src/contexts/dictation-context.d.ts +0 -97
- package/dist/src/contexts/dictation-context.js +0 -208
- package/dist/src/contexts/dictation-context.js.map +0 -1
- package/dist/src/controllers/DictationController.d.ts +0 -35
- package/dist/src/controllers/DictationController.js +0 -130
- package/dist/src/controllers/DictationController.js.map +0 -1
- package/dist/src/controllers/MediaController.d.ts +0 -31
- package/dist/src/controllers/MediaController.js +0 -99
- package/dist/src/controllers/MediaController.js.map +0 -1
- package/dist/src/icons/icons.d.ts +0 -17
- package/dist/src/icons/icons.js +0 -158
- package/dist/src/icons/icons.js.map +0 -1
- package/dist/src/styles/ComponentStyles.d.ts +0 -2
- package/dist/src/styles/ComponentStyles.js +0 -18
- package/dist/src/styles/ComponentStyles.js.map +0 -1
- package/dist/src/styles/audio-visualiser.d.ts +0 -2
- package/dist/src/styles/audio-visualiser.js +0 -33
- package/dist/src/styles/audio-visualiser.js.map +0 -1
- package/dist/src/styles/buttons.d.ts +0 -2
- package/dist/src/styles/buttons.js +0 -52
- package/dist/src/styles/buttons.js.map +0 -1
- package/dist/src/styles/callout.d.ts +0 -2
- package/dist/src/styles/callout.js +0 -23
- package/dist/src/styles/callout.js.map +0 -1
- package/dist/src/styles/default-theme.d.ts +0 -2
- package/dist/src/styles/default-theme.js +0 -50
- package/dist/src/styles/default-theme.js.map +0 -1
- package/dist/src/styles/recording-button.d.ts +0 -2
- package/dist/src/styles/recording-button.js +0 -8
- package/dist/src/styles/recording-button.js.map +0 -1
- package/dist/src/styles/select.d.ts +0 -2
- package/dist/src/styles/select.js +0 -36
- package/dist/src/styles/select.js.map +0 -1
- package/dist/src/styles/settings-menu.d.ts +0 -2
- package/dist/src/styles/settings-menu.js +0 -34
- package/dist/src/styles/settings-menu.js.map +0 -1
- package/dist/src/types.d.ts +0 -7
- package/dist/src/types.js +0 -2
- package/dist/src/types.js.map +0 -1
- package/dist/src/utils/auth.d.ts +0 -9
- package/dist/src/utils/auth.js +0 -21
- package/dist/src/utils/auth.js.map +0 -1
- package/dist/src/utils/converters.d.ts +0 -4
- package/dist/src/utils/converters.js +0 -8
- package/dist/src/utils/converters.js.map +0 -1
- package/dist/src/utils/devices.d.ts +0 -26
- package/dist/src/utils/devices.js +0 -53
- package/dist/src/utils/devices.js.map +0 -1
- package/dist/src/utils/events.d.ts +0 -44
- package/dist/src/utils/events.js +0 -88
- package/dist/src/utils/events.js.map +0 -1
- package/dist/src/utils/languages.d.ts +0 -7
- package/dist/src/utils/languages.js +0 -29
- package/dist/src/utils/languages.js.map +0 -1
- package/dist/src/utils/media.d.ts +0 -6
- package/dist/src/utils/media.js +0 -39
- package/dist/src/utils/media.js.map +0 -1
- package/dist/src/utils/token.d.ts +0 -13
- package/dist/src/utils/token.js +0 -60
- package/dist/src/utils/token.js.map +0 -1
- package/dist/src/utils/validation.d.ts +0 -1
- package/dist/src/utils/validation.js +0 -7
- package/dist/src/utils/validation.js.map +0 -1
- package/dist/stories/audio-visualiser.stories.d.ts +0 -39
- package/dist/stories/audio-visualiser.stories.js +0 -71
- package/dist/stories/audio-visualiser.stories.js.map +0 -1
- package/dist/stories/corti-dictation.stories.d.ts +0 -27
- package/dist/stories/corti-dictation.stories.js +0 -129
- package/dist/stories/corti-dictation.stories.js.map +0 -1
- package/dist/stories/device-selector.stories.d.ts +0 -18
- package/dist/stories/device-selector.stories.js +0 -84
- package/dist/stories/device-selector.stories.js.map +0 -1
- package/dist/stories/language-selector.stories.d.ts +0 -18
- package/dist/stories/language-selector.stories.js +0 -53
- package/dist/stories/language-selector.stories.js.map +0 -1
- package/dist/stories/recording-button.stories.d.ts +0 -27
- package/dist/stories/recording-button.stories.js +0 -90
- package/dist/stories/recording-button.stories.js.map +0 -1
- package/dist/stories/settings-menu.stories.d.ts +0 -23
- package/dist/stories/settings-menu.stories.js +0 -156
- package/dist/stories/settings-menu.stories.js.map +0 -1
- package/dist/styles/ComponentStyles.d.ts +0 -2
- package/dist/styles/ComponentStyles.js +0 -18
- package/dist/styles/ComponentStyles.js.map +0 -1
- package/dist/styles/default-theme.d.ts +0 -2
- package/dist/styles/default-theme.js +0 -14
- package/dist/styles/default-theme.js.map +0 -1
- package/dist/styles/theme.d.ts +0 -2
- package/dist/styles/theme.js +0 -56
- package/dist/styles/theme.js.map +0 -1
- package/dist/tsconfig.stories.tsbuildinfo +0 -1
- package/dist/utils.d.ts +0 -59
- package/dist/utils.js +0 -179
- package/dist/utils.js.map +0 -1
package/dist/utils.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
/**
|
|
3
|
-
* Returns the localized name of a language given its BCP-47 code.
|
|
4
|
-
*
|
|
5
|
-
* @param languageCode - The BCP-47 language code (e.g. "en")
|
|
6
|
-
* @returns The localized language name (e.g. "English") or the original code if unavailable.
|
|
7
|
-
*/
|
|
8
|
-
export function getLanguageName(languageCode) {
|
|
9
|
-
const userLocale = navigator.language || 'en';
|
|
10
|
-
const displayNames = new Intl.DisplayNames([userLocale], {
|
|
11
|
-
type: 'language',
|
|
12
|
-
});
|
|
13
|
-
const languageName = displayNames.of(languageCode);
|
|
14
|
-
return languageName || languageCode;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Requests access to the microphone.
|
|
18
|
-
*
|
|
19
|
-
* This function checks if the microphone permission is in "prompt" state, then requests
|
|
20
|
-
* access and stops any active tracks immediately. It also logs if permission is already granted.
|
|
21
|
-
*
|
|
22
|
-
* @returns A promise that resolves when the permission request is complete.
|
|
23
|
-
*/
|
|
24
|
-
export async function requestMicAccess() {
|
|
25
|
-
try {
|
|
26
|
-
// Fallback if Permissions API is not available
|
|
27
|
-
if (!navigator.permissions) {
|
|
28
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
29
|
-
stream.getTracks().forEach(track => track.stop());
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const permissionStatus = await navigator.permissions.query({
|
|
33
|
-
// eslint-disable-next-line no-undef
|
|
34
|
-
name: 'microphone',
|
|
35
|
-
});
|
|
36
|
-
if (permissionStatus.state === 'prompt') {
|
|
37
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
38
|
-
stream.getTracks().forEach(track => track.stop());
|
|
39
|
-
}
|
|
40
|
-
else if (permissionStatus.state === 'denied') {
|
|
41
|
-
console.warn('Microphone permission is denied.');
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
console.error('Error checking/requesting microphone permission:', error);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Retrieves available audio input devices.
|
|
50
|
-
*
|
|
51
|
-
* This function uses the mediaDevices API to enumerate devices and filters out those
|
|
52
|
-
* which are audio inputs. In some browsers, you may need to request user media before
|
|
53
|
-
* device labels are populated.
|
|
54
|
-
*
|
|
55
|
-
* @returns A promise that resolves with an object containing:
|
|
56
|
-
* - `devices`: an array of MediaDeviceInfo objects for audio inputs.
|
|
57
|
-
* - `defaultDeviceId`: the deviceId of the first audio input, if available.
|
|
58
|
-
*/
|
|
59
|
-
export async function getAudioDevices() {
|
|
60
|
-
if (!navigator.mediaDevices?.enumerateDevices) {
|
|
61
|
-
console.error('Media devices API not supported.');
|
|
62
|
-
return { devices: [] };
|
|
63
|
-
}
|
|
64
|
-
await requestMicAccess();
|
|
65
|
-
try {
|
|
66
|
-
// Optionally: await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
67
|
-
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
68
|
-
const audioDevices = devices.filter(device => device.kind === 'audioinput');
|
|
69
|
-
const defaultDevice = audioDevices.length > 0 ? audioDevices[0] : undefined;
|
|
70
|
-
return { devices: audioDevices, defaultDevice };
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
console.error('Error enumerating devices:', error);
|
|
74
|
-
return { devices: [] };
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Decodes a JWT token and extracts environment and tenant details from its issuer URL.
|
|
79
|
-
*
|
|
80
|
-
* NOTE: This function is temporarily kept for backward compatibility in return values.
|
|
81
|
-
* The SDK now handles token parsing internally, so this should be removed once we
|
|
82
|
-
* reduce the return results to only include what's necessary.
|
|
83
|
-
*
|
|
84
|
-
* @param token - A JSON Web Token (JWT) string.
|
|
85
|
-
* @returns An object containing:
|
|
86
|
-
* - `environment`: The extracted environment from the issuer URL.
|
|
87
|
-
* - `tenant`: The extracted tenant from the issuer URL.
|
|
88
|
-
* - `accessToken`: The original token string.
|
|
89
|
-
* If the issuer URL doesn't match the expected format, returns undefined.
|
|
90
|
-
*
|
|
91
|
-
* @throws Will throw an error if:
|
|
92
|
-
* - The token format is invalid.
|
|
93
|
-
* - The base64 decoding or URI decoding fails.
|
|
94
|
-
* - The JSON payload is invalid.
|
|
95
|
-
* - The token payload does not contain an issuer (iss) field.
|
|
96
|
-
*/
|
|
97
|
-
export function decodeToken(token) {
|
|
98
|
-
// Validate the token structure (should contain at least header and payload parts)
|
|
99
|
-
const parts = token.split('.');
|
|
100
|
-
if (parts.length < 2) {
|
|
101
|
-
throw new Error('Invalid token format');
|
|
102
|
-
}
|
|
103
|
-
// Retrieve the payload (second part) of the JWT token
|
|
104
|
-
const base64Url = parts[1];
|
|
105
|
-
// Replace URL-safe characters to match standard base64 encoding
|
|
106
|
-
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
107
|
-
// Decode the base64 string into a JSON string
|
|
108
|
-
let jsonPayload;
|
|
109
|
-
try {
|
|
110
|
-
jsonPayload = decodeURIComponent(atob(base64)
|
|
111
|
-
.split('')
|
|
112
|
-
.map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
|
113
|
-
.join(''));
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
throw new Error('Failed to decode token payload');
|
|
117
|
-
}
|
|
118
|
-
// Parse the JSON string to obtain token details
|
|
119
|
-
let tokenDetails;
|
|
120
|
-
try {
|
|
121
|
-
tokenDetails = JSON.parse(jsonPayload);
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
throw new Error('Invalid JSON payload in token');
|
|
125
|
-
}
|
|
126
|
-
// Extract the issuer URL from the token details
|
|
127
|
-
const issuerUrl = tokenDetails.iss;
|
|
128
|
-
if (!issuerUrl) {
|
|
129
|
-
throw new Error('Token payload does not contain an issuer (iss) field');
|
|
130
|
-
}
|
|
131
|
-
// Regex to extract environment and tenant from issuer URL:
|
|
132
|
-
// Expected format: https://keycloak.{environment}.corti.app/realms/{tenant}
|
|
133
|
-
// Note: Unnecessary escapes in character classes have been removed.
|
|
134
|
-
const regex = /^https:\/\/(keycloak|auth)\.([^.]+)\.corti\.app\/realms\/([^/]+)/;
|
|
135
|
-
const match = issuerUrl.match(regex);
|
|
136
|
-
// If the issuer URL matches the expected pattern, return the extracted values along with the token
|
|
137
|
-
if (match) {
|
|
138
|
-
const expiresAt = tokenDetails.exp && typeof tokenDetails.exp === 'number'
|
|
139
|
-
? tokenDetails.exp
|
|
140
|
-
: undefined;
|
|
141
|
-
return {
|
|
142
|
-
environment: match[2],
|
|
143
|
-
tenant: match[3],
|
|
144
|
-
accessToken: token,
|
|
145
|
-
expiresAt,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
export async function getMediaStream(deviceId) {
|
|
150
|
-
if (!deviceId) {
|
|
151
|
-
throw new Error('No device ID provided');
|
|
152
|
-
}
|
|
153
|
-
if (deviceId === 'display_audio') {
|
|
154
|
-
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
155
|
-
audio: true,
|
|
156
|
-
video: true,
|
|
157
|
-
});
|
|
158
|
-
stream.getTracks().forEach(track => {
|
|
159
|
-
if (track.kind === 'video') {
|
|
160
|
-
stream.removeTrack(track);
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
return stream;
|
|
164
|
-
}
|
|
165
|
-
// Get media stream and initialize audio service.
|
|
166
|
-
const constraints = deviceId !== 'default'
|
|
167
|
-
? { audio: { deviceId: { exact: deviceId } } }
|
|
168
|
-
: { audio: true };
|
|
169
|
-
return await navigator.mediaDevices.getUserMedia(constraints);
|
|
170
|
-
}
|
|
171
|
-
export function getErrorMessage(event) {
|
|
172
|
-
try {
|
|
173
|
-
return JSON.parse(event.message);
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
return event?.message || event;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\n/**\n * Returns the localized name of a language given its BCP-47 code.\n *\n * @param languageCode - The BCP-47 language code (e.g. \"en\")\n * @returns The localized language name (e.g. \"English\") or the original code if unavailable.\n */\nexport function getLanguageName(languageCode: string): string {\n const userLocale = navigator.language || 'en';\n const displayNames = new Intl.DisplayNames([userLocale], {\n type: 'language',\n });\n const languageName = displayNames.of(languageCode);\n return languageName || languageCode;\n}\n\n/**\n * Requests access to the microphone.\n *\n * This function checks if the microphone permission is in \"prompt\" state, then requests\n * access and stops any active tracks immediately. It also logs if permission is already granted.\n *\n * @returns A promise that resolves when the permission request is complete.\n */\nexport async function requestMicAccess(): Promise<void> {\n try {\n // Fallback if Permissions API is not available\n if (!navigator.permissions) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach(track => track.stop());\n return;\n }\n\n const permissionStatus = await navigator.permissions.query({\n // eslint-disable-next-line no-undef\n name: 'microphone' as PermissionName,\n });\n\n if (permissionStatus.state === 'prompt') {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach(track => track.stop());\n } else if (permissionStatus.state === 'denied') {\n console.warn('Microphone permission is denied.');\n }\n } catch (error) {\n console.error('Error checking/requesting microphone permission:', error);\n }\n}\n\n/**\n * Retrieves available audio input devices.\n *\n * This function uses the mediaDevices API to enumerate devices and filters out those\n * which are audio inputs. In some browsers, you may need to request user media before\n * device labels are populated.\n *\n * @returns A promise that resolves with an object containing:\n * - `devices`: an array of MediaDeviceInfo objects for audio inputs.\n * - `defaultDeviceId`: the deviceId of the first audio input, if available.\n */\nexport async function getAudioDevices(): Promise<{\n devices: MediaDeviceInfo[];\n defaultDevice?: MediaDeviceInfo;\n}> {\n if (!navigator.mediaDevices?.enumerateDevices) {\n console.error('Media devices API not supported.');\n return { devices: [] };\n }\n\n await requestMicAccess();\n\n try {\n // Optionally: await navigator.mediaDevices.getUserMedia({ audio: true });\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter(device => device.kind === 'audioinput');\n const defaultDevice = audioDevices.length > 0 ? audioDevices[0] : undefined;\n return { devices: audioDevices, defaultDevice };\n } catch (error) {\n console.error('Error enumerating devices:', error);\n return { devices: [] };\n }\n}\n\n/**\n * Decodes a JWT token and extracts environment and tenant details from its issuer URL.\n *\n * NOTE: This function is temporarily kept for backward compatibility in return values.\n * The SDK now handles token parsing internally, so this should be removed once we\n * reduce the return results to only include what's necessary.\n *\n * @param token - A JSON Web Token (JWT) string.\n * @returns An object containing:\n * - `environment`: The extracted environment from the issuer URL.\n * - `tenant`: The extracted tenant from the issuer URL.\n * - `accessToken`: The original token string.\n * If the issuer URL doesn't match the expected format, returns undefined.\n *\n * @throws Will throw an error if:\n * - The token format is invalid.\n * - The base64 decoding or URI decoding fails.\n * - The JSON payload is invalid.\n * - The token payload does not contain an issuer (iss) field.\n */\nexport function decodeToken(token: string) {\n // Validate the token structure (should contain at least header and payload parts)\n const parts = token.split('.');\n if (parts.length < 2) {\n throw new Error('Invalid token format');\n }\n\n // Retrieve the payload (second part) of the JWT token\n const base64Url = parts[1];\n\n // Replace URL-safe characters to match standard base64 encoding\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n\n // Decode the base64 string into a JSON string\n let jsonPayload: string;\n try {\n jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join(''),\n );\n } catch (error) {\n throw new Error('Failed to decode token payload');\n }\n\n // Parse the JSON string to obtain token details\n let tokenDetails: { iss: string; [key: string]: unknown };\n try {\n tokenDetails = JSON.parse(jsonPayload);\n } catch (error) {\n throw new Error('Invalid JSON payload in token');\n }\n\n // Extract the issuer URL from the token details\n const issuerUrl: string = tokenDetails.iss;\n if (!issuerUrl) {\n throw new Error('Token payload does not contain an issuer (iss) field');\n }\n\n // Regex to extract environment and tenant from issuer URL:\n // Expected format: https://keycloak.{environment}.corti.app/realms/{tenant}\n // Note: Unnecessary escapes in character classes have been removed.\n const regex =\n /^https:\\/\\/(keycloak|auth)\\.([^.]+)\\.corti\\.app\\/realms\\/([^/]+)/;\n const match = issuerUrl.match(regex);\n\n // If the issuer URL matches the expected pattern, return the extracted values along with the token\n if (match) {\n const expiresAt = tokenDetails.exp && typeof tokenDetails.exp === 'number'\n ? tokenDetails.exp\n : undefined;\n\n return {\n environment: match[2],\n tenant: match[3],\n accessToken: token,\n expiresAt,\n };\n }\n}\n\nexport async function getMediaStream(deviceId?: string): Promise<MediaStream> {\n if (!deviceId) {\n throw new Error('No device ID provided');\n }\n\n if (deviceId === 'display_audio') {\n const stream = await navigator.mediaDevices.getDisplayMedia({\n audio: true,\n video: true,\n });\n stream.getTracks().forEach(track => {\n if (track.kind === 'video') {\n stream.removeTrack(track);\n }\n });\n return stream;\n }\n\n // Get media stream and initialize audio service.\n const constraints: MediaStreamConstraints =\n deviceId !== 'default'\n ? { audio: { deviceId: { exact: deviceId } } }\n : { audio: true };\n\n return await navigator.mediaDevices.getUserMedia(constraints);\n}\n\nexport function getErrorMessage(event: Error) {\n try {\n return JSON.parse(event.message);\n } catch {\n return event?.message || event;\n }\n}\n"]}
|