Audio

For audio streams, we use the browser defaults. We don't currently have hooks in our API for setting "audio constraints," but we are working on adding them. The default for Chrome is currently 40kb/s mono using the Opus codec, which is generally considered "full quality" for voice. It's much better than telephone-quality audio, but not as good for delivering music as higher bitrate encodings.

If you have a specific need to support music, we can provide sample code that is helpful for some use cases.

Video

There are two things that determine the quality of video that someone is sending to another peer (or the server): The requested image resolution from the camera, and the bandwidth settings sent to the video encoder. We combine both of these into our setBandwidth() API call.

By default, we request a video track with an ideal and maximum resolution of 1280x720, and a minimum aspect ratio of 1.777. This means that most modern webcams will return a 1280x720 track, but depending on the camera, the track might have somewhat different dimensions—as close as possible to 'ideal' without violating the maximums or minimums.

In peer-to-peer calls, the browsers negotiate encoding bitrate between themselves based on network conditions, and each participant sends a single camera stream with that bitrate to the other participants.

In server-based calls, each participant can actually send multiple video streams to the server. These streams are called 'simulcast encodings' or 'spatial layers'. The highest-quality video track (also called the highest spatial layer) typically uses whatever resolution the camera is providing, and the browser creates the lower spatial layers by scaling the video down and reducing the bandwidth used by the encoder.

We set defaults for these layers based on our experience-based compromise between quality and performance. The top spatial layer is specified as 680kbps, 30fps, and full-resolution video (typically 1280x720 as described above). The middle layer is 200kbps, 15fps, and scaled down by a factor of 2 (nominally 640x360). The lowest spatial layer is 80kbps, 10fps, and scaled down by 4 (320x180). We adjust these defaults periodically to take advantage of improvements in the underlying capabilities of Chrome, Safari, and Firefox.

Sending specific video resolution

We default to acquiring the camera video track at 1280x720, and to sending three simulcast layers:

These are good general quality settings for typical video use cases. 680kb/s is fairly high quality for real-time video, and the total bitrate of all three simulcast layers is just under 1Mb/s, which is a good rule of thumb for outbound UDP traffic that a wide variety of real-world network connections will handle well.

If you are sending something smaller, like a 160x160 video track, Chrome will only encode and send a single simulcast layer. But you may want to change the bitrate of that lower layer. For clients that are only ever sending 160x160 video, you could do this, for example:

const call = Daily.createCallObject({
  subscribeToTracksAutomatically: false,
  dailyConfig: {
    // turns the hardware light off when camera is muted
    experimentalChromeVideoMuteLightOff: true,
    // sets simulcast encoding for a single outbound layer
    // to 220 kb/s and 15fps
    camSimulcastEncodings: [
      {
        maxBitrate: 220000,
        maxFramerate: 15,
      },
    ],
  },
 });

We are happy to help you test bitrates and simulcast layer configurations. If some clients need to both broadcast to everyone and send 160x160 resolution small videos we can provide sample code.