【m】分窗渲染测试没问题

This commit is contained in:
2026-04-24 23:03:41 +08:00
parent b66b639df0
commit eba0d07c83
4 changed files with 403 additions and 303 deletions

View File

@@ -326,15 +326,15 @@ class CallStateManager {
{ googTypingNoiseDetection: true } // 启用打字噪声检测
]
};
this.renderstreaming = new RenderStreaming(signaling, config); // 创建WebRTC连接管理实例
this.renderstreaming.onNewPeer = (connectionId) => {
console.log(`New peer created for ${connectionId}, adding local tracks`);
this.renderstreaming = new RenderStreaming(signaling, config);
this.renderstreaming.onNewPeer = (participantId) => {
console.log(`New peer created for ${participantId}, adding local tracks`);
if (this.state.localStream) {
const tracks = this.state.localStream.getTracks();
for (const track of tracks) {
this.renderstreaming.addTransceiver(track, { direction: 'sendonly' });
this.renderstreaming.addTransceiver(track, { direction: 'sendonly' }, participantId);
}
this.setCodecPreferences();
this.setCodecPreferences(participantId);
}
};
// 连接建立回调
@@ -375,44 +375,39 @@ this.renderstreaming.onNewPeer = (connectionId) => {
};
// participant离开回调host收到房间仍然存在
this.renderstreaming.onParticipantLeft = (connectionId) => {
console.log(`Participant left: ${connectionId}, room still active`);
// 更新远程用户状态,但不关闭房间
this.renderstreaming.onParticipantLeft = (participantId) => {
console.log(`Participant left: ${participantId}, room still active`);
this.updateRemoteUserStatus('offline');
this.updateRemoteUserNetworkQuality('no_signal');
showNotification('对方已离开通话', 'warning');
// 清理该 participant 的远端流
if (this.state.remoteStreams[connectionId]) {
this.state.remoteStreams[connectionId].getTracks().forEach(track => track.stop());
delete this.state.remoteStreams[connectionId];
if (this.state.remoteStreams[participantId]) {
this.state.remoteStreams[participantId].getTracks().forEach(track => track.stop());
delete this.state.remoteStreams[participantId];
}
// 同时清理单路远端流(兼容)
if (this.state.remoteStream) {
this.state.remoteStream.getTracks().forEach(track => track.stop());
this.state.remoteStream = null;
}
// 通知UI更新
this.notify({ type: 'PARTICIPANT_LEFT', connectionId: connectionId });
// 通知UI更新用participantId作为connectionId传给renderer
this.notify({ type: 'PARTICIPANT_LEFT', connectionId: participantId });
};
// 轨道事件回调
this.renderstreaming.onTrackEvent = (data) => {
const direction = data.transceiver.direction;
if (direction == "sendrecv" || direction == "recvonly") {
// 获取当前连接的远端
const trackConnectionId = this.connectionId;
// Host端: 每个participant有独立的远端流
// Participant端: 只有一个host的远端流
// 使用participantId区分不同participant的
const trackParticipantId = data.participantId || this.connectionId;
const isHost = this.role === 'host';
// 获取或创建对应的远端流
let targetStream = null;
if (isHost) {
// Host端: 按 connectionId 管理多路远端流
if (!this.state.remoteStreams[trackConnectionId]) {
this.state.remoteStreams[trackConnectionId] = new MediaStream();
// Host端: 按 participantId 管理多路远端流
if (!this.state.remoteStreams[trackParticipantId]) {
this.state.remoteStreams[trackParticipantId] = new MediaStream();
}
targetStream = this.state.remoteStreams[trackConnectionId];
targetStream = this.state.remoteStreams[trackParticipantId];
} else {
// Participant端: 使用单一远端流
if (this.state.remoteStream == null) {
@@ -423,22 +418,19 @@ this.renderstreaming.onNewPeer = (connectionId) => {
// 检查是否已经有相同类型的轨道
const existingTracks = targetStream.getTracks().filter(track => track.kind === data.track.kind);
// 移除旧的轨道
existingTracks.forEach(track => {
targetStream.removeTrack(track);
console.log('Removed old track:', track.kind);
});
// 添加新的轨道
targetStream.addTrack(data.track);
console.log('Added new track:', data.track.kind, 'to stream:', trackConnectionId);
console.log('Added new track:', data.track.kind, 'for participant:', trackParticipantId);
// 通知UI远程流已更新
this.notify({
type: 'REMOTE_STREAM_OBTAINED',
stream: targetStream,
connectionId: trackConnectionId,
connectionId: trackParticipantId,
isHost: isHost
});
console.log('Notified UI about remote stream update');
@@ -585,29 +577,24 @@ this.renderstreaming.onNewPeer = (connectionId) => {
/**
* 设置编解码器偏好
*/
setCodecPreferences() {
/** @type {RTCRtpCodecCapability[] | null} */
setCodecPreferences(participantId) {
let selectedCodecs = null;
// 获取视频编解码器能力
const { codecs } = RTCRtpSender.getCapabilities('video');
if (codecs && codecs.length > 0) {
// 优先选择H.264编解码器
const h264Codec = codecs.find(c => c.mimeType === 'video/H264');
if (h264Codec) {
selectedCodecs = [h264Codec];
}
}
if (selectedCodecs == null) return;
if (selectedCodecs == null) {
return;
}
// 获取视频收发器并设置编解码器偏好
if (this.renderstreaming) {
const transceivers = this.renderstreaming.getTransceivers().filter(t => t.receiver.track.kind == "video");
const transceivers = this.renderstreaming.getTransceivers(participantId);
if (transceivers && transceivers.length > 0) {
transceivers.forEach(t => t.setCodecPreferences(selectedCodecs));
const videoTransceivers = transceivers.filter(t => t.receiver.track.kind == "video");
if (videoTransceivers && videoTransceivers.length > 0) {
videoTransceivers.forEach(t => t.setCodecPreferences(selectedCodecs));
}
}
}
}