@pipecat-ai/client-react 0.3.5 → 0.4.1
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/README.md +66 -1
- package/dist/index.d.ts +68 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +232 -66
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +230 -68
- package/dist/index.module.js.map +1 -1
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -93,17 +93,58 @@ Creates a new `<video>` element that renders either the bot or local participant
|
|
|
93
93
|
/>
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
+
### RTVIClientCamToggle
|
|
97
|
+
|
|
98
|
+
This is a stateful headless component and exposes the user's camEnabled state and an `onClick` handler to toggle the state.
|
|
99
|
+
|
|
100
|
+
#### Props
|
|
101
|
+
|
|
102
|
+
- `onCamEnabledChanged(enabled: boolean)` (function, optional): Triggered when the user's camEnabled state changes
|
|
103
|
+
- `disabled` (boolean, optional): Disables the cam toggle
|
|
104
|
+
|
|
105
|
+
```jsx
|
|
106
|
+
<RTVIClientCamToggle>
|
|
107
|
+
{({ disabled, isCamEnabled, onClick }) => (
|
|
108
|
+
<button disabled={disabled} onClick={onClick}>
|
|
109
|
+
{isCamEnabled ? "Turn off" : "Turn on"} camera
|
|
110
|
+
</button>
|
|
111
|
+
)}
|
|
112
|
+
</RTVIClientCamToggle>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### RTVIClientMicToggle
|
|
116
|
+
|
|
117
|
+
This is a stateful headless component and exposes the user's micEnabled state and an `onClick` handler to toggle the state.
|
|
118
|
+
|
|
119
|
+
#### Props
|
|
120
|
+
|
|
121
|
+
- `onMicEnabledChanged(enabled: boolean)` (function, optional): Triggered when the user's micEnabled state changes
|
|
122
|
+
- `disabled` (boolean, optional): Disables the mic toggle
|
|
123
|
+
|
|
124
|
+
```jsx
|
|
125
|
+
<RTVIClientMicToggle>
|
|
126
|
+
{({ disabled, isMicEnabled, onClick }) => (
|
|
127
|
+
<button disabled={disabled} onClick={onClick}>
|
|
128
|
+
{isMicEnabled ? "Mute" : "Unmute"} microphone
|
|
129
|
+
</button>
|
|
130
|
+
)}
|
|
131
|
+
</RTVIClientMicToggle>
|
|
132
|
+
```
|
|
133
|
+
|
|
96
134
|
### VoiceVisualizer
|
|
97
135
|
|
|
98
136
|
Renders a visual representation of audio input levels on a `<canvas>` element.
|
|
99
|
-
The visualization consists of
|
|
137
|
+
The visualization consists of vertical bars.
|
|
100
138
|
|
|
101
139
|
#### Props
|
|
102
140
|
|
|
103
141
|
- `participantType` (string, required): The participant type to visualize audio for.
|
|
104
142
|
- `backgroundColor` (string, optional): The background color of the canvas. Default: 'transparent'.
|
|
105
143
|
- `barColor` (string, optional): The color of the audio level bars. Default: 'black'.
|
|
144
|
+
- `barCount` (number, optional): The amount of bars to render. Default: 5
|
|
106
145
|
- `barGap` (number, optional): The gap between bars in pixels. Default: 12.
|
|
146
|
+
- `barLineCap` ('round' | 'square', optional): The line cap for each bar. Default: 'round'
|
|
147
|
+
- `barOrigin` ('bottom' | 'center' | 'top', optional): The origin from where the bars grow to full height. Default: 'center'
|
|
107
148
|
- `barWidth` (number, optional): The width of each bar in pixels. Default: 30.
|
|
108
149
|
- `barMaxHeight` (number, optional): The maximum height at full volume of each bar in pixels. Default: 120.
|
|
109
150
|
|
|
@@ -157,6 +198,30 @@ function EventListener() {
|
|
|
157
198
|
}
|
|
158
199
|
```
|
|
159
200
|
|
|
201
|
+
### useRTVIClientCamControl
|
|
202
|
+
|
|
203
|
+
Allows to control the user's camera state.
|
|
204
|
+
|
|
205
|
+
```jsx
|
|
206
|
+
import { useRTVIClientCamControl } from "@pipecat-ai/client-react";
|
|
207
|
+
|
|
208
|
+
function CustomCamToggle() {
|
|
209
|
+
const { enableCam, isCamEnabled } = useRTVIClientCamControl();
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### useRTVIClientMicControl
|
|
214
|
+
|
|
215
|
+
Allows to control the user's microphone state.
|
|
216
|
+
|
|
217
|
+
```jsx
|
|
218
|
+
import { useRTVIClientMicControl } from "@pipecat-ai/client-react";
|
|
219
|
+
|
|
220
|
+
function CustomMicToggle() {
|
|
221
|
+
const { enableMic, isMicEnabled } = useRTVIClientMicControl();
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
160
225
|
### useRTVIClientMediaDevices
|
|
161
226
|
|
|
162
227
|
Manage and list available media devices.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RTVIClient, RTVIEvent, RTVIEventHandler, Tracks, TransportState } from "@pipecat-ai/client-js";
|
|
2
2
|
import { Provider } from "jotai/react";
|
|
3
|
-
import { JSX } from "react/jsx-runtime";
|
|
4
3
|
import React from "react";
|
|
4
|
+
import { JSX } from "react/jsx-runtime";
|
|
5
5
|
interface Props {
|
|
6
6
|
client: RTVIClient;
|
|
7
7
|
jotaiStore?: React.ComponentProps<typeof Provider>["store"];
|
|
@@ -16,6 +16,69 @@ export const RTVIClientAudio: {
|
|
|
16
16
|
(): JSX.Element;
|
|
17
17
|
displayName: string;
|
|
18
18
|
};
|
|
19
|
+
export const useRTVIClientTransportState: () => TransportState;
|
|
20
|
+
/**
|
|
21
|
+
* Hook to control camera state
|
|
22
|
+
*/
|
|
23
|
+
export const useRTVIClientCamControl: () => {
|
|
24
|
+
enableCam: (enabled: boolean) => void;
|
|
25
|
+
isCamEnabled: boolean;
|
|
26
|
+
};
|
|
27
|
+
interface RTVIClientCamToggleProps {
|
|
28
|
+
/**
|
|
29
|
+
* Callback fired when camera state changes
|
|
30
|
+
*/
|
|
31
|
+
onCamEnabledChanged?: (enabled: boolean) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Optional prop to disable the cam toggle.
|
|
34
|
+
* When disabled, changes are not applied to the client.
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Render prop that provides state and handlers to the children
|
|
40
|
+
*/
|
|
41
|
+
children: (props: {
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
isCamEnabled: boolean;
|
|
44
|
+
onClick: () => void;
|
|
45
|
+
}) => React.ReactNode;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Headless component for controlling camera state
|
|
49
|
+
*/
|
|
50
|
+
export const RTVIClientCamToggle: React.FC<RTVIClientCamToggleProps>;
|
|
51
|
+
/**
|
|
52
|
+
* Hook to control microphone state
|
|
53
|
+
*/
|
|
54
|
+
export const useRTVIClientMicControl: () => {
|
|
55
|
+
enableMic: (enabled: boolean) => void;
|
|
56
|
+
isMicEnabled: boolean;
|
|
57
|
+
};
|
|
58
|
+
interface RTVIClientMicToggleProps {
|
|
59
|
+
/**
|
|
60
|
+
* Callback fired when microphone state changes
|
|
61
|
+
*/
|
|
62
|
+
onMicEnabledChanged?: (enabled: boolean) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Optional prop to disable the mic toggle.
|
|
65
|
+
* When disabled, changes are not applied to the client.
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
disabled?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Render prop that provides state and handlers to the children
|
|
71
|
+
*/
|
|
72
|
+
children: (props: {
|
|
73
|
+
disabled?: boolean;
|
|
74
|
+
isMicEnabled: boolean;
|
|
75
|
+
onClick: () => void;
|
|
76
|
+
}) => React.ReactNode;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Headless component for controlling microphone state
|
|
80
|
+
*/
|
|
81
|
+
export const RTVIClientMicToggle: React.FC<RTVIClientMicToggleProps>;
|
|
19
82
|
interface RTVIClientVideoInterface {
|
|
20
83
|
aspectRatio: number;
|
|
21
84
|
height: number;
|
|
@@ -54,14 +117,16 @@ export const useRTVIClientMediaDevices: () => {
|
|
|
54
117
|
updateMic: (id: string) => void;
|
|
55
118
|
updateSpeaker: (id: string) => void;
|
|
56
119
|
};
|
|
57
|
-
export const useRTVIClientTransportState: () => TransportState;
|
|
58
120
|
type _ParticipantType1 = Parameters<typeof useRTVIClientMediaTrack>[1];
|
|
59
121
|
interface _Props2 {
|
|
60
122
|
backgroundColor?: string;
|
|
61
123
|
barColor?: string;
|
|
124
|
+
barCount?: number;
|
|
62
125
|
barGap?: number;
|
|
63
|
-
|
|
126
|
+
barLineCap?: "round" | "square";
|
|
64
127
|
barMaxHeight?: number;
|
|
128
|
+
barOrigin?: "top" | "bottom" | "center";
|
|
129
|
+
barWidth?: number;
|
|
65
130
|
participantType: _ParticipantType1;
|
|
66
131
|
}
|
|
67
132
|
export const VoiceVisualizer: React.FC<_Props2>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;
|
|
1
|
+
{"mappings":"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","sources":["client-react/src/src/RTVIClientProvider.tsx","client-react/src/src/useRTVIClient.ts","client-react/src/src/useRTVIClientEvent.ts","client-react/src/src/useRTVIClientMediaTrack.ts","client-react/src/src/RTVIClientAudio.tsx","client-react/src/src/useRTVIClientTransportState.ts","client-react/src/src/useRTVIClientCamControl.ts","client-react/src/src/RTVIClientCamToggle.tsx","client-react/src/src/useRTVIClientMicControl.ts","client-react/src/src/RTVIClientMicToggle.tsx","client-react/src/src/useMergedRef.ts","client-react/src/src/RTVIClientVideo.tsx","client-react/src/src/useRTVIClientMediaDevices.ts","client-react/src/src/VoiceVisualizer.tsx","client-react/src/src/index.ts","client-react/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClientAudio } from \"./RTVIClientAudio\";\nimport { RTVIClientCamToggle } from \"./RTVIClientCamToggle\";\nimport { RTVIClientMicToggle } from \"./RTVIClientMicToggle\";\nimport { RTVIClientProvider } from \"./RTVIClientProvider\";\nimport { RTVIClientVideo } from \"./RTVIClientVideo\";\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaDevices } from \"./useRTVIClientMediaDevices\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\n\nexport {\n RTVIClientAudio,\n RTVIClientCamToggle,\n RTVIClientMicToggle,\n RTVIClientProvider,\n RTVIClientVideo,\n useRTVIClient,\n useRTVIClientCamControl,\n useRTVIClientEvent,\n useRTVIClientMediaDevices,\n useRTVIClientMediaTrack,\n useRTVIClientMicControl,\n useRTVIClientTransportState,\n VoiceVisualizer,\n};\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|
package/dist/index.js
CHANGED
|
@@ -15,12 +15,16 @@ function $parcel$interopDefault(a) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
$parcel$export(module.exports, "RTVIClientAudio", () => $e6a9aa6ceb34e585$export$ba1245f7cbf3ae02);
|
|
18
|
+
$parcel$export(module.exports, "RTVIClientCamToggle", () => $e7a27a30474b270e$export$156c26e16246ae3e);
|
|
19
|
+
$parcel$export(module.exports, "RTVIClientMicToggle", () => $8a175691955798a2$export$bf1c2c9ca877628d);
|
|
18
20
|
$parcel$export(module.exports, "RTVIClientProvider", () => $0befa35d025c789a$export$4a4ae2d5dc96782);
|
|
19
21
|
$parcel$export(module.exports, "RTVIClientVideo", () => $c1952f9ddec789e5$export$d090a384943608eb);
|
|
20
22
|
$parcel$export(module.exports, "useRTVIClient", () => $8ee07494475a7fa7$export$31a5f6a22c9b8fba);
|
|
23
|
+
$parcel$export(module.exports, "useRTVIClientCamControl", () => $affd351738e2f16c$export$46099a7ec2fe8ac5);
|
|
21
24
|
$parcel$export(module.exports, "useRTVIClientEvent", () => $8a6b68ebf0332682$export$33a6ac53b8f02625);
|
|
22
25
|
$parcel$export(module.exports, "useRTVIClientMediaDevices", () => $01bcacdf0a25e20c$export$652c54907b83a48d);
|
|
23
26
|
$parcel$export(module.exports, "useRTVIClientMediaTrack", () => $e5be552b22401c66$export$7c03381e0d26a6c3);
|
|
27
|
+
$parcel$export(module.exports, "useRTVIClientMicControl", () => $b5946020fafb75c5$export$805915964ad7bc25);
|
|
24
28
|
$parcel$export(module.exports, "useRTVIClientTransportState", () => $6b6c1a9f794236bd$export$599fa01283bd4ece);
|
|
25
29
|
$parcel$export(module.exports, "VoiceVisualizer", () => $a1dfa75b13e6bb9b$export$59bf27bd43679db6);
|
|
26
30
|
/**
|
|
@@ -125,18 +129,18 @@ const $e5be552b22401c66$export$7c03381e0d26a6c3 = (trackType, participantType)=>
|
|
|
125
129
|
const oldTrack = get(atom);
|
|
126
130
|
if (oldTrack?.id === track.id) return;
|
|
127
131
|
set(atom, track);
|
|
128
|
-
}, [
|
|
129
|
-
participantType,
|
|
130
|
-
track,
|
|
131
|
-
trackType
|
|
132
|
-
]));
|
|
132
|
+
}, []));
|
|
133
133
|
(0, $8a6b68ebf0332682$export$33a6ac53b8f02625)((0, $5Zyvw$pipecataiclientjs.RTVIEvent).TrackStarted, (0, $5Zyvw$react.useCallback)((track, participant)=>{
|
|
134
134
|
updateTrack(track, track.kind, Boolean(participant?.local));
|
|
135
|
-
}, [
|
|
135
|
+
}, [
|
|
136
|
+
updateTrack
|
|
137
|
+
]));
|
|
136
138
|
(0, $8a6b68ebf0332682$export$33a6ac53b8f02625)((0, $5Zyvw$pipecataiclientjs.RTVIEvent).ScreenTrackStarted, (0, $5Zyvw$react.useCallback)((track, participant)=>{
|
|
137
139
|
const trackType = track.kind === "audio" ? "screenAudio" : "screenVideo";
|
|
138
140
|
updateTrack(track, trackType, Boolean(participant?.local));
|
|
139
|
-
}, [
|
|
141
|
+
}, [
|
|
142
|
+
updateTrack
|
|
143
|
+
]));
|
|
140
144
|
(0, $5Zyvw$react.useEffect)(()=>{
|
|
141
145
|
if (!client) return;
|
|
142
146
|
const tracks = client.tracks();
|
|
@@ -186,6 +190,128 @@ $e6a9aa6ceb34e585$export$ba1245f7cbf3ae02.displayName = "RTVIClientAudio";
|
|
|
186
190
|
|
|
187
191
|
|
|
188
192
|
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Copyright (c) 2024, Daily.
|
|
196
|
+
*
|
|
197
|
+
* SPDX-License-Identifier: BSD-2-Clause
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
const $6b6c1a9f794236bd$var$transportStateAtom = (0, $5Zyvw$jotai.atom)("disconnected");
|
|
202
|
+
const $6b6c1a9f794236bd$export$599fa01283bd4ece = ()=>{
|
|
203
|
+
const [transportState, setTransportState] = (0, $5Zyvw$jotai.useAtom)($6b6c1a9f794236bd$var$transportStateAtom);
|
|
204
|
+
(0, $8a6b68ebf0332682$export$33a6ac53b8f02625)((0, $5Zyvw$pipecataiclientjs.RTVIEvent).TransportStateChanged, setTransportState);
|
|
205
|
+
return transportState;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
const $affd351738e2f16c$export$46099a7ec2fe8ac5 = ()=>{
|
|
210
|
+
const client = (0, $8ee07494475a7fa7$export$31a5f6a22c9b8fba)();
|
|
211
|
+
const [isCamEnabled, setIsCamEnabled] = (0, $5Zyvw$react.useState)(client?.isCamEnabled ?? false);
|
|
212
|
+
const transportState = (0, $6b6c1a9f794236bd$export$599fa01283bd4ece)();
|
|
213
|
+
// Sync component state with client state initially
|
|
214
|
+
(0, $5Zyvw$react.useEffect)(()=>{
|
|
215
|
+
if (!client || transportState !== "initialized" || typeof client.isCamEnabled !== "boolean") return;
|
|
216
|
+
setIsCamEnabled(client.isCamEnabled);
|
|
217
|
+
}, [
|
|
218
|
+
client,
|
|
219
|
+
transportState
|
|
220
|
+
]);
|
|
221
|
+
const enableCam = (0, $5Zyvw$react.useCallback)((enabled)=>{
|
|
222
|
+
setIsCamEnabled(enabled);
|
|
223
|
+
client?.enableCam?.(enabled);
|
|
224
|
+
}, [
|
|
225
|
+
client
|
|
226
|
+
]);
|
|
227
|
+
return {
|
|
228
|
+
enableCam: enableCam,
|
|
229
|
+
isCamEnabled: isCamEnabled
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
const $e7a27a30474b270e$export$156c26e16246ae3e = ({ onCamEnabledChanged: onCamEnabledChanged, disabled: disabled = false, children: children })=>{
|
|
235
|
+
const { isCamEnabled: isCamEnabled, enableCam: enableCam } = (0, $affd351738e2f16c$export$46099a7ec2fe8ac5)();
|
|
236
|
+
const handleToggleCam = (0, $5Zyvw$react.useCallback)(()=>{
|
|
237
|
+
if (disabled) return;
|
|
238
|
+
const newEnabledState = !isCamEnabled;
|
|
239
|
+
enableCam(newEnabledState);
|
|
240
|
+
onCamEnabledChanged?.(newEnabledState);
|
|
241
|
+
}, [
|
|
242
|
+
disabled,
|
|
243
|
+
enableCam,
|
|
244
|
+
isCamEnabled,
|
|
245
|
+
onCamEnabledChanged
|
|
246
|
+
]);
|
|
247
|
+
return (0, $5Zyvw$reactjsxruntime.jsx)((0, $5Zyvw$reactjsxruntime.Fragment), {
|
|
248
|
+
children: children({
|
|
249
|
+
isCamEnabled: isCamEnabled,
|
|
250
|
+
onClick: handleToggleCam,
|
|
251
|
+
disabled: disabled
|
|
252
|
+
})
|
|
253
|
+
});
|
|
254
|
+
};
|
|
255
|
+
var $e7a27a30474b270e$export$2e2bcd8739ae039 = $e7a27a30474b270e$export$156c26e16246ae3e;
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
const $b5946020fafb75c5$export$805915964ad7bc25 = ()=>{
|
|
264
|
+
const client = (0, $8ee07494475a7fa7$export$31a5f6a22c9b8fba)();
|
|
265
|
+
const [isMicEnabled, setIsMicEnabled] = (0, $5Zyvw$react.useState)(client?.isMicEnabled ?? false);
|
|
266
|
+
const transportState = (0, $6b6c1a9f794236bd$export$599fa01283bd4ece)();
|
|
267
|
+
// Sync component state with client state initially
|
|
268
|
+
(0, $5Zyvw$react.useEffect)(()=>{
|
|
269
|
+
if (!client || transportState !== "initialized" || typeof client.isMicEnabled !== "boolean") return;
|
|
270
|
+
setIsMicEnabled(client.isMicEnabled);
|
|
271
|
+
}, [
|
|
272
|
+
client,
|
|
273
|
+
transportState
|
|
274
|
+
]);
|
|
275
|
+
const enableMic = (0, $5Zyvw$react.useCallback)((enabled)=>{
|
|
276
|
+
setIsMicEnabled(enabled);
|
|
277
|
+
client?.enableMic?.(enabled);
|
|
278
|
+
}, [
|
|
279
|
+
client
|
|
280
|
+
]);
|
|
281
|
+
return {
|
|
282
|
+
enableMic: enableMic,
|
|
283
|
+
isMicEnabled: isMicEnabled
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
const $8a175691955798a2$export$bf1c2c9ca877628d = ({ onMicEnabledChanged: onMicEnabledChanged, disabled: disabled = false, children: children })=>{
|
|
289
|
+
const { enableMic: enableMic, isMicEnabled: isMicEnabled } = (0, $b5946020fafb75c5$export$805915964ad7bc25)();
|
|
290
|
+
const handleToggleMic = (0, $5Zyvw$react.useCallback)(()=>{
|
|
291
|
+
if (disabled) return;
|
|
292
|
+
const newEnabledState = !isMicEnabled;
|
|
293
|
+
enableMic(newEnabledState);
|
|
294
|
+
onMicEnabledChanged?.(newEnabledState);
|
|
295
|
+
}, [
|
|
296
|
+
disabled,
|
|
297
|
+
enableMic,
|
|
298
|
+
isMicEnabled,
|
|
299
|
+
onMicEnabledChanged
|
|
300
|
+
]);
|
|
301
|
+
return (0, $5Zyvw$reactjsxruntime.jsx)((0, $5Zyvw$reactjsxruntime.Fragment), {
|
|
302
|
+
children: children({
|
|
303
|
+
isMicEnabled: isMicEnabled,
|
|
304
|
+
onClick: handleToggleMic,
|
|
305
|
+
disabled: disabled
|
|
306
|
+
})
|
|
307
|
+
});
|
|
308
|
+
};
|
|
309
|
+
var $8a175691955798a2$export$2e2bcd8739ae039 = $8a175691955798a2$export$bf1c2c9ca877628d;
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
189
315
|
/**
|
|
190
316
|
* Copyright (c) 2024, Daily.
|
|
191
317
|
*
|
|
@@ -334,6 +460,7 @@ $c1952f9ddec789e5$export$d090a384943608eb.displayName = "RTVIClientVideo";
|
|
|
334
460
|
|
|
335
461
|
|
|
336
462
|
|
|
463
|
+
|
|
337
464
|
const $01bcacdf0a25e20c$var$availableMicsAtom = (0, $5Zyvw$jotai.atom)([]);
|
|
338
465
|
const $01bcacdf0a25e20c$var$availableCamsAtom = (0, $5Zyvw$jotai.atom)([]);
|
|
339
466
|
const $01bcacdf0a25e20c$var$availableSpeakersAtom = (0, $5Zyvw$jotai.atom)([]);
|
|
@@ -348,6 +475,25 @@ const $01bcacdf0a25e20c$export$652c54907b83a48d = ()=>{
|
|
|
348
475
|
const selectedCam = (0, $5Zyvw$jotai.useAtomValue)($01bcacdf0a25e20c$var$selectedCamAtom);
|
|
349
476
|
const selectedMic = (0, $5Zyvw$jotai.useAtomValue)($01bcacdf0a25e20c$var$selectedMicAtom);
|
|
350
477
|
const selectedSpeaker = (0, $5Zyvw$jotai.useAtomValue)($01bcacdf0a25e20c$var$selectedSpeakerAtom);
|
|
478
|
+
const initDevices = (0, $5Zyvw$jotaiutils.useAtomCallback)((0, $5Zyvw$react.useCallback)(async (_get, set)=>{
|
|
479
|
+
if (!client) return;
|
|
480
|
+
const availableCams = await client.getAllCams();
|
|
481
|
+
const availableMics = await client.getAllMics();
|
|
482
|
+
const availableSpeakers = await client.getAllSpeakers();
|
|
483
|
+
set($01bcacdf0a25e20c$var$availableCamsAtom, availableCams);
|
|
484
|
+
set($01bcacdf0a25e20c$var$availableMicsAtom, availableMics);
|
|
485
|
+
set($01bcacdf0a25e20c$var$availableSpeakersAtom, availableSpeakers);
|
|
486
|
+
set($01bcacdf0a25e20c$var$selectedCamAtom, client.selectedCam);
|
|
487
|
+
set($01bcacdf0a25e20c$var$selectedMicAtom, client.selectedMic);
|
|
488
|
+
set($01bcacdf0a25e20c$var$selectedSpeakerAtom, client.selectedSpeaker);
|
|
489
|
+
}, [
|
|
490
|
+
client
|
|
491
|
+
]));
|
|
492
|
+
(0, $5Zyvw$react.useEffect)(()=>{
|
|
493
|
+
initDevices();
|
|
494
|
+
}, [
|
|
495
|
+
initDevices
|
|
496
|
+
]);
|
|
351
497
|
(0, $8a6b68ebf0332682$export$33a6ac53b8f02625)((0, $5Zyvw$pipecataiclientjs.RTVIEvent).AvailableCamsUpdated, (0, $5Zyvw$jotaiutils.useAtomCallback)((0, $5Zyvw$react.useCallback)((_get, set, cams)=>{
|
|
352
498
|
set($01bcacdf0a25e20c$var$availableCamsAtom, cams);
|
|
353
499
|
}, [])));
|
|
@@ -396,30 +542,17 @@ const $01bcacdf0a25e20c$export$652c54907b83a48d = ()=>{
|
|
|
396
542
|
|
|
397
543
|
|
|
398
544
|
|
|
399
|
-
/**
|
|
400
|
-
* Copyright (c) 2024, Daily.
|
|
401
|
-
*
|
|
402
|
-
* SPDX-License-Identifier: BSD-2-Clause
|
|
403
|
-
*/
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const $6b6c1a9f794236bd$var$transportStateAtom = (0, $5Zyvw$jotai.atom)("disconnected");
|
|
407
|
-
const $6b6c1a9f794236bd$export$599fa01283bd4ece = ()=>{
|
|
408
|
-
const [transportState, setTransportState] = (0, $5Zyvw$jotai.useAtom)($6b6c1a9f794236bd$var$transportStateAtom);
|
|
409
|
-
(0, $8a6b68ebf0332682$export$33a6ac53b8f02625)((0, $5Zyvw$pipecataiclientjs.RTVIEvent).TransportStateChanged, setTransportState);
|
|
410
|
-
return transportState;
|
|
411
|
-
};
|
|
412
545
|
|
|
413
546
|
|
|
414
547
|
|
|
415
548
|
|
|
416
549
|
|
|
417
|
-
const $a1dfa75b13e6bb9b$export$59bf27bd43679db6 = /*#__PURE__*/ (0, ($parcel$interopDefault($5Zyvw$react))).memo(({ backgroundColor: backgroundColor = "transparent", barColor: barColor = "black",
|
|
550
|
+
const $a1dfa75b13e6bb9b$export$59bf27bd43679db6 = /*#__PURE__*/ (0, ($parcel$interopDefault($5Zyvw$react))).memo(({ backgroundColor: backgroundColor = "transparent", barColor: barColor = "black", barCount: barCount = 5, barGap: barGap = 12, barLineCap: barLineCap = "round", barMaxHeight: barMaxHeight = 120, barOrigin: barOrigin = "center", barWidth: barWidth = 30, participantType: participantType })=>{
|
|
418
551
|
const canvasRef = (0, $5Zyvw$react.useRef)(null);
|
|
419
552
|
const track = (0, $e5be552b22401c66$export$7c03381e0d26a6c3)("audio", participantType);
|
|
420
553
|
(0, $5Zyvw$react.useEffect)(()=>{
|
|
421
554
|
if (!canvasRef.current) return;
|
|
422
|
-
const canvasWidth =
|
|
555
|
+
const canvasWidth = barCount * barWidth + (barCount - 1) * barGap;
|
|
423
556
|
const canvasHeight = barMaxHeight;
|
|
424
557
|
const canvas = canvasRef.current;
|
|
425
558
|
const scaleFactor = 2;
|
|
@@ -429,7 +562,7 @@ const $a1dfa75b13e6bb9b$export$59bf27bd43679db6 = /*#__PURE__*/ (0, ($parcel$int
|
|
|
429
562
|
canvas.height = canvasHeight * scaleFactor;
|
|
430
563
|
canvas.style.width = `${canvasWidth}px`;
|
|
431
564
|
canvas.style.height = `${canvasHeight}px`;
|
|
432
|
-
canvasCtx.lineCap =
|
|
565
|
+
canvasCtx.lineCap = barLineCap;
|
|
433
566
|
canvasCtx.scale(scaleFactor, scaleFactor);
|
|
434
567
|
};
|
|
435
568
|
const canvasCtx = canvas.getContext("2d");
|
|
@@ -443,34 +576,29 @@ const $a1dfa75b13e6bb9b$export$59bf27bd43679db6 = /*#__PURE__*/ (0, ($parcel$int
|
|
|
443
576
|
analyser.fftSize = 1024;
|
|
444
577
|
source.connect(analyser);
|
|
445
578
|
const frequencyData = new Uint8Array(analyser.frequencyBinCount);
|
|
446
|
-
canvasCtx.lineCap =
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
579
|
+
canvasCtx.lineCap = barLineCap;
|
|
580
|
+
// Create frequency bands based on barCount
|
|
581
|
+
const bands = Array.from({
|
|
582
|
+
length: barCount
|
|
583
|
+
}, (_, i)=>{
|
|
584
|
+
// Use improved logarithmic scale for better frequency distribution
|
|
585
|
+
const minFreq = barCount > 20 ? 200 : 80; // Adjust min frequency based on bar count
|
|
586
|
+
const maxFreq = 10000; // Cover most important audio frequencies
|
|
587
|
+
// Use Mel scale inspired approach for more perceptually uniform distribution
|
|
588
|
+
// This helps with a large number of bars by placing fewer in the very low range
|
|
589
|
+
// https://en.wikipedia.org/wiki/Mel_scale
|
|
590
|
+
const melMin = 2595 * Math.log10(1 + minFreq / 700);
|
|
591
|
+
const melMax = 2595 * Math.log10(1 + maxFreq / 700);
|
|
592
|
+
const melStep = (melMax - melMin) / barCount;
|
|
593
|
+
const melValue = melMin + i * melStep;
|
|
594
|
+
const startFreq = 700 * (Math.pow(10, melValue / 2595) - 1);
|
|
595
|
+
const endFreq = 700 * (Math.pow(10, (melValue + melStep) / 2595) - 1);
|
|
596
|
+
return {
|
|
597
|
+
startFreq: startFreq,
|
|
598
|
+
endFreq: endFreq,
|
|
451
599
|
smoothValue: 0
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
startFreq: 255,
|
|
455
|
-
endFreq: 500,
|
|
456
|
-
smoothValue: 0
|
|
457
|
-
},
|
|
458
|
-
{
|
|
459
|
-
startFreq: 500,
|
|
460
|
-
endFreq: 2000,
|
|
461
|
-
smoothValue: 0
|
|
462
|
-
},
|
|
463
|
-
{
|
|
464
|
-
startFreq: 2000,
|
|
465
|
-
endFreq: 4000,
|
|
466
|
-
smoothValue: 0
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
startFreq: 4000,
|
|
470
|
-
endFreq: 8000,
|
|
471
|
-
smoothValue: 0
|
|
472
|
-
}
|
|
473
|
-
];
|
|
600
|
+
};
|
|
601
|
+
});
|
|
474
602
|
const getFrequencyBinIndex = (frequency)=>{
|
|
475
603
|
const nyquist = audioContext.sampleRate / 2;
|
|
476
604
|
return Math.round(frequency / nyquist * (analyser.frequencyBinCount - 1));
|
|
@@ -497,9 +625,25 @@ const $a1dfa75b13e6bb9b$export$59bf27bd43679db6 = /*#__PURE__*/ (0, ($parcel$int
|
|
|
497
625
|
}
|
|
498
626
|
const x = startX + i * (barWidth + barGap);
|
|
499
627
|
// Calculate bar height with a maximum cap
|
|
500
|
-
const
|
|
501
|
-
const
|
|
502
|
-
|
|
628
|
+
const minHeight = 0;
|
|
629
|
+
const barHeight = Math.max(minHeight, Math.min(band.smoothValue / 255 * barMaxHeight, barMaxHeight));
|
|
630
|
+
let yTop, yBottom;
|
|
631
|
+
const canvasHeight = canvas.height / scaleFactor;
|
|
632
|
+
switch(barOrigin){
|
|
633
|
+
case "top":
|
|
634
|
+
yTop = adjustedCircleRadius;
|
|
635
|
+
yBottom = Math.min(adjustedCircleRadius + barHeight, canvasHeight - adjustedCircleRadius);
|
|
636
|
+
break;
|
|
637
|
+
case "bottom":
|
|
638
|
+
yBottom = canvasHeight - adjustedCircleRadius;
|
|
639
|
+
yTop = Math.max(yBottom - barHeight, adjustedCircleRadius);
|
|
640
|
+
break;
|
|
641
|
+
case "center":
|
|
642
|
+
default:
|
|
643
|
+
yTop = Math.max(canvasHeight / 2 - barHeight / 2, adjustedCircleRadius);
|
|
644
|
+
yBottom = Math.min(canvasHeight / 2 + barHeight / 2, canvasHeight - adjustedCircleRadius);
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
503
647
|
if (band.smoothValue > 0) {
|
|
504
648
|
canvasCtx.beginPath();
|
|
505
649
|
canvasCtx.moveTo(x + barWidth / 2, yTop);
|
|
@@ -507,28 +651,47 @@ const $a1dfa75b13e6bb9b$export$59bf27bd43679db6 = /*#__PURE__*/ (0, ($parcel$int
|
|
|
507
651
|
canvasCtx.lineWidth = barWidth;
|
|
508
652
|
canvasCtx.strokeStyle = barColor;
|
|
509
653
|
canvasCtx.stroke();
|
|
510
|
-
} else
|
|
511
|
-
canvasCtx.beginPath();
|
|
512
|
-
canvasCtx.arc(x + barWidth / 2, canvas.height / scaleFactor / 2, adjustedCircleRadius, 0, 2 * Math.PI);
|
|
513
|
-
canvasCtx.fillStyle = barColor;
|
|
514
|
-
canvasCtx.fill();
|
|
515
|
-
canvasCtx.closePath();
|
|
516
|
-
}
|
|
654
|
+
} else drawInactiveCircle(adjustedCircleRadius, barColor, x, yTop);
|
|
517
655
|
});
|
|
518
656
|
if (!isActive) drawInactiveCircles(adjustedCircleRadius, barColor);
|
|
519
657
|
requestAnimationFrame(drawSpectrum);
|
|
520
658
|
}
|
|
659
|
+
function drawInactiveCircle(circleRadius, color, x, y) {
|
|
660
|
+
switch(barLineCap){
|
|
661
|
+
case "square":
|
|
662
|
+
canvasCtx.fillStyle = color;
|
|
663
|
+
canvasCtx.fillRect(x + barWidth / 2 - circleRadius, y - circleRadius, circleRadius * 2, circleRadius * 2);
|
|
664
|
+
break;
|
|
665
|
+
case "round":
|
|
666
|
+
default:
|
|
667
|
+
canvasCtx.beginPath();
|
|
668
|
+
canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);
|
|
669
|
+
canvasCtx.fillStyle = color;
|
|
670
|
+
canvasCtx.fill();
|
|
671
|
+
canvasCtx.closePath();
|
|
672
|
+
break;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
521
675
|
function drawInactiveCircles(circleRadius, color) {
|
|
522
676
|
const totalBarsWidth = bands.length * barWidth + (bands.length - 1) * barGap;
|
|
523
677
|
const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2;
|
|
524
|
-
const
|
|
678
|
+
const canvasHeight = canvas.height / scaleFactor;
|
|
679
|
+
let y;
|
|
680
|
+
switch(barOrigin){
|
|
681
|
+
case "top":
|
|
682
|
+
y = circleRadius;
|
|
683
|
+
break;
|
|
684
|
+
case "bottom":
|
|
685
|
+
y = canvasHeight - circleRadius;
|
|
686
|
+
break;
|
|
687
|
+
case "center":
|
|
688
|
+
default:
|
|
689
|
+
y = canvasHeight / 2;
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
525
692
|
bands.forEach((_, i)=>{
|
|
526
693
|
const x = startX + i * (barWidth + barGap);
|
|
527
|
-
|
|
528
|
-
canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);
|
|
529
|
-
canvasCtx.fillStyle = color;
|
|
530
|
-
canvasCtx.fill();
|
|
531
|
-
canvasCtx.closePath();
|
|
694
|
+
drawInactiveCircle(circleRadius, color, x, y);
|
|
532
695
|
});
|
|
533
696
|
}
|
|
534
697
|
drawSpectrum();
|
|
@@ -541,8 +704,11 @@ const $a1dfa75b13e6bb9b$export$59bf27bd43679db6 = /*#__PURE__*/ (0, ($parcel$int
|
|
|
541
704
|
}, [
|
|
542
705
|
backgroundColor,
|
|
543
706
|
barColor,
|
|
707
|
+
barCount,
|
|
544
708
|
barGap,
|
|
709
|
+
barLineCap,
|
|
545
710
|
barMaxHeight,
|
|
711
|
+
barOrigin,
|
|
546
712
|
barWidth,
|
|
547
713
|
track
|
|
548
714
|
]);
|