On the Road to WebRTC 1.0, Including VP8

Safari 11 was the first Safari version to support WebRTC. Since then, we have worked to continue improving WebKit’s implementation and compliance with the spec. I am excited to announce major improvements to WebRTC in Safari 12.1 on iOS 12.2 and macOS 10.14.4 betas, including VP8 video codec support, video simulcast support and Unified Plan SDP (Session Description Protocol) experimental support.

VP8 Video Codec

The VP8 video codec is widely used in existing WebRTC solutions. It is now supported as a WebRTC-only video codec in Safari 12.1 on both iOS and macOS betas. By supporting both VP8 and H.264, Safari 12.1 can exchange video with any other WebRTC endpoint. H.264 is the default codec for Safari because it is backed by hardware acceleration and tuned for real-time communication. This provides a great user experience and power efficiency. We found that, on an iPhone 7 Plus in laboratory conditions, the use of H.264 on a 720p video call increases the battery life by up to an hour compared to VP8. With H.264, VP8 and Unified Plan, Safari can mix H.264 and VP8 on a single connection. It is as simple as doing the following:

const localStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
var pc = new RTCPeerConnection();
// Create a transceiver to send video.
pc.addTransceiver('video', { direction: 'sendonly'}).sender.replaceTrack(localStream.getVideoTracks()[0]);
// Create a transceiver to receive video.
pc.addTransceiver('video', { direction: 'recvonly'});
// Send the offer to the other party.
sendOffer(await pc.createOffer());
// Other party selects H.264 for the 1st transceiver and VP8 for the 2nd transceiver.

Video Simulcast

To further improve WebRTC support for multi-party video conferencing, simulcast is now supported for both H.264 and VP8. Kudos to the libwebrtc community, including Cosmo Software, for making great progress in that important area. Simulcast is a technique that encodes the same video content with different encoding parameters, typically different frame sizes and bit rates. This is particularly useful when the same content is sent to several clients through a central server, called an SFU. As the clients might have different constraints (screen size, network conditions), the SFU is able to send the most suitable stream to each client. Each individual encoding can be controlled using RTCRtpSender.setParameters on the sender side. Simulcast is currently activated using SDP munging. Future work should allow simulcast activation using RTCPeerConnection.addTransceiver, as per specification.

Unified Plan

WebRTC uses SDP as the format for negotiating the configuration of a connection. While previous versions of Safari used Plan B SDP only, Safari is now transitioning to the standardized version known as Unified Plan SDP. Unified Plan SDP can express WebRTC configurations in a much more flexible way, as each audio or video stream transmission can be configured independently.

If your website uses at most one audio and one video track per connection, this transition should not require any major changes. If your website uses connections with more audio or video tracks, adoption may be required. With Unified Plan SDP enabled, the support of the WebRTC 1.0 API, in particular the transceiver API, is more complete and spec-compliant than ever. To detect whether Safari uses Unified Plan, you can use feature detection:

function usesUnifiedPlan()
{
return RTCRtpTransceiver.prototype.hasOwnProperty("currentDirection”);
}

Unified Plan is an experimental feature that is currently turned on by default in Safari Technology Preview and turned off by default in Safari in iOS 12.2 and macOS 10.14.4 betas. This can be turned on using the Develop menu on macOS and Safari settings on iOS.

Additional API updates

Safari also comes with additional improvements, including better support of capture device selection, experimental support of the screen capture API, and deprecation of the WebRTC legacy API.

Web applications sometimes want to select the same capture devices used on a previous call. Device IDs will remain stable across browsing sessions as soon as navigator.mediaDevices.getUserMedia is successfully called once. Your web page can implement persistent device selection as follows:

let stream;
let deviceId = window.localStorage.getItem('preferredMicrophoneId');
const constraint = deviceId ? {audio : {deviceId: {exact: deviceId}}} : {audio: true};
try {
stream = await navigator.mediaDevices.getUserMedia(constraint);
} catch (e) {
// ...
}
deviceId = stream.getAudioTracks()[0].getSettings().deviceId;
window.localStorage.setItem('preferredMicrophoneId', deviceId);

Existing fingerprinting mitigations remain in place, including the filtering of information provided by navigator.mediaDevices.enumerateDevices as detailed in the blog post, “A Closer Look Into WebRTC”.

Initial support of the screen capture API is now available as an experimental feature in Safari Technology Preview. By calling navigator.mediaDevices.getDisplayMedia, a web application can capture the main screen on macOS.

Following the strategy detailed in “A Closer Look Into WebRTC”, the WebRTC legacy API was disabled by default in Safari 12.0. Support for the WebRTC legacy API is removed from iOS 12.2 and macOS 10.14.4 betas. Should your application need support of the WebRTC legacy API, we recommend the use of the open source adapter.js library as a polyfill.

Feedback

We always appreciate your feedback. Send us bug reports, or feel free to tweet @webkit on Twitter, or email web-evangelist@apple.com.