하울링은 왜 생기는가?
하울링은 간단히 말하면, 자신의 마이크에서 들어온 소리가 다시 자신의 스피커로 출력되고,
그게 다시 마이크로 입력되면서 무한 루프를 타는 상황입니다.
WebRTC는 getUserMedia
로 마이크와 카메라를 활성화하고, 실시간으로 stream을 주고받기 때문에 이런 구조에서는 오디오 루프가 쉽게 생길 수 있습니다.
여러 방법을 시도해봤습니다
처음에는 아래와 같은 해결책들을 시도했습니다:
- 연결 직후 마이크를 자동으로 mute 처리
- local stream과 remote stream을 분리해 렌더링
- 오디오 트랙만 따로 추적해서 제어
<audio muted />
설정 (그러나 의도대로 안 되는 경우도 많음)
하지만 완벽하게 해결되진 않았고, 상황에 따라 다시 하울링이 발생했습니다.
실제로 적용 방법
결론적으로 아래 두 가지 조합으로 문제를 대부분 해결할 수 있었습니다.
1. getUserMedia
constraints에 echoCancellation 옵션 추가
브라우저에서 기본 제공하는 오디오 필터 기능을 활용했습니다.
navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true,
noiseSuppression: true,
},
video: true,
});
이 옵션을 명시적으로 넣었더니, 브라우저가 하울링을 줄이기 위해 자체적으로 오디오를 필터링해줍니다. 그리고 로컬 오디오 렌더링을 방지하기 위해
if (remoteUser.id !== localUser.id) {
videoElement.srcObject = remoteStream;
}
이 조건만 제대로 걸어줘도 자기 목소리를 다시 듣는 상황을 방지할 수 있었고, 하울링도 없어졌습니다.
마무리하며
WebRTC는 브라우저 환경에 따라 동작 차이가 크고, 작은 설정 하나로 사용자 경험이 크게 달라지기 때문에 하울링 같은 문제는 조기에 잡아두는 게 중요합니다.
이후에는 Agora SDK로 전환해 더 안정적인 연결 구조를 가져가게 되었지만, WebRTC 기반 구조에서도 기본 설정만 잘 해줘도 충분히 쓸 수 있다는 걸 경험했습니다.