Refactor camera handling and video stream management in Assistant and MobileCall pages

- Remove direct camera start/stop calls and replace them with streamlined video stream handling.
- Update DebugVideoPanel to accept a streamOverride for better flexibility in video source management.
- Adjust MobileCallPage to utilize the new videoStream state, enhancing the call experience.
- Introduce videoStream state management in useVoicePreview for improved media handling during voice interactions.
This commit is contained in:
Xin Wang
2026-07-13 07:05:06 +08:00
parent ede5e2334b
commit fd57f34a55
3 changed files with 43 additions and 45 deletions

View File

@@ -89,6 +89,7 @@ export function useVoicePreview(
const [error, setError] = useState<string | null>(null);
const [micWarning, setMicWarning] = useState<string | null>(null);
const [localStream, setLocalStream] = useState<MediaStream | null>(null);
const [videoStream, setVideoStream] = useState<MediaStream | null>(null);
const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);
const [messages, setMessages] = useState<ChatMessage[]>([]);
const [callEnded, setCallEnded] = useState(false);
@@ -161,6 +162,7 @@ export function useVoicePreview(
const disconnect = useCallback(() => {
releaseResources();
setLocalStream(null);
setVideoStream(null);
setRemoteStream(null);
setMessages([]);
messageSeqRef.current = 0;
@@ -173,6 +175,7 @@ export function useVoicePreview(
const fail = useCallback((message: string) => {
releaseResources();
setLocalStream(null);
setVideoStream(null);
setRemoteStream(null);
setError(message);
setNetworkQuality("unknown");
@@ -306,6 +309,10 @@ export function useVoicePreview(
onDeviceError: (deviceError) => {
setMicWarning(deviceError.message || "无法访问麦克风。已尝试继续连接。");
},
onCamUpdated: () => {
const track = transport.tracks().local.video;
setVideoStream(track ? new MediaStream([track]) : null);
},
onTransportStateChanged: (nextState) => {
if (nextState === "connected" || nextState === "ready") {
setStatus("connected");
@@ -331,7 +338,9 @@ export function useVoicePreview(
await transport.updateMic(selectedDeviceIdRef.current);
}
const localAudio = transport.tracks().local.audio;
const localVideo = transport.tracks().local.video;
setLocalStream(localAudio ? new MediaStream([localAudio]) : null);
setVideoStream(localVideo ? new MediaStream([localVideo]) : null);
void refreshDevices();
const request = new Request(`${API_BASE}/api/webrtc/offer`, {
@@ -377,6 +386,10 @@ export function useVoicePreview(
if (transport && deviceId) await transport.updateCam(deviceId);
}, []);
const selectCamera = useCallback((deviceId: string) => {
transportRef.current?.updateCam(deviceId);
}, []);
const selectDevice = useCallback(async (deviceId: string) => {
setSelectedDeviceId(deviceId);
selectedDeviceIdRef.current = deviceId;
@@ -413,6 +426,7 @@ export function useVoicePreview(
error,
micWarning,
localStream,
videoStream,
remoteStream,
messages,
callEnded,
@@ -428,6 +442,7 @@ export function useVoicePreview(
sendText,
connect,
replaceVideoStream,
selectCamera,
disconnect,
audioRef,
};