하울링은 왜 생기는가?

하울링은 간단히 말하면, 자신의 마이크에서 들어온 소리가 다시 자신의 스피커로 출력되고,

그게 다시 마이크로 입력되면서 무한 루프를 타는 상황입니다.

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 기반 구조에서도 기본 설정만 잘 해줘도 충분히 쓸 수 있다는 걸 경험했습니다.