【m】回声抑制
This commit is contained in:
@@ -10,5 +10,29 @@ export function getRTCConfiguration() {
|
||||
let config = {};
|
||||
config.sdpSemantics = 'unified-plan';
|
||||
config.iceServers = getServers();
|
||||
|
||||
// 添加音频处理选项,增强回声消除
|
||||
config.mediaConstraints = {
|
||||
audio: {
|
||||
echoCancellation: true,
|
||||
noiseSuppression: true,
|
||||
autoGainControl: true,
|
||||
highpassFilter: true,
|
||||
typingNoiseDetection: true
|
||||
}
|
||||
};
|
||||
|
||||
// 添加WebRTC音频处理选项
|
||||
config.rtcConfiguration = {
|
||||
'googEchoCancellation': true,
|
||||
'googEchoCancellation2': true,
|
||||
'googNoiseSuppression': true,
|
||||
'googNoiseSuppression2': true,
|
||||
'googAutoGainControl': true,
|
||||
'googAutoGainControl2': true,
|
||||
'googHighpassFilter': true,
|
||||
'googTypingNoiseDetection': true
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -75,10 +75,14 @@ class CallStateManager {
|
||||
throw new Error('getUserMedia is not supported');
|
||||
}
|
||||
|
||||
// 请求摄像头权限并获取媒体流
|
||||
// 请求摄像头权限并获取媒体流,启用回声消除
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: true
|
||||
audio: {
|
||||
echoCancellation: true,
|
||||
noiseSuppression: true,
|
||||
autoGainControl: true
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Stream obtained successfully:', stream);
|
||||
@@ -133,24 +137,33 @@ class CallStateManager {
|
||||
});
|
||||
await this.getLocalStream();
|
||||
|
||||
// 更新WebRTC连接中的视频轨道
|
||||
// 更新WebRTC连接中的媒体轨道
|
||||
if (this.renderstreaming) {
|
||||
console.log('Updating video track in WebRTC connection');
|
||||
console.log('Updating media tracks in WebRTC connection');
|
||||
|
||||
// 获取所有收发器
|
||||
const transceivers = this.renderstreaming.getTransceivers();
|
||||
console.log('All transceivers:', transceivers);
|
||||
|
||||
// 查找现有的视频收发器
|
||||
// 查找现有的视频和音频收发器
|
||||
const videoTransceivers = transceivers.filter(t => {
|
||||
return t.sender && t.sender.track && t.sender.track.kind === 'video';
|
||||
});
|
||||
console.log('Found video transceivers:', videoTransceivers);
|
||||
|
||||
// 获取新的视频轨道
|
||||
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 (videoTracks.length > 0) {
|
||||
const newVideoTrack = videoTracks[0];
|
||||
console.log('Using new video track:', newVideoTrack);
|
||||
@@ -176,12 +189,40 @@ class CallStateManager {
|
||||
console.error('Error adding new video transceiver:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 延迟设置编解码器偏好,确保收发器已完全创建
|
||||
setTimeout(() => {
|
||||
this.setCodecPreferences();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 更新音频轨道
|
||||
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);
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 延迟设置编解码器偏好,确保收发器已完全创建
|
||||
setTimeout(() => {
|
||||
this.setCodecPreferences();
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
// 直接更新媒体状态
|
||||
@@ -244,11 +285,19 @@ class CallStateManager {
|
||||
// 创建信令实例
|
||||
const signaling = this.useWebSocket ? new WebSocketSignaling() : new Signaling();
|
||||
const config = getRTCConfiguration(); // 获取RTC配置
|
||||
// 优化RTC配置,确保支持高分辨率
|
||||
// 优化RTC配置,确保支持高分辨率和良好的音频处理
|
||||
config.peerConnectionOptions = {
|
||||
optional: [
|
||||
{ googCpuOveruseDetection: false }, // 禁用CPU过度使用检测
|
||||
{ googScreencastMinBitrate: 3000 } // 设置最小比特率
|
||||
{ googScreencastMinBitrate: 3000 }, // 设置最小比特率
|
||||
{ googEchoCancellation: true }, // 启用回声消除
|
||||
{ googEchoCancellation2: true }, // 启用高级回声消除
|
||||
{ googNoiseSuppression: true }, // 启用噪声抑制
|
||||
{ googNoiseSuppression2: true }, // 启用高级噪声抑制
|
||||
{ googAutoGainControl: true }, // 启用自动增益控制
|
||||
{ googAutoGainControl2: true }, // 启用高级自动增益控制
|
||||
{ googHighpassFilter: true }, // 启用高通滤波器
|
||||
{ googTypingNoiseDetection: true } // 启用打字噪声检测
|
||||
]
|
||||
};
|
||||
this.renderstreaming = new RenderStreaming(signaling, config); // 创建WebRTC连接管理实例
|
||||
|
||||
Reference in New Issue
Block a user