Bug 198402 - iOS 12.3 and 12.4 emit PeerConnection SDP offer m-lines in random order
Summary: iOS 12.3 and 12.4 emit PeerConnection SDP offer m-lines in random order
Status: RESOLVED CONFIGURATION CHANGED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebRTC (show other bugs)
Version: Safari Technology Preview
Hardware: iPhone / iPad iOS 12
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-05-30 18:35 PDT by Chad Phillips
Modified: 2019-06-06 10:45 PDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chad Phillips 2019-05-30 18:35:57 PDT
In iOS 12.2 and prior, WebRTC PeerConnection offers generated from iOS always structured the SDP such that the audio m-lines came first, and the video m-lines came second.

iOS 12.3 and 12.4 no longer works this way, instead it structures the SDP audio/video m-lines seemingly randomly, sometimes putting the audio m-lines first, sometimes the video m-lines first.

Is this a regression? I'm asking because it breaks compatibility with a popular WebRTC server, which always sends its SDP answers with the audio m-lines first, and video m-lines second. In the case of iOS sending its video m-lines first, this results in the following error when setRemoteDescription() is called with the answer SDP: InvalidAccessError: Failed to set remote answer sdp: The order of m-lines in answer doesn't match order in offer. Rejecting answer.

If this is not a regression, then it would be helpful if you could describe how to munge the answer SDP properly to get around the error message above. I've tried simply extracting all related video m-lines and moving them after the audio m-lines, as in this before/after example, but it fails with "SyntaxError: Invalid SDP line": https://pastebin.com/ZGv7mSqL
Comment 1 youenn fablet 2019-05-30 21:56:24 PDT
Hi Chad,

Can you make sure to call addTrack(audio) first and addTrack(video) second?
If you do not have a video track initially, I would think calling addTransceiver('audio') and then using sender.replaceTrack to do the trick to make sure to have the audio track first.
If you handle only one audio and one video track, that should be ok to handle properly this way.

I would think the munging should work as well though a slight typo sometimes make it hard to debug. If you have a jsfiddle, I can try to help further.
Comment 2 youenn fablet 2019-05-30 22:02:14 PDT
Would it be possible you added an extra empty line somewhere during munging?
Comment 3 Chad Phillips 2019-05-31 10:59:14 PDT
youenn,

Thanks for your replies, very helpful!

Two things:

1. Adding the media tracks via addTrack() in the specific order I want does indeed fix the issue.

2. The munged SDP was failing because it was missing a trailing \r\n after the last line. This seems like a silly reason to fail SDP parsing, perhaps that can be rectified? At the very least, an SDP parsing error should include some more helpful output for the developer!

3. The adapter.js 'addStream' shim for Safari uses stream.getTracks() internally to then call addTrack() on all the tracks in the stream. Is it possible that the Webkit implementation of getTracks() returns the media tracks in random order?
Comment 4 youenn fablet 2019-05-31 11:06:40 PDT
(In reply to Chad Phillips from comment #3)
> youenn,
> 
> Thanks for your replies, very helpful!
> 
> Two things:
> 
> 1. Adding the media tracks via addTrack() in the specific order I want does
> indeed fix the issue.

Nice

> 2. The munged SDP was failing because it was missing a trailing \r\n after
> the last line. This seems like a silly reason to fail SDP parsing, perhaps
> that can be rectified? At the very least, an SDP parsing error should
> include some more helpful output for the developer!

You are not the first one caught up in this area.
This error message is usually a signal of such kind of error, agreed it is not very clear though.

> 3. The adapter.js 'addStream' shim for Safari uses stream.getTracks()
> internally to then call addTrack() on all the tracks in the stream. Is it
> possible that the Webkit implementation of getTracks() returns the media
> tracks in random order?

Tracks are stored in a map internally whose key is the stream id.
But this is implementation dependent and the spec does not require any specific order, nor should implementations rely on that.
adapter.js could be of some help there by doing getAudioTracks/getVideoTracks so as to preserve the old behavior.

I'll close the bug, please reopen it if needed.
Comment 5 Chad Phillips 2019-06-06 10:45:51 PDT
FYI, a workaround landed in adapter.js, v7.2.4: https://github.com/webrtcHacks/adapter/commit/e823e5847a727c5e01862fd72eb5ed0091a3ac30