Tech 2 min read

Audio Feedback Prevention: Easy-to-Miss Tips for Web Meetings and WebRTC

Someone across the desk was building a video call app and ran into brutal audio feedback. The cause was simple: they forgot muted on the local preview. I tend to forget this too, so leaving a note.

How feedback happens

マイク → 送信 → 相手のスピーカー

相手のマイク ← 拾う ←┘

自分のスピーカー ← 受信

自分のマイク ← 拾う ←┘

     無限ループ

Sound that comes out of the speakers enters the mic, gets sent back to the other side… and repeats. This occurs regardless of the transport (WebSocket, WebRTC, Agora, etc.).

Fix 1: Mute local playback (most important)

When previewing your own camera, always mute the audio.

// ローカルプレビュー用
const localVideo = document.getElementById('local-video');
localVideo.srcObject = localStream;
localVideo.muted = true;  // これがないとハウリング

Do not mute the remote media.

// リモート(相手)の映像・音声
const remoteVideo = document.getElementById('remote-video');
remoteVideo.srcObject = remoteStream;
// muted は設定しない(相手の声が聞こえなくなる)

Fix 2: Enable echo cancellation

Enable echo cancellation when obtaining the mic with getUserMedia.

const stream = await navigator.mediaDevices.getUserMedia({
  audio: {
    echoCancellation: true,   // エコーキャンセル
    noiseSuppression: true,   // ノイズ抑制
    autoGainControl: true     // 自動ゲイン調整
  },
  video: true
});

The browser compares “what goes out of the speakers” with “what comes into the mic” and removes the echo component.

Fix 3: Hardware measures

Fallbacks when software mitigation isn’t enough.

  • Use headphones - Physically breaks the loop
  • Increase distance between speaker and mic - Reduces the echo canceller’s load
  • Use a directional mic - Picks up less sound from the speakers’ direction

People who get feedback in web meetings are usually on speakers and echo cancellation isn’t doing enough. Switching to headphones fixes it instantly.

Independent of transport

Feedback mitigation is independent of the transport layer.

TransportFeedback Mitigation
WebRTCSame
WebSocket + MediaRecorderSame
Agora / TwilioSame
LiveKitSame

“How you move the data” and “how you handle audio I/O” are different layers. No matter what tech you use, if the browser plays local audio through the speakers, you’ll get feedback.

Checklist

Things to confirm during implementation.

  • Local <video> / <audio> has the muted attribute
  • getUserMedia specifies echoCancellation: true
  • Remote stream is not muted
  • During testing, take off headphones and verify with speakers

The last one is especially important. If you develop while wearing headphones, you won’t notice.