webrtcHacks / adapter

Shim to insulate apps from spec changes and prefix differences. Latest adapter.js release:

Home Page:https://webrtcHacks.github.io/adapter/adapter-latest.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RTCPeerConnection.setLocalDescription() without arguments fails on Safari 13.1 (macOS Catalina 10.15.4) with TypeError: Argument 1 ('description') to RTCPeerConnection.setLocalDescription must be an instance of RTCSessionDescription

rhansen opened this issue · comments

Please read first!

Please use discuss-webrtc for general technical discussions and questions.

  • I have provided steps to reproduce (e.g. a link to a jsfiddle)
  • I have provided browser name, version and adapter.js version
  • This issue only happens when adapter.js is used (kinda, see below)

Note: If the checkboxes above are not checked (which you do after the issue is posted), the issue will be closed.

Versions affected

Browser name including version (e.g. Chrome 64.0.3282.119)
Safari Version 13.1 (15609.1.20.111.8)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15

adapter.js (e.g. 6.1.0)
8.0.0

Description

Calling RTCPeerConnection.setLocalDescription() without any arguments in Safari 13.1 (macOS Catalina 10.15.4) fails with:

TypeError: Argument 1 ('description') to RTCPeerConnection.setLocalDescription must be an instance of RTCSessionDescription

Steps to reproduce

https://jsfiddle.net/60ne23pb/1/

const ctx = new (window.AudioContext || webkitAudioContext)();
const gain = ctx.createGain();
const {stream} = gain.connect(ctx.createMediaStreamDestination());
const track = stream.getAudioTracks()[0];

const pc = new RTCPeerConnection({});
pc.addEventListener('negotiationneeded', async () => {
  await pc.setLocalDescription();
});
pc.addTrack(track, stream);

Expected results

It should behave according to the spec:

Passing in a description is optional. If left out, then setLocalDescription will implicitly create an offer or create an answer, as needed.

Actual results

Throws the following exception:

TypeError: Argument 1 ('description') to RTCPeerConnection.setLocalDescription must be an instance of RTCSessionDescription

Removing adapter.js changes the behavior slightly; it instead throws:

TypeError: Not enough arguments

tagging @youennf who might know which Safari version this is supported in.
@jan-ivar might have an opinion on polyfilling it (checking RTCPeerConnection.prototype.setLocalDescription.length might work).

i'd not recommend using the parameterless stuff in production.

From bug 174656 it doesn't look like Safari supports perfect negotiation yet.

The perfect negotiation pattern aims to solve intermittent failures caused by glare (inherent timing races between two parties) seen in most other WebRTC negotiation patterns. Such failures are typically in the <5% range.

A polyfill would allow sites to write negotiation code with 0% glare on browsers that support perfect negotiation.

A polyfill might marginally improve, but not guarantee 0% glare, on browsers that don't support perfect negotiation natively.

But speaking more narrowly to this issue, pc.setLocalDescription() (without arguments) appears to start working with Safari Tech Preview 14.2 for me.

It turns out this is pretty hard to polyfill correctly when the operations chain is not empty, since the implicit calls to createOffer/Answer are supposed to happen when SLD comes off the chain, not when it goes on it.

Looks like support for parameterless setLocalDescription() was added to WebKit in WebKit/WebKit@07a6779, which is in WebKit 610.1.8 (Safari tech preview 104) and later.

the implicit calls to createOffer/Answer are supposed to happen when SLD comes off the chain, not when it goes on it.

I take it there is no way to reach into the internals and push an arbitrary function onto the operations chain?

Would polyfilling it the simple-but-technically-incorrect way be worse than not polyfilling at all? I'm guessing that an imperfect polyfill written by subject matter experts would be better than what amateurs like myself would do.

I take it there is no way to reach into the internals and push an arbitrary function onto the operations chain?

@rhansen Unfortunately there isn't.

Would polyfilling it the simple-but-technically-incorrect way be worse than not polyfilling at all? I'm guessing that an imperfect polyfill written by subject matter experts would be better than what amateurs like myself would do.

I've mocked up a PR, if someone wants to volunteer to test it and carry it over the finish line.

commented

Looks like support for parameterless setLocalDescription() was added to WebKit in WebKit/WebKit@07a6779, which is in WebKit 610.1.8 (Safari tech preview 104) and later.

As far as I can tell, support for parameterless setLocalDescription() was actually added in WebKit/WebKit@4aacc63 (5 months after the one you linked to). which is in WebKit 611.1.1 and was released in Safari 14.1.

From the commit message there:

Also update setLocalDescription to take no parameters.

published as 8.1.0 on npm. Both gh-pages repos have been updated.