5
votes

Given a WebRTC PeerConnection between two clients, one client is trying to send an audio MediaStream to another.

If this MediaStream is an Oscillator at 440hz - everything works fine. The audio is very crisp, and the transmission goes through correctly.

However, if the audio is at 20000hz, the audio is very noisy and crackly - I expect to hear nothing, but I hear a lot of noise instead.

I believe this might be a problem of sample rate sent in the connection, maybe its not sending the audio at 48000samples/second like I expect. Is there a way for me to increase the sample rate?

Here is a fiddle to reproduce the issue: https://jsfiddle.net/mb3c5gw1/9/

Minimal reproduction code including a visualizer:

<button id="btn">start</button>
<canvas id="canvas"></canvas>

<script>class OscilloMeter{constructor(a){this.ctx=a.getContext("2d")}listen(a,b){function c(){g.getByteTimeDomainData(j),d.clearRect(0,0,e,f),d.beginPath();let a=0;for(let c=0;c<h;c++){const e=j[c]/128;var b=e*f/2;d.lineTo(a,b),a+=k}d.lineTo(canvas.width,canvas.height/2),d.stroke(),requestAnimationFrame(c)}const d=this.ctx,e=d.canvas.width,f=d.canvas.height,g=b.createAnalyser(),h=g.fftSize=256,j=new Uint8Array(h),k=e/h;d.lineWidth=2,a.connect(g),c()}}</script>
btn.onclick = e => {

  const ctx = new AudioContext();

  const source = ctx.createMediaStreamDestination();

  const oscillator = ctx.createOscillator();

  oscillator.type = 'sine';
  oscillator.frequency.setValueAtTime(20000, ctx.currentTime); // value in hertz
  oscillator.connect(source);
  oscillator.start();



  // a visual cue of AudioNode out (uses an AnalyserNode)
  const meter = new OscilloMeter(canvas);

  const pc1 = new RTCPeerConnection(),
    pc2 = new RTCPeerConnection();

  pc2.ontrack = ({
    track
  }) => {
    const endStream = new MediaStream([track]);
    const src = ctx.createMediaStreamSource(endStream);
    
    const audio = new Audio();
    audio.srcObject = endStream;
    meter.listen(src, ctx);
    audio.play()
  };

  pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
  pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
  pc1.oniceconnectionstatechange = e => console.log(pc1.iceConnectionState);
  pc1.onnegotiationneeded = async e => {
    try {
      await pc1.setLocalDescription(await pc1.createOffer());
      await pc2.setRemoteDescription(pc1.localDescription);
      await pc2.setLocalDescription(await pc2.createAnswer());
      await pc1.setRemoteDescription(pc2.localDescription);
    } catch (e) {
      console.error(e);
    }
  }


  const stream = source.stream;
  pc1.addTrack(stream.getAudioTracks()[0], stream);

};
1
Probably via stream constraints and settings. developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/… - AKX
Thanks @AKX, the track I send is of high bitrate, and if I just play it, 20khz work perfectly However, this compression or something happens only when I transmit this track, meaning it has to do with WebRTC - Amit
need more settings rather than human voice if you need transmit high quality audio, @Amit - ssskip

1 Answers

0
votes

Looking around in the webrtc demo i found this: https://webrtc.github.io/samples/src/content/peerconnection/audio/ in the example they show a dropdown where you can setup the audio codec. I think this is your solution.