@pipecat-ai/client-react 0.3.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/README.md +234 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +548 -0
- package/dist/index.js.map +1 -0
- package/dist/index.module.js +531 -0
- package/dist/index.module.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
<h1><div align="center">
|
|
2
|
+
<img alt="pipecat react" width="500px" height="auto" src="../pipecat-react.png">
|
|
3
|
+
</div></h1>
|
|
4
|
+
|
|
5
|
+
[](https://docs.pipecat.ai/client/introduction)
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @pipecat-ai/client-js @pipecat-ai/client-react
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
Instantiate an `RTVIClient` instance and pass it down to the `RTVIClientProvider`. Render the `<RTVIClientAudio>` component to have audio output setup automatically.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { RTVIClient } from "@pipecat-ai/client-js";
|
|
20
|
+
import { RTVIClientAudio, RTVIClientProvider } from "@pipecat-ai/client-react";
|
|
21
|
+
|
|
22
|
+
const client = new RTVIClient({
|
|
23
|
+
baseUrl: "https://rtvi.pipecat.bot",
|
|
24
|
+
enableMic: true,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
render(
|
|
28
|
+
<RTVIClientProvider client={client}>
|
|
29
|
+
<MyApp />
|
|
30
|
+
<RTVIClientAudio />
|
|
31
|
+
</RTVIClientProvider>
|
|
32
|
+
);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
We recommend starting the voiceClient from a click of a button, so here's a minimal implementation of `<MyApp>` to get started:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { useRTVIClient } from "@pipecat-ai/client-react";
|
|
39
|
+
|
|
40
|
+
const MyApp = () => {
|
|
41
|
+
const client = useRTVIClient();
|
|
42
|
+
return <button onClick={() => client.start()}>OK Computer</button>;
|
|
43
|
+
};
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Components
|
|
47
|
+
|
|
48
|
+
### RTVIClientProvider
|
|
49
|
+
|
|
50
|
+
The root component for providing RTVI client context to your application.
|
|
51
|
+
|
|
52
|
+
#### Props
|
|
53
|
+
|
|
54
|
+
- `client` (RTVIClient, required): A singleton instance of RTVIClient.
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
<RTVIClientProvider client={rtviClient}>
|
|
58
|
+
{/* Child components */}
|
|
59
|
+
</RTVIClientProvider>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### RTVIClientAudio
|
|
63
|
+
|
|
64
|
+
Creates a new `<audio>` element that mounts the bot's audio track.
|
|
65
|
+
|
|
66
|
+
#### Props
|
|
67
|
+
|
|
68
|
+
No props
|
|
69
|
+
|
|
70
|
+
```jsx
|
|
71
|
+
<RTVIClientAudio />
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### RTVIClientVideo
|
|
75
|
+
|
|
76
|
+
Creates a new `<video>` element that renders either the bot or local participant's video track.
|
|
77
|
+
|
|
78
|
+
#### Props
|
|
79
|
+
|
|
80
|
+
- `participant` ("local" | "bot"): Defines which participant's video track is rendered
|
|
81
|
+
- `fit` ("contain" | "cover", optional): Defines whether the video should be fully contained or cover the box. Default: 'contain'.
|
|
82
|
+
- `mirror` (boolean, optional): Forces the video to be mirrored, if set.
|
|
83
|
+
- `onResize(dimensions: object)` (function, optional): Triggered whenever the video's rendered width or height changes. Returns the video's native `width`, `height` and `aspectRatio`.
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
<RTVIClientVideo
|
|
87
|
+
participant="local"
|
|
88
|
+
fit="cover"
|
|
89
|
+
mirror
|
|
90
|
+
onResize={({ aspectRatio, height, width }) => {
|
|
91
|
+
console.log("Video dimensions changed:", { aspectRatio, height, width });
|
|
92
|
+
}}
|
|
93
|
+
/>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### VoiceVisualizer
|
|
97
|
+
|
|
98
|
+
Renders a visual representation of audio input levels on a `<canvas>` element.
|
|
99
|
+
The visualization consists of five vertical bars.
|
|
100
|
+
|
|
101
|
+
#### Props
|
|
102
|
+
|
|
103
|
+
- `participantType` (string, required): The participant type to visualize audio for.
|
|
104
|
+
- `backgroundColor` (string, optional): The background color of the canvas. Default: 'transparent'.
|
|
105
|
+
- `barColor` (string, optional): The color of the audio level bars. Default: 'black'.
|
|
106
|
+
- `barGap` (number, optional): The gap between bars in pixels. Default: 12.
|
|
107
|
+
- `barWidth` (number, optional): The width of each bar in pixels. Default: 30.
|
|
108
|
+
- `barMaxHeight` (number, optional): The maximum height at full volume of each bar in pixels. Default: 120.
|
|
109
|
+
|
|
110
|
+
```jsx
|
|
111
|
+
<VoiceVisualizer
|
|
112
|
+
participantType="local"
|
|
113
|
+
backgroundColor="white"
|
|
114
|
+
barColor="black"
|
|
115
|
+
barGap={1}
|
|
116
|
+
barWidth={4}
|
|
117
|
+
barMaxHeight={24}
|
|
118
|
+
/>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Hooks
|
|
122
|
+
|
|
123
|
+
### useRTVIClient
|
|
124
|
+
|
|
125
|
+
Provides access to the `RTVIClient` instance originally passed to [`RTVIClientProvider`](#rtviclientprovider).
|
|
126
|
+
|
|
127
|
+
```jsx
|
|
128
|
+
import { useRTVIClient } from "@pipecat-ai/client-react";
|
|
129
|
+
|
|
130
|
+
function MyComponent() {
|
|
131
|
+
const rtviClient = useRTVIClient();
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### useRTVIClientEvent
|
|
136
|
+
|
|
137
|
+
Allows subscribing to RTVI client events.
|
|
138
|
+
It is advised to wrap handlers with `useCallback`.
|
|
139
|
+
|
|
140
|
+
#### Arguments
|
|
141
|
+
|
|
142
|
+
- `event` (RTVIEvent, required)
|
|
143
|
+
- `handler` (function, required)
|
|
144
|
+
|
|
145
|
+
```jsx
|
|
146
|
+
import { useCallback } from "react";
|
|
147
|
+
import { RTVIEvent, TransportState } from "@pipecat-ai/client-js";
|
|
148
|
+
import { useRTVIClientEvent } from "@pipecat-ai/client-react";
|
|
149
|
+
|
|
150
|
+
function EventListener() {
|
|
151
|
+
useRTVIClientEvent(
|
|
152
|
+
RTVIEvent.TransportStateChanged,
|
|
153
|
+
useCallback((transportState: TransportState) => {
|
|
154
|
+
console.log("Transport state changed to", transportState);
|
|
155
|
+
}, [])
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### useRTVIClientMediaDevices
|
|
161
|
+
|
|
162
|
+
Manage and list available media devices.
|
|
163
|
+
|
|
164
|
+
```jsx
|
|
165
|
+
import { useRTVIClientMediaDevices } from "@pipecat-ai/client-react";
|
|
166
|
+
|
|
167
|
+
function DeviceSelector() {
|
|
168
|
+
const {
|
|
169
|
+
availableCams,
|
|
170
|
+
availableMics,
|
|
171
|
+
selectedCam,
|
|
172
|
+
selectedMic,
|
|
173
|
+
updateCam,
|
|
174
|
+
updateMic,
|
|
175
|
+
} = useRTVIClientMediaDevices();
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<>
|
|
179
|
+
<select
|
|
180
|
+
name="cam"
|
|
181
|
+
onChange={(ev) => updateCam(ev.target.value)}
|
|
182
|
+
value={selectedCam?.deviceId}
|
|
183
|
+
>
|
|
184
|
+
{availableCams.map((cam) => (
|
|
185
|
+
<option key={cam.deviceId} value={cam.deviceId}>
|
|
186
|
+
{cam.label}
|
|
187
|
+
</option>
|
|
188
|
+
))}
|
|
189
|
+
</select>
|
|
190
|
+
<select
|
|
191
|
+
name="mic"
|
|
192
|
+
onChange={(ev) => updateMic(ev.target.value)}
|
|
193
|
+
value={selectedMic?.deviceId}
|
|
194
|
+
>
|
|
195
|
+
{availableMics.map((mic) => (
|
|
196
|
+
<option key={mic.deviceId} value={mic.deviceId}>
|
|
197
|
+
{mic.label}
|
|
198
|
+
</option>
|
|
199
|
+
))}
|
|
200
|
+
</select>
|
|
201
|
+
</>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### useRTVIClientMediaTrack
|
|
207
|
+
|
|
208
|
+
Access audio and video tracks.
|
|
209
|
+
|
|
210
|
+
#### Arguments
|
|
211
|
+
|
|
212
|
+
- `trackType` ("audio" | "video", required)
|
|
213
|
+
- `participantType` ("bot" | "local", required)
|
|
214
|
+
|
|
215
|
+
```jsx
|
|
216
|
+
import { useRTVIClientMediaTrack } from "@pipecat-ai/client-react";
|
|
217
|
+
|
|
218
|
+
function MyTracks() {
|
|
219
|
+
const localAudioTrack = useRTVIClientMediaTrack("audio", "local");
|
|
220
|
+
const botAudioTrack = useRTVIClientMediaTrack("audio", "bot");
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### useRTVIClientTransportState
|
|
225
|
+
|
|
226
|
+
Returns the current transport state.
|
|
227
|
+
|
|
228
|
+
```jsx
|
|
229
|
+
import { useRTVIClientTransportState } from "@pipecat-ai/client-react";
|
|
230
|
+
|
|
231
|
+
function ConnectionStatus() {
|
|
232
|
+
const transportState = useRTVIClientTransportState();
|
|
233
|
+
}
|
|
234
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { RTVIClient, RTVIEvent, RTVIEventHandler, Tracks, TransportState } from "@pipecat-ai/client-js";
|
|
2
|
+
import { Provider } from "jotai/react";
|
|
3
|
+
import { JSX } from "react/jsx-runtime";
|
|
4
|
+
import React from "react";
|
|
5
|
+
interface Props {
|
|
6
|
+
client: RTVIClient;
|
|
7
|
+
jotaiStore?: React.ComponentProps<typeof Provider>["store"];
|
|
8
|
+
}
|
|
9
|
+
export const RTVIClientProvider: React.FC<React.PropsWithChildren<Props>>;
|
|
10
|
+
export const useRTVIClient: () => RTVIClient | undefined;
|
|
11
|
+
export const useRTVIClientEvent: <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => void;
|
|
12
|
+
type ParticipantType = keyof Tracks;
|
|
13
|
+
type TrackType = keyof Tracks["local"];
|
|
14
|
+
export const useRTVIClientMediaTrack: (trackType: TrackType, participantType: ParticipantType) => MediaStreamTrack | null;
|
|
15
|
+
export const RTVIClientAudio: {
|
|
16
|
+
(): JSX.Element;
|
|
17
|
+
displayName: string;
|
|
18
|
+
};
|
|
19
|
+
interface RTVIClientVideoInterface {
|
|
20
|
+
aspectRatio: number;
|
|
21
|
+
height: number;
|
|
22
|
+
width: number;
|
|
23
|
+
}
|
|
24
|
+
interface _Props1 extends Omit<React.VideoHTMLAttributes<HTMLVideoElement>, "onResize"> {
|
|
25
|
+
participant: "local" | "bot";
|
|
26
|
+
/**
|
|
27
|
+
* Defines whether the video should be fully contained or cover the box. Default: 'contain'.
|
|
28
|
+
*/
|
|
29
|
+
fit?: "contain" | "cover";
|
|
30
|
+
/**
|
|
31
|
+
* Forces the video to be mirrored, if set.
|
|
32
|
+
*/
|
|
33
|
+
mirror?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Optional callback, which is triggered whenever the video's rendered width or height changes.
|
|
36
|
+
* Returns the video's native width, height and aspectRatio.
|
|
37
|
+
*/
|
|
38
|
+
onResize?(dimensions: RTVIClientVideoInterface): void;
|
|
39
|
+
}
|
|
40
|
+
export const RTVIClientVideo: React.ForwardRefExoticComponent<_Props1 & React.RefAttributes<HTMLVideoElement>>;
|
|
41
|
+
type OptionalMediaDeviceInfo = MediaDeviceInfo | Record<string, never>;
|
|
42
|
+
export const useRTVIClientMediaDevices: () => {
|
|
43
|
+
availableCams: MediaDeviceInfo[];
|
|
44
|
+
availableMics: MediaDeviceInfo[];
|
|
45
|
+
availableSpeakers: MediaDeviceInfo[];
|
|
46
|
+
selectedCam: OptionalMediaDeviceInfo;
|
|
47
|
+
selectedMic: OptionalMediaDeviceInfo;
|
|
48
|
+
selectedSpeaker: OptionalMediaDeviceInfo;
|
|
49
|
+
updateCam: (id: string) => void;
|
|
50
|
+
updateMic: (id: string) => void;
|
|
51
|
+
updateSpeaker: (id: string) => void;
|
|
52
|
+
};
|
|
53
|
+
export const useRTVIClientTransportState: () => TransportState;
|
|
54
|
+
type _ParticipantType1 = Parameters<typeof useRTVIClientMediaTrack>[1];
|
|
55
|
+
interface _Props2 {
|
|
56
|
+
backgroundColor?: string;
|
|
57
|
+
barColor?: string;
|
|
58
|
+
barGap?: number;
|
|
59
|
+
barWidth?: number;
|
|
60
|
+
barMaxHeight?: number;
|
|
61
|
+
participantType: _ParticipantType1;
|
|
62
|
+
}
|
|
63
|
+
export const VoiceVisualizer: React.FC<_Props2>;
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;AAYA;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,cAAc,CAAC,eAAoB,CAAC,CAAC,OAAO,CAAC,CAAC;CAClE;AAMD,OAAO,MAAM,oBAAoB,MAAM,EAAE,CAAC,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAYvE,CAAC;ACxBF,OAAO,MAAM,2CAGZ,CAAC;ACFF,OAAO,MAAM,qBAAsB,CAAC,SAAS,SAAS,SAC7C,CAAC,WACC,iBAAiB,CAAC,CAAC,SAW7B,CAAC;ACTF,uBAAuB,MAAM,MAAM,CAAC;AACpC,iBAAiB,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;AAgBvC,OAAO,MAAM,qCACA,SAAS,mBACH,eAAe,4BA4CjC,CAAC;AClEF,OAAO,MAAM;;;CA6BZ,CAAC;AE9BF;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iBACE,SAAQ,IAAI,CAAC,MAAM,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,UAAU,CAAC;IACrE,WAAW,EAAE,OAAO,GAAG,KAAK,CAAC;IAE7B;;OAEG;IACH,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,QAAQ,CAAC,CAAC,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAC;CACvD;AAED,OAAO,MAAM,iGAuJZ,CAAC;ACpLF,+BAA+B,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AASvE,OAAO,MAAM;;;;;;;oBA4DJ,MAAM;oBAMN,MAAM;wBAMN,MAAM;CAiBd,CAAC;AC7FF,OAAO,MAAM,iDAMZ,CAAC;ACTF,yBAAuB,UAAU,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC;AAErE;IACE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,iBAAe,CAAC;CAClC;AAED,OAAO,MAAM,iBAAiB,MAAM,EAAE,CAAC,OAAK,CAyM3C,CAAC","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/useMergedRef.ts","client-react/src/src/RTVIClientVideo.tsx","client-react/src/src/useRTVIClientMediaDevices.ts","client-react/src/src/useRTVIClientTransportState.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,"/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClientAudio } from \"./RTVIClientAudio\";\nimport { RTVIClientProvider } from \"./RTVIClientProvider\";\nimport { RTVIClientVideo } from \"./RTVIClientVideo\";\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaDevices } from \"./useRTVIClientMediaDevices\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\n\nexport {\n RTVIClientAudio,\n RTVIClientProvider,\n RTVIClientVideo,\n useRTVIClient,\n useRTVIClientEvent,\n useRTVIClientMediaDevices,\n useRTVIClientMediaTrack,\n useRTVIClientTransportState,\n VoiceVisualizer,\n};\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|