Ezmary commited on
Commit
89adfc6
·
verified ·
1 Parent(s): 36348bf

Update src/components/control-tray/ControlTray.tsx

Browse files
src/components/control-tray/ControlTray.tsx CHANGED
@@ -5,7 +5,7 @@ import React, { memo, RefObject, useEffect, useState, useCallback, useRef } from
5
  import { useLiveAPIContext } from "../../contexts/LiveAPIContext";
6
  import { AudioRecorder } from "../../lib/audio-recorder";
7
  import Logo from '../logo/Logo';
8
- import { PauseIconWithSurroundPulse, microphoneIcon, cameraIcon, stopCamIcon, pauseIcon } from '../icons';
9
 
10
  const SvgSwitchCameraIcon = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-[22px] h-[22px]"><path d="M11 19H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h5"/><path d="M13 5h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5"/><path d="m17 12-3-3 3-3"/><path d="m7 12 3 3-3 3"/></svg>;
11
 
@@ -23,7 +23,7 @@ export type ControlTrayProps = {
23
  };
24
 
25
  const ControlTray: React.FC<ControlTrayProps> = ({ videoRef, onVideoStreamChange, supportsVideo, isAppMicActive, onAppMicToggle, isAppCamActive, onAppCamToggle, currentFacingMode, onFacingModeChange, onUserSpeakingChange }) => {
26
- const { client, connected, connect, volume } = useLiveAPIContext();
27
  const audioRecorderRef = useRef<AudioRecorder | null>(null);
28
  const [activeLocalVideoStream, setActiveLocalVideoStream] = useState<MediaStream | null>(null);
29
  const [isSwitchingCamera, setIsSwitchingCamera] = useState(false);
@@ -32,35 +32,43 @@ const ControlTray: React.FC<ControlTrayProps> = ({ videoRef, onVideoStreamChange
32
 
33
  useEffect(() => {
34
  if (!audioRecorderRef.current) {
35
- audioRecorderRef.current = new AudioRecorder();
36
  }
37
  const audioRecorder = audioRecorderRef.current;
38
-
39
- const onData = (base64: string, volume: number) => {
40
  if (client && connected && isAppMicActive) {
41
  client.sendRealtimeInput([{ mimeType: "audio/pcm;rate=16000", data: base64 }]);
42
- setUserVolume(volume);
43
- onUserSpeakingChange(volume > 0.01);
44
  }
45
  };
46
- const onStop = () => {
47
- setUserVolume(0);
48
- onUserSpeakingChange(false);
49
- }
 
50
 
51
- if (connected && isAppMicActive) {
52
- audioRecorder.on("data", onData).on("stop", onStop).start();
53
- } else {
54
- if (audioRecorder.recording) audioRecorder.stop();
 
 
 
 
 
 
 
 
55
  }
 
56
  return () => {
57
- if (audioRecorder) {
58
- audioRecorder.off("data", onData).off("stop", onStop);
59
- if (audioRecorder.recording) audioRecorder.stop();
60
- }
61
  };
62
- }, [connected, client, isAppMicActive, onUserSpeakingChange]);
63
 
 
64
  useEffect(() => {
65
  if (videoRef.current) {
66
  if (videoRef.current.srcObject !== activeLocalVideoStream) {
@@ -191,8 +199,6 @@ const ControlTray: React.FC<ControlTrayProps> = ({ videoRef, onVideoStreamChange
191
  }
192
  };
193
 
194
- const isSpeaking = onUserSpeakingChange.length > 0 && userVolume > 0.01;
195
-
196
  return (
197
  <footer id="footer-controls" className="footer-controls-html-like">
198
  <canvas style={{ display: "none" }} ref={renderCanvasRef} />
@@ -206,8 +212,8 @@ const ControlTray: React.FC<ControlTrayProps> = ({ videoRef, onVideoStreamChange
206
  isMini={true}
207
  isActive={true}
208
  isAi={false}
209
- speakingVolume={volume}
210
- isUserSpeaking={isSpeaking}
211
  />
212
  </div>
213
  )}
 
5
  import { useLiveAPIContext } from "../../contexts/LiveAPIContext";
6
  import { AudioRecorder } from "../../lib/audio-recorder";
7
  import Logo from '../logo/Logo';
8
+ import { PauseIconWithSurroundPulse, microphoneIcon, cameraIcon, stopCamIcon } from '../icons';
9
 
10
  const SvgSwitchCameraIcon = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-[22px] h-[22px]"><path d="M11 19H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h5"/><path d="M13 5h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5"/><path d="m17 12-3-3 3-3"/><path d="m7 12 3 3-3 3"/></svg>;
11
 
 
23
  };
24
 
25
  const ControlTray: React.FC<ControlTrayProps> = ({ videoRef, onVideoStreamChange, supportsVideo, isAppMicActive, onAppMicToggle, isAppCamActive, onAppCamToggle, currentFacingMode, onFacingModeChange, onUserSpeakingChange }) => {
26
+ const { client, connected, connect, volume: aiVolume } = useLiveAPIContext();
27
  const audioRecorderRef = useRef<AudioRecorder | null>(null);
28
  const [activeLocalVideoStream, setActiveLocalVideoStream] = useState<MediaStream | null>(null);
29
  const [isSwitchingCamera, setIsSwitchingCamera] = useState(false);
 
32
 
33
  useEffect(() => {
34
  if (!audioRecorderRef.current) {
35
+ audioRecorderRef.current = new AudioRecorder();
36
  }
37
  const audioRecorder = audioRecorderRef.current;
38
+
39
+ const handleData = (base64: string) => {
40
  if (client && connected && isAppMicActive) {
41
  client.sendRealtimeInput([{ mimeType: "audio/pcm;rate=16000", data: base64 }]);
 
 
42
  }
43
  };
44
+
45
+ const handleVolume = (volume: number) => {
46
+ setUserVolume(volume);
47
+ onUserSpeakingChange(volume > 0.01);
48
+ };
49
 
50
+ const handleStop = () => {
51
+ setUserVolume(0);
52
+ onUserSpeakingChange(false);
53
+ };
54
+
55
+ if (isAppMicActive && !audioRecorder.recording) {
56
+ audioRecorder.on('data', handleData);
57
+ audioRecorder.on('volume', handleVolume);
58
+ audioRecorder.on('stop', handleStop);
59
+ audioRecorder.start();
60
+ } else if (!isAppMicActive && audioRecorder.recording) {
61
+ audioRecorder.stop();
62
  }
63
+
64
  return () => {
65
+ audioRecorder.off('data', handleData);
66
+ audioRecorder.off('volume', handleVolume);
67
+ audioRecorder.off('stop', handleStop);
 
68
  };
69
+ }, [isAppMicActive, connected, client, onUserSpeakingChange]);
70
 
71
+ // ... (بقیه useEffect ها و توابع بدون تغییر باقی می‌مانند)
72
  useEffect(() => {
73
  if (videoRef.current) {
74
  if (videoRef.current.srcObject !== activeLocalVideoStream) {
 
199
  }
200
  };
201
 
 
 
202
  return (
203
  <footer id="footer-controls" className="footer-controls-html-like">
204
  <canvas style={{ display: "none" }} ref={renderCanvasRef} />
 
212
  isMini={true}
213
  isActive={true}
214
  isAi={false}
215
+ speakingVolume={aiVolume}
216
+ isUserSpeaking={userVolume > 0.01}
217
  />
218
  </div>
219
  )}