Ezmary commited on
Commit
50f12c9
·
verified ·
1 Parent(s): cdd3d29

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
 
@@ -30,39 +30,56 @@ const ControlTray: React.FC<ControlTrayProps> = ({ videoRef, onVideoStreamChange
30
  const renderCanvasRef = React.useRef<HTMLCanvasElement>(null);
31
  const [userVolume, setUserVolume] = useState(0);
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  useEffect(() => {
34
  if (!audioRecorderRef.current) {
35
  audioRecorderRef.current = new AudioRecorder();
36
  }
37
  const audioRecorder = audioRecorderRef.current;
38
 
39
- // --- 👇 تغییر اصلی اینجاست: دریافت ولوم از رویداد data 👇 ---
40
- const onData = (base64: string, volume: number) => {
41
- if (client && connected && isAppMicActive) {
42
- client.sendRealtimeInput([{ mimeType: "audio/pcm;rate=16000", data: base64 }]);
43
- setUserVolume(volume);
44
- onUserSpeakingChange(volume > 0.01);
45
- }
46
- };
47
-
48
  const onStop = () => {
49
  setUserVolume(0);
50
  onUserSpeakingChange(false);
51
  }
52
 
53
- if (connected && isAppMicActive) {
54
- audioRecorder.on("data", onData).on("stop", onStop).start();
 
 
 
 
 
55
  } else {
56
- if (audioRecorder.recording) audioRecorder.stop();
 
 
57
  }
 
 
58
  return () => {
59
  if (audioRecorder) {
60
- audioRecorder.off("data", onData).off("stop", onStop);
61
- if (audioRecorder.recording) audioRecorder.stop();
62
  }
63
  };
64
- }, [connected, client, isAppMicActive, onUserSpeakingChange]);
65
 
 
 
66
  useEffect(() => {
67
  if (videoRef.current) {
68
  if (videoRef.current.srcObject !== activeLocalVideoStream) {
@@ -193,13 +210,12 @@ const ControlTray: React.FC<ControlTrayProps> = ({ videoRef, onVideoStreamChange
193
  }
194
  };
195
 
196
- const isSpeaking = onUserSpeakingChange.length > 0 && userVolume > 0.01;
197
 
198
  return (
199
  <footer id="footer-controls" className="footer-controls-html-like">
200
  <canvas style={{ display: "none" }} ref={renderCanvasRef} />
201
  <div id="mic-button" className="control-button mic-button-color" onClick={handleMicToggle}>
202
- {/* استفاده از آیکون جدید با انیمیشن */}
203
  {isAppMicActive ? <PauseIconWithSurroundPulse userVolume={userVolume} /> : microphoneIcon}
204
  </div>
205
 
 
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
 
 
30
  const renderCanvasRef = React.useRef<HTMLCanvasElement>(null);
31
  const [userVolume, setUserVolume] = useState(0);
32
 
33
+ // --- 👇 تغییر اصلی اینجاست 👇 ---
34
+ // Event-handler جدید برای دریافت هر دو مقدار
35
+ const handleAudioData = useCallback((base64: string, vol: number) => {
36
+ if (client && connected && isAppMicActive) {
37
+ // فقط دیتای صدا را به سرور بفرست
38
+ if (base64) {
39
+ client.sendRealtimeInput([{ mimeType: "audio/pcm;rate=16000", data: base64 }]);
40
+ }
41
+ // حجم صدا را برای انیمیشن‌ها آپدیت کن
42
+ setUserVolume(vol);
43
+ onUserSpeakingChange(vol > 0.01);
44
+ }
45
+ }, [client, connected, isAppMicActive, onUserSpeakingChange]);
46
+
47
  useEffect(() => {
48
  if (!audioRecorderRef.current) {
49
  audioRecorderRef.current = new AudioRecorder();
50
  }
51
  const audioRecorder = audioRecorderRef.current;
52
 
53
+ // Event listener برای توقف ضبط
 
 
 
 
 
 
 
 
54
  const onStop = () => {
55
  setUserVolume(0);
56
  onUserSpeakingChange(false);
57
  }
58
 
59
+ if (isAppMicActive && connected) {
60
+ // ثبت کردن event handlerها
61
+ audioRecorder.on("data", handleAudioData);
62
+ audioRecorder.on("stop", onStop);
63
+ if (!audioRecorder.recording) {
64
+ audioRecorder.start();
65
+ }
66
  } else {
67
+ if (audioRecorder.recording) {
68
+ audioRecorder.stop();
69
+ }
70
  }
71
+
72
+ // Cleanup function
73
  return () => {
74
  if (audioRecorder) {
75
+ audioRecorder.off("data", handleAudioData);
76
+ audioRecorder.off("stop", onStop);
77
  }
78
  };
79
+ }, [isAppMicActive, connected, handleAudioData, onUserSpeakingChange]);
80
 
81
+ // --- 👆 پایان تغییرات اصلی 👆 ---
82
+
83
  useEffect(() => {
84
  if (videoRef.current) {
85
  if (videoRef.current.srcObject !== activeLocalVideoStream) {
 
210
  }
211
  };
212
 
213
+ const isSpeaking = userVolume > 0.01;
214
 
215
  return (
216
  <footer id="footer-controls" className="footer-controls-html-like">
217
  <canvas style={{ display: "none" }} ref={renderCanvasRef} />
218
  <div id="mic-button" className="control-button mic-button-color" onClick={handleMicToggle}>
 
219
  {isAppMicActive ? <PauseIconWithSurroundPulse userVolume={userVolume} /> : microphoneIcon}
220
  </div>
221