【m】分窗渲染测试没问题
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user