【m】占位重构完成

This commit is contained in:
2026-04-25 13:29:35 +08:00
parent d80e64ca66
commit 85f80d9f59
4 changed files with 115 additions and 107 deletions

View File

@@ -137,108 +137,106 @@ class CallStateManager {
// 如果是开启视频,重新获取摄像头资源
if (mediaType === 'video' && value) {
if (this.state.localStream) {
// 停止当前的媒体流
try {
// 只获取新的视频轨道,不干扰正在工作的音频
const newVideoStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false });
const newVideoTrack = newVideoStream.getVideoTracks()[0];
if (!newVideoTrack) {
throw new Error('Failed to get video track');
}
// 更新本地流中的视频轨道(替换旧的已停止的轨道)
if (this.state.localStream) {
this.state.localStream.getTracks().forEach(track => track.stop());
const oldVideoTracks = this.state.localStream.getVideoTracks();
oldVideoTracks.forEach(track => {
track.stop();
this.state.localStream.removeTrack(track);
});
this.state.localStream.addTrack(newVideoTrack);
} else {
// 本地流不存在时(不应该发生),使用新流
this.state.localStream = newVideoStream;
}
this.state.localStream = null;
}
// 请求摄像头权限并获取媒体流
this.state.localStream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
await this.getLocalStream();
// 更新WebRTC连接中的媒体轨道
if (this.renderstreaming) {
console.log('Updating media tracks in WebRTC connection');
// 更新WebRTC连接中的视频轨道
if (this.renderstreaming) {
console.log('Updating video track in WebRTC connection');
// 获取所有收发器
const transceivers = this.renderstreaming.getTransceivers();
console.log('All transceivers:', transceivers);
if (this.role === 'host') {
// Host端需要遍历所有participant的peer来替换视频轨道
const participantIds = Object.keys(this.state.remoteStreams);
for (const participantId of participantIds) {
const transceivers = this.renderstreaming.getTransceivers(participantId);
if (!transceivers) continue;
// 查找现有的视频和音频收发器
const videoTransceivers = transceivers.filter(t => {
return t.sender && t.sender.track && t.sender.track.kind === 'video';
});
console.log('Found video transceivers:', videoTransceivers);
const videoTransceivers = transceivers.filter(t =>
t.sender && t.sender.track && t.sender.track.kind === 'video'
);
const audioTransceivers = transceivers.filter(t => {
return t.sender && t.sender.track && t.sender.track.kind === 'audio';
});
console.log('Found audio transceivers:', audioTransceivers);
// 获取新的视频和音频轨道
const videoTracks = this.state.localStream.getVideoTracks();
console.log('New video tracks:', videoTracks);
const audioTracks = this.state.localStream.getAudioTracks();
console.log('New audio tracks:', audioTracks);
// 更新音频轨道
if (audioTracks.length > 0) {
const newAudioTrack = audioTracks[0];
console.log('Using new audio track:', newAudioTrack);
if (audioTransceivers.length > 0) {
// 替换现有的音频轨道
for (const transceiver of audioTransceivers) {
try {
console.log('Replacing audio track in transceiver:', transceiver);
await transceiver.sender.replaceTrack(newAudioTrack);
console.log('Successfully replaced audio track');
} catch (error) {
console.error('Error replacing audio track:', error);
if (videoTransceivers.length > 0) {
for (const transceiver of videoTransceivers) {
try {
await transceiver.sender.replaceTrack(newVideoTrack);
console.log(`Replaced video track for participant ${participantId}`);
} catch (error) {
console.error(`Error replacing video track for ${participantId}:`, error);
}
}
} else {
// 没有视频收发器,添加新的
try {
this.renderstreaming.addTransceiver(newVideoTrack, { direction: 'sendonly' }, participantId);
console.log(`Added new video transceiver for participant ${participantId}`);
} catch (error) {
console.error(`Error adding video transceiver for ${participantId}:`, error);
}
}
// 设置编解码器偏好
setTimeout(() => { this.setCodecPreferences(participantId); }, 100);
}
} else {
// 添加新的音频收发器
try {
console.log('Adding new audio transceiver');
const transceiver = this.renderstreaming.addTransceiver(newAudioTrack, { direction: 'sendonly' });
console.log('Added new audio transceiver:', transceiver);
} catch (error) {
console.error('Error adding new audio transceiver:', error);
}
}
}
// 更新视频轨道
if (videoTracks.length > 0) {
const newVideoTrack = videoTracks[0];
console.log('Using new video track:', newVideoTrack);
// Participant端使用单一peer
const transceivers = this.renderstreaming.getTransceivers();
if (transceivers) {
const videoTransceivers = transceivers.filter(t =>
t.sender && t.sender.track && t.sender.track.kind === 'video'
);
if (videoTransceivers.length > 0) {
// 替换现有的视频轨道
for (const transceiver of videoTransceivers) {
try {
console.log('Replacing video track in transceiver:', transceiver);
await transceiver.sender.replaceTrack(newVideoTrack);
console.log('Successfully replaced video track');
} catch (error) {
console.error('Error replacing video track:', error);
if (videoTransceivers.length > 0) {
for (const transceiver of videoTransceivers) {
try {
await transceiver.sender.replaceTrack(newVideoTrack);
console.log('Successfully replaced video track');
} catch (error) {
console.error('Error replacing video track:', error);
}
}
} else {
try {
this.renderstreaming.addTransceiver(newVideoTrack, { direction: 'sendonly' });
console.log('Added new video transceiver');
} catch (error) {
console.error('Error adding video transceiver:', error);
}
}
}
} else {
// 添加新的视频收发器
try {
console.log('Adding new video transceiver');
const transceiver = this.renderstreaming.addTransceiver(newVideoTrack, { direction: 'sendonly' });
console.log('Added new video transceiver:', transceiver);
} catch (error) {
console.error('Error adding new video transceiver:', error);
}
setTimeout(() => { this.setCodecPreferences(); }, 100);
}
}
// 更新状态和通知UI
this.state.session.localUser.mediaState.video = true;
this.notify({ type: 'LOCAL_STREAM_OBTAINED', stream: this.state.localStream });
this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'video', value: true });
this.emitMediaStateChange();
this.startLocalActivityDetection();
// 延迟设置编解码器偏好,确保收发器已完全创建
setTimeout(() => {
this.setCodecPreferences();
}, 100);
} catch (error) {
console.error('Error reopening video:', error);
this.state.session.localUser.mediaState.video = false;
this.notify({ type: 'LOCAL_MEDIA_CHANGE', mediaType: 'video', value: false });
}
} else {
// 直接更新媒体状态
@@ -481,9 +479,9 @@ class CallStateManager {
}
} else if (data.type === 'media-state-changed') {
// 处理媒体状态变化
console.log('收到媒体状态变化:', data.data);
// 更新远程用户的媒体状态
this.updateRemoteMedia(data.data);
console.log('收到媒体状态变化:', data.data, 'from participant:', data.participantId);
// 更新远程用户的媒体状态传递participantId以便精准定位
this.updateRemoteMedia(data.data, data.participantId);
} else if (data.type === 'user-info') {
// 处理用户信息更新
console.log('收到用户信息:', data.data);
@@ -601,12 +599,12 @@ class CallStateManager {
// 更新远端媒体状态 (由 WebSocket 触发)
updateRemoteMedia(mediaState) {
updateRemoteMedia(mediaState, participantId) {
this.state.session.remoteUser.mediaState = {
...this.state.session.remoteUser.mediaState,
...mediaState
};
this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState });
this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState, participantId });
// 通知UI更新用户列表
this.notify({ type: 'USER_LIST_UPDATE', localUser: this.state.session.localUser, remoteUser: this.state.session.remoteUser });
}