webrtc-adapter
Advanced tools
Comparing version 3.1.7 to 3.2.0
{ | ||
"name": "webrtc-adapter", | ||
"version": "3.1.7", | ||
"version": "3.2.0", | ||
"description": "A shim to insulate apps from WebRTC spec changes and browser prefix differences", | ||
@@ -5,0 +5,0 @@ "license": "BSD-3-Clause", |
@@ -280,2 +280,20 @@ /* | ||
}; | ||
var findCodecByPayloadType = function(pt, codecs) { | ||
pt = parseInt(pt, 10); | ||
for (var i = 0; i < codecs.length; i++) { | ||
if (codecs[i].payloadType === pt || | ||
codecs[i].preferredPayloadType === pt) { | ||
return codecs[i]; | ||
} | ||
} | ||
}; | ||
var rtxCapabilityMatches = function(lRtx, rRtx, lCodecs, rCodecs) { | ||
var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs); | ||
var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs); | ||
return lCodec && rCodec && | ||
lCodec.name.toLowerCase() === rCodec.name.toLowerCase(); | ||
}; | ||
localCapabilities.codecs.forEach(function(lCodec) { | ||
@@ -286,2 +304,12 @@ for (var i = 0; i < remoteCapabilities.codecs.length; i++) { | ||
lCodec.clockRate === rCodec.clockRate) { | ||
if (lCodec.name.toLowerCase() === 'rtx' && | ||
lCodec.parameters && rCodec.parameters.apt) { | ||
// for RTX we need to find the local rtx that has a apt | ||
// which points to the same local codec as the remote one. | ||
if (!rtxCapabilityMatches(lCodec, rCodec, | ||
localCapabilities.codecs, remoteCapabilities.codecs)) { | ||
continue; | ||
} | ||
} | ||
rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy | ||
// number of channels is the highest common number of channels | ||
@@ -443,3 +471,4 @@ rCodec.numChannels = Math.min(lCodec.numChannels, | ||
if (transceiver.kind === 'video' | ||
&& transceiver.recvEncodingParameters) { | ||
&& transceiver.recvEncodingParameters | ||
&& browserDetails.version < 15019) { | ||
transceiver.recvEncodingParameters.forEach(function(p) { | ||
@@ -668,6 +697,8 @@ delete p.rtx; | ||
// in adapter.js | ||
localCapabilities.codecs = localCapabilities.codecs.filter( | ||
function(codec) { | ||
return codec.name !== 'rtx'; | ||
}); | ||
if (browserDetails.version < 15019) { | ||
localCapabilities.codecs = localCapabilities.codecs.filter( | ||
function(codec) { | ||
return codec.name !== 'rtx'; | ||
}); | ||
} | ||
@@ -678,9 +709,12 @@ sendEncodingParameters = [{ | ||
rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind); | ||
if (direction === 'sendrecv' || direction === 'sendonly') { | ||
rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, | ||
kind); | ||
track = rtpReceiver.track; | ||
receiverList.push([track, rtpReceiver]); | ||
// FIXME: not correct when there are multiple streams but that is | ||
// not currently supported in this shim. | ||
stream.addTrack(track); | ||
track = rtpReceiver.track; | ||
receiverList.push([track, rtpReceiver]); | ||
// FIXME: not correct when there are multiple streams but that | ||
// is not currently supported in this shim. | ||
stream.addTrack(track); | ||
} | ||
@@ -697,2 +731,8 @@ // FIXME: look at direction. | ||
if (localTrack) { | ||
// add RTX | ||
if (browserDetails.version >= 15019 && kind === 'video') { | ||
sendEncodingParameters[0].rtx = { | ||
ssrc: (2 * sdpMLineIndex + 2) * 1001 + 1 | ||
}; | ||
} | ||
rtpSender = new RTCRtpSender(localTrack, | ||
@@ -989,6 +1029,8 @@ transports.dtlsTransport); | ||
// in adapter.js | ||
localCapabilities.codecs = localCapabilities.codecs.filter( | ||
function(codec) { | ||
return codec.name !== 'rtx'; | ||
}); | ||
if (browserDetails.version < 15019) { | ||
localCapabilities.codecs = localCapabilities.codecs.filter( | ||
function(codec) { | ||
return codec.name !== 'rtx'; | ||
}); | ||
} | ||
localCapabilities.codecs.forEach(function(codec) { | ||
@@ -1011,2 +1053,8 @@ // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552 | ||
if (track) { | ||
// add RTX | ||
if (browserDetails.version >= 15019 && kind === 'video') { | ||
sendEncodingParameters[0].rtx = { | ||
ssrc: (2 * sdpMLineIndex + 1) * 1001 + 1 | ||
}; | ||
} | ||
rtpSender = new RTCRtpSender(track, transports.dtlsTransport); | ||
@@ -1013,0 +1061,0 @@ } |
@@ -87,2 +87,10 @@ /* | ||
}; | ||
var rtx = { | ||
name: 'rtx', | ||
kind: 'video', | ||
clockRate: 90000, | ||
preferredPayloadType: 101, | ||
numChannels: 1, | ||
parameters: {apt: 100} | ||
}; | ||
var codecs; | ||
@@ -94,6 +102,6 @@ switch (kind) { | ||
case 'video': | ||
codecs = [vp8]; | ||
codecs = [vp8, rtx]; | ||
break; | ||
default: | ||
codecs = [opus, vp8]; | ||
codecs = [opus, vp8, rtx]; | ||
break; | ||
@@ -748,3 +756,3 @@ } | ||
it.skip('responds with a inactive answer to inactive', (done) => { | ||
it('responds with a inactive answer to inactive', (done) => { | ||
pc.setRemoteDescription({type: 'offer', sdp: sdp.replace('sendrecv', | ||
@@ -784,10 +792,3 @@ 'recvonly')}) | ||
it.skip('responds with a sendonly answer to recvonly', (done) => { | ||
const audioTrack = new MediaStreamTrack(); | ||
audioTrack.kind = 'audio'; | ||
const videoTrack = new MediaStreamTrack(); | ||
videoTrack.kind = 'video'; | ||
const stream = new MediaStream([audioTrack, videoTrack]); | ||
pc.addStream(stream); | ||
it('responds with a sendonly answer to recvonly', (done) => { | ||
pc.setRemoteDescription({type: 'offer', sdp: sdp.replace('sendrecv', | ||
@@ -820,3 +821,3 @@ 'recvonly')}) | ||
it.skip('responds with a inactive answer to recvonly', (done) => { | ||
it('responds with a inactive answer to recvonly', (done) => { | ||
pc.setRemoteDescription({type: 'offer', sdp: sdp.replace('sendrecv', | ||
@@ -835,3 +836,62 @@ 'recvonly')}) | ||
}); | ||
describe('after a video offer with RTX', () => { | ||
const sdp = 'v=0\r\no=- 166855176514521964 2 IN IP4 127.0.0.1\r\n' + | ||
's=-\r\nt=0 0\r\na=msid-semantic: WMS\r\n' + | ||
'm=video 9 UDP/TLS/RTP/SAVPF 102 103\r\n' + | ||
'c=IN IP4 0.0.0.0\r\n' + | ||
'a=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:foo\r\na=ice-pwd:bar\r\n' + | ||
'a=fingerprint:sha-256 so:me:co:lo:ns\r\n' + | ||
'a=setup:actpass\r\n' + | ||
'a=mid:video1\r\n' + | ||
'a=sendrecv\r\na=rtcp-mux\r\n' + | ||
'a=rtcp-rsize\r\n' + | ||
'a=rtpmap:102 vp8/90000\r\n' + | ||
'a=rtpmap:103 rtx/90000\r\n' + | ||
'a=fmtp:103 apt=102\r\n' + | ||
'a=ssrc-group:FID 1001 1002\r\n' + | ||
'a=ssrc:1001 msid:stream1 track1\r\n' + | ||
'a=ssrc:1001 cname:some\r\n' + | ||
'a=ssrc:1002 msid:stream1 track1\r\n' + | ||
'a=ssrc:1002 cname:some\r\n'; | ||
describe('with no local track', () => { | ||
it('creates an answer with RTX but no FID group', (done) => { | ||
pc.setRemoteDescription({type: 'offer', sdp: sdp}) | ||
.then(() => { | ||
return pc.createAnswer(); | ||
}) | ||
.then((answer) => { | ||
expect(answer.sdp).to.contain('a=rtpmap:102 vp8'); | ||
expect(answer.sdp).to.contain('a=rtpmap:103 rtx'); | ||
expect(answer.sdp).to.contain('a=fmtp:103 apt=102'); | ||
expect(answer.sdp).not.to.contain('a=ssrc-group:FID'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('with a local track', () => { | ||
beforeEach(() => { | ||
const videoTrack = new MediaStreamTrack(); | ||
videoTrack.kind = 'video'; | ||
const stream = new MediaStream([videoTrack]); | ||
pc.addStream(stream); | ||
}); | ||
it('creates an answer with RTX', (done) => { | ||
pc.setRemoteDescription({type: 'offer', sdp: sdp}) | ||
.then(() => { | ||
return pc.createAnswer(); | ||
}) | ||
.then((answer) => { | ||
expect(answer.sdp).to.contain('a=rtpmap:102 vp8'); | ||
expect(answer.sdp).to.contain('a=rtpmap:103 rtx'); | ||
expect(answer.sdp).to.contain('a=fmtp:103 apt=102'); | ||
expect(answer.sdp).to.contain('a=ssrc-group:FID 2002 2003'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
521214
13539