【m】自适应分辨率,不知道有没问题

This commit is contained in:
2026-04-25 22:26:30 +08:00
parent fd06063d83
commit 1d10d54af4
2 changed files with 65 additions and 25 deletions

View File

@@ -440,6 +440,19 @@ class CallStateManager {
this.hangUp(); // 房间已关闭,挂断连接
};
// SDP Answer 接收回调:重新设置编码参数以保障画质
this.renderstreaming.onGotAnswer = (connectionId) => {
console.log('SDP Answer received, resetting encoding parameters for connectionId:', connectionId);
if (this.role === 'host') {
const allParticipantIds = Object.keys(this.state.remoteStreams || {});
for (const pid of allParticipantIds) {
setTimeout(() => { this.setVideoEncodingParameters(pid); }, 50);
}
} else {
setTimeout(() => { this.setVideoEncodingParameters(); }, 50);
}
};
// participant加入回调host收到新participant加入房间
this.renderstreaming.onParticipantJoined = (participantId) => {
console.log(`Participant joined: ${participantId}`);
@@ -848,43 +861,46 @@ class CallStateManager {
* 优先选择 VP9/AV1更高效的压缩回退到 H264 High Profile
*/
setCodecPreferences(participantId) {
const { codecs } = RTCRtpSender.getCapabilities('video');
if (!codecs || codecs.length === 0) return;
const capabilities = RTCRtpSender.getCapabilities('video');
if (!capabilities || !capabilities.codecs || capabilities.codecs.length === 0) return;
const { codecs } = capabilities;
let selectedCodecs = null;
// 构建多codec优先级列表而非只选一个
let selectedCodecs = [];
// 优先级: AV1 > VP9 > H264 High Profile > H264
const av1Codec = codecs.find(c => c.mimeType === 'video/AV1');
const vp9Codec = codecs.find(c => c.mimeType === 'video/VP9');
// H264 High Profile 提供比 Baseline/Constrained Baseline 更好的画质
const h264HighCodec = codecs.find(c =>
c.mimeType === 'video/H264' &&
c.sdpFmtpLine && c.sdpFmtpLine.includes('profile-level-id=6400')
);
const h264Codec = codecs.find(c => c.mimeType === 'video/H264');
if (av1Codec) {
selectedCodecs = [av1Codec];
console.log('Selected codec: AV1');
} else if (vp9Codec) {
selectedCodecs = [vp9Codec];
console.log('Selected codec: VP9');
} else if (h264HighCodec) {
selectedCodecs = [h264HighCodec];
console.log('Selected codec: H264 High Profile');
} else if (h264Codec) {
selectedCodecs = [h264Codec];
console.log('Selected codec: H264');
}
if (av1Codec) selectedCodecs.push(av1Codec);
if (vp9Codec) selectedCodecs.push(vp9Codec);
if (h264HighCodec) selectedCodecs.push(h264HighCodec);
if (h264Codec && (!h264HighCodec || h264Codec !== h264HighCodec)) selectedCodecs.push(h264Codec);
if (selectedCodecs == null) return;
if (selectedCodecs.length === 0) return;
if (this.renderstreaming) {
const transceivers = this.renderstreaming.getTransceivers(participantId);
if (transceivers && transceivers.length > 0) {
const videoTransceivers = transceivers.filter(t => t.receiver.track.kind == "video");
const videoTransceivers = transceivers.filter(t => {
if (t.sender && t.sender.track) {
return t.sender.track.kind === 'video';
}
return t.mid !== null && t.receiver && t.receiver.track && t.receiver.track.kind === 'video';
});
if (videoTransceivers && videoTransceivers.length > 0) {
videoTransceivers.forEach(t => t.setCodecPreferences(selectedCodecs));
videoTransceivers.forEach(t => {
try {
t.setCodecPreferences(selectedCodecs);
} catch(e) {
console.error('Error setting codec preferences:', e);
}
});
console.log(`Codec preferences set: ${selectedCodecs.map(c => c.mimeType).join(' > ')}`);
}
}
}
@@ -914,8 +930,32 @@ class CallStateManager {
params.encodings = [{}];
}
// 设置最大比特率为 4Mbps1080p@30fps 良好画质)
params.encodings[0].maxBitrate = 4000000; // 4 Mbps = 4,000,000 bps
// 根据实际采集分辨率动态设置maxBitrate
const videoTrack = sender.track;
const settings = videoTrack ? videoTrack.getSettings() : {};
const height = settings.height || 1080;
const bitrateMap = {
270: 1000000,
480: 1500000,
720: 2500000,
1080: 4000000,
1440: 6000000
};
// 找到最接近的分辨率对应的比特率
let maxBitrate = 4000000;
const heights = Object.keys(bitrateMap).map(Number).sort((a, b) => a - b);
for (const h of heights) {
if (height <= h) {
maxBitrate = bitrateMap[h];
break;
}
maxBitrate = bitrateMap[h];
}
params.encodings[0].maxBitrate = maxBitrate;
params.encodings[0].scaleResolutionDownBy = 1.0;
params.encodings[0].xGoogleMinBitrate = Math.floor(maxBitrate * 0.5);
// 优先保持分辨率,降低帧率来适应带宽
// 'maintain-resolution' 在带宽不足时保持清晰度
@@ -924,7 +964,7 @@ class CallStateManager {
}
sender.setParameters(params);
console.log(`Set video encoding: maxBitrate=4Mbps, degradationPreference=maintain-resolution${participantId ? ` for ${participantId}` : ''}`);
console.log(`Set video encoding: maxBitrate=${maxBitrate / 1000000}Mbps, scaleResolutionDownBy=1.0, xGoogleMinBitrate=${Math.floor(maxBitrate * 0.5)}${participantId ? ` for ${participantId}` : ''}`);
} catch (error) {
console.error('Error setting video encoding parameters:', error);
}