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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
521214
13539