Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
5fa0a04b
提交
5fa0a04b
authored
2月 09, 2018
作者:
Brian West
提交者:
Muteesa Fred
7月 24, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update adapter.js
上级
99d2e5e2
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
717 行增加
和
422 行删除
+717
-422
adapter-latest.js
html5/verto/js/src/vendor/adapter-latest.js
+717
-422
verto-min.js
html5/verto/video_demo-live_canvas/js/verto-min.js
+0
-0
verto-min.js
html5/verto/video_demo/js/verto-min.js
+0
-0
没有找到文件。
html5/verto/js/src/vendor/adapter-latest.js
浏览文件 @
5fa0a04b
...
@@ -25,9 +25,7 @@ function writeMediaSection(transceiver, caps, type, stream, dtlsRole) {
...
@@ -25,9 +25,7 @@ function writeMediaSection(transceiver, caps, type, stream, dtlsRole) {
sdp
+=
'a=mid:'
+
transceiver
.
mid
+
'
\
r
\
n'
;
sdp
+=
'a=mid:'
+
transceiver
.
mid
+
'
\
r
\
n'
;
if
(
transceiver
.
direction
)
{
if
(
transceiver
.
rtpSender
&&
transceiver
.
rtpReceiver
)
{
sdp
+=
'a='
+
transceiver
.
direction
+
'
\
r
\
n'
;
}
else
if
(
transceiver
.
rtpSender
&&
transceiver
.
rtpReceiver
)
{
sdp
+=
'a=sendrecv
\
r
\
n'
;
sdp
+=
'a=sendrecv
\
r
\
n'
;
}
else
if
(
transceiver
.
rtpSender
)
{
}
else
if
(
transceiver
.
rtpSender
)
{
sdp
+=
'a=sendonly
\
r
\
n'
;
sdp
+=
'a=sendonly
\
r
\
n'
;
...
@@ -101,7 +99,6 @@ function filterIceServers(iceServers, edgeVersion) {
...
@@ -101,7 +99,6 @@ function filterIceServers(iceServers, edgeVersion) {
server
.
urls
=
isString
?
urls
[
0
]
:
urls
;
server
.
urls
=
isString
?
urls
[
0
]
:
urls
;
return
!!
urls
.
length
;
return
!!
urls
.
length
;
}
}
return
false
;
});
});
}
}
...
@@ -215,25 +212,51 @@ function maybeAddCandidate(iceTransport, candidate) {
...
@@ -215,25 +212,51 @@ function maybeAddCandidate(iceTransport, candidate) {
return
!
alreadyAdded
;
return
!
alreadyAdded
;
}
}
// https://w3c.github.io/mediacapture-main/#mediastream
// Helper function to add the track to the stream and
// dispatch the event ourselves.
function
addTrackToStreamAndFireEvent
(
track
,
stream
)
{
stream
.
addTrack
(
track
);
var
e
=
new
Event
(
'addtrack'
);
// TODO: MediaStreamTrackEvent
e
.
track
=
track
;
stream
.
dispatchEvent
(
e
);
}
function
removeTrackFromStreamAndFireEvent
(
track
,
stream
)
{
stream
.
removeTrack
(
track
);
var
e
=
new
Event
(
'removetrack'
);
// TODO: MediaStreamTrackEvent
e
.
track
=
track
;
stream
.
dispatchEvent
(
e
);
}
function
fireAddTrack
(
pc
,
track
,
receiver
,
streams
)
{
var
trackEvent
=
new
Event
(
'track'
);
trackEvent
.
track
=
track
;
trackEvent
.
receiver
=
receiver
;
trackEvent
.
transceiver
=
{
receiver
:
receiver
};
trackEvent
.
streams
=
streams
;
window
.
setTimeout
(
function
()
{
pc
.
_dispatchEvent
(
'track'
,
trackEvent
);
});
}
function
makeError
(
name
,
description
)
{
var
e
=
new
Error
(
description
);
e
.
name
=
name
;
return
e
;
}
module
.
exports
=
function
(
window
,
edgeVersion
)
{
module
.
exports
=
function
(
window
,
edgeVersion
)
{
var
RTCPeerConnection
=
function
(
config
)
{
var
RTCPeerConnection
=
function
(
config
)
{
var
self
=
this
;
var
pc
=
this
;
var
_eventTarget
=
document
.
createDocumentFragment
();
var
_eventTarget
=
document
.
createDocumentFragment
();
[
'addEventListener'
,
'removeEventListener'
,
'dispatchEvent'
]
[
'addEventListener'
,
'removeEventListener'
,
'dispatchEvent'
]
.
forEach
(
function
(
method
)
{
.
forEach
(
function
(
method
)
{
self
[
method
]
=
_eventTarget
[
method
].
bind
(
_eventTarget
);
pc
[
method
]
=
_eventTarget
[
method
].
bind
(
_eventTarget
);
});
});
this
.
onicecandidate
=
null
;
this
.
onaddstream
=
null
;
this
.
ontrack
=
null
;
this
.
onremovestream
=
null
;
this
.
onsignalingstatechange
=
null
;
this
.
oniceconnectionstatechange
=
null
;
this
.
onicegatheringstatechange
=
null
;
this
.
onnegotiationneeded
=
null
;
this
.
ondatachannel
=
null
;
this
.
canTrickleIceCandidates
=
null
;
this
.
canTrickleIceCandidates
=
null
;
this
.
needNegotiation
=
false
;
this
.
needNegotiation
=
false
;
...
@@ -252,9 +275,8 @@ module.exports = function(window, edgeVersion) {
...
@@ -252,9 +275,8 @@ module.exports = function(window, edgeVersion) {
this
.
usingBundle
=
config
.
bundlePolicy
===
'max-bundle'
;
this
.
usingBundle
=
config
.
bundlePolicy
===
'max-bundle'
;
if
(
config
.
rtcpMuxPolicy
===
'negotiate'
)
{
if
(
config
.
rtcpMuxPolicy
===
'negotiate'
)
{
var
e
=
new
Error
(
'rtcpMuxPolicy
\'
negotiate
\'
is not supported'
);
throw
(
makeError
(
'NotSupportedError'
,
e
.
name
=
'NotSupportedError'
;
'rtcpMuxPolicy
\'
negotiate
\'
is not supported'
));
throw
(
e
);
}
else
if
(
!
config
.
rtcpMuxPolicy
)
{
}
else
if
(
!
config
.
rtcpMuxPolicy
)
{
config
.
rtcpMuxPolicy
=
'require'
;
config
.
rtcpMuxPolicy
=
'require'
;
}
}
...
@@ -302,16 +324,36 @@ module.exports = function(window, edgeVersion) {
...
@@ -302,16 +324,36 @@ module.exports = function(window, edgeVersion) {
this
.
_sdpSessionVersion
=
0
;
this
.
_sdpSessionVersion
=
0
;
this
.
_dtlsRole
=
undefined
;
// role for a=setup to use in answers.
this
.
_dtlsRole
=
undefined
;
// role for a=setup to use in answers.
this
.
_isClosed
=
false
;
};
};
RTCPeerConnection
.
prototype
.
_emitGatheringStateChange
=
function
()
{
// set up event handlers on prototype
var
event
=
new
Event
(
'icegatheringstatechange'
);
RTCPeerConnection
.
prototype
.
onicecandidate
=
null
;
RTCPeerConnection
.
prototype
.
onaddstream
=
null
;
RTCPeerConnection
.
prototype
.
ontrack
=
null
;
RTCPeerConnection
.
prototype
.
onremovestream
=
null
;
RTCPeerConnection
.
prototype
.
onsignalingstatechange
=
null
;
RTCPeerConnection
.
prototype
.
oniceconnectionstatechange
=
null
;
RTCPeerConnection
.
prototype
.
onicegatheringstatechange
=
null
;
RTCPeerConnection
.
prototype
.
onnegotiationneeded
=
null
;
RTCPeerConnection
.
prototype
.
ondatachannel
=
null
;
RTCPeerConnection
.
prototype
.
_dispatchEvent
=
function
(
name
,
event
)
{
if
(
this
.
_isClosed
)
{
return
;
}
this
.
dispatchEvent
(
event
);
this
.
dispatchEvent
(
event
);
if
(
typeof
this
.
onicegatheringstatechange
===
'function'
)
{
if
(
typeof
this
[
'on'
+
name
]
===
'function'
)
{
this
.
onicegatheringstatechange
(
event
);
this
[
'on'
+
name
]
(
event
);
}
}
};
};
RTCPeerConnection
.
prototype
.
_emitGatheringStateChange
=
function
()
{
var
event
=
new
Event
(
'icegatheringstatechange'
);
this
.
_dispatchEvent
(
'icegatheringstatechange'
,
event
);
};
RTCPeerConnection
.
prototype
.
getConfiguration
=
function
()
{
RTCPeerConnection
.
prototype
.
getConfiguration
=
function
()
{
return
this
.
_config
;
return
this
.
_config
;
};
};
...
@@ -342,6 +384,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -342,6 +384,7 @@ module.exports = function(window, edgeVersion) {
sendEncodingParameters
:
null
,
sendEncodingParameters
:
null
,
recvEncodingParameters
:
null
,
recvEncodingParameters
:
null
,
stream
:
null
,
stream
:
null
,
associatedRemoteMediaStreams
:
[],
wantReceive
:
true
wantReceive
:
true
};
};
if
(
this
.
usingBundle
&&
hasBundleTransport
)
{
if
(
this
.
usingBundle
&&
hasBundleTransport
)
{
...
@@ -357,6 +400,19 @@ module.exports = function(window, edgeVersion) {
...
@@ -357,6 +400,19 @@ module.exports = function(window, edgeVersion) {
};
};
RTCPeerConnection
.
prototype
.
addTrack
=
function
(
track
,
stream
)
{
RTCPeerConnection
.
prototype
.
addTrack
=
function
(
track
,
stream
)
{
var
alreadyExists
=
this
.
transceivers
.
find
(
function
(
s
)
{
return
s
.
track
===
track
;
});
if
(
alreadyExists
)
{
throw
makeError
(
'InvalidAccessError'
,
'Track already exists.'
);
}
if
(
this
.
signalingState
===
'closed'
)
{
throw
makeError
(
'InvalidStateError'
,
'Attempted to call addTrack on a closed peerconnection.'
);
}
var
transceiver
;
var
transceiver
;
for
(
var
i
=
0
;
i
<
this
.
transceivers
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
this
.
transceivers
.
length
;
i
++
)
{
if
(
!
this
.
transceivers
[
i
].
track
&&
if
(
!
this
.
transceivers
[
i
].
track
&&
...
@@ -382,10 +438,10 @@ module.exports = function(window, edgeVersion) {
...
@@ -382,10 +438,10 @@ module.exports = function(window, edgeVersion) {
};
};
RTCPeerConnection
.
prototype
.
addStream
=
function
(
stream
)
{
RTCPeerConnection
.
prototype
.
addStream
=
function
(
stream
)
{
var
self
=
this
;
var
pc
=
this
;
if
(
edgeVersion
>=
15025
)
{
if
(
edgeVersion
>=
15025
)
{
stream
.
getTracks
().
forEach
(
function
(
track
)
{
stream
.
getTracks
().
forEach
(
function
(
track
)
{
self
.
addTrack
(
track
,
stream
);
pc
.
addTrack
(
track
,
stream
);
});
});
}
else
{
}
else
{
// Clone is necessary for local demos mostly, attaching directly
// Clone is necessary for local demos mostly, attaching directly
...
@@ -399,17 +455,54 @@ module.exports = function(window, edgeVersion) {
...
@@ -399,17 +455,54 @@ module.exports = function(window, edgeVersion) {
});
});
});
});
clonedStream
.
getTracks
().
forEach
(
function
(
track
)
{
clonedStream
.
getTracks
().
forEach
(
function
(
track
)
{
self
.
addTrack
(
track
,
clonedStream
);
pc
.
addTrack
(
track
,
clonedStream
);
});
});
}
}
};
};
RTCPeerConnection
.
prototype
.
removeStream
=
function
(
stream
)
{
RTCPeerConnection
.
prototype
.
removeTrack
=
function
(
sender
)
{
var
idx
=
this
.
localStreams
.
indexOf
(
stream
);
if
(
!
(
sender
instanceof
window
.
RTCRtpSender
))
{
if
(
idx
>
-
1
)
{
throw
new
TypeError
(
'Argument 1 of RTCPeerConnection.removeTrack '
+
this
.
localStreams
.
splice
(
idx
,
1
);
'does not implement interface RTCRtpSender.'
);
}
var
transceiver
=
this
.
transceivers
.
find
(
function
(
t
)
{
return
t
.
rtpSender
===
sender
;
});
if
(
!
transceiver
)
{
throw
makeError
(
'InvalidAccessError'
,
'Sender was not created by this connection.'
);
}
var
stream
=
transceiver
.
stream
;
transceiver
.
rtpSender
.
stop
();
transceiver
.
rtpSender
=
null
;
transceiver
.
track
=
null
;
transceiver
.
stream
=
null
;
// remove the stream from the set of local streams
var
localStreams
=
this
.
transceivers
.
map
(
function
(
t
)
{
return
t
.
stream
;
});
if
(
localStreams
.
indexOf
(
stream
)
===
-
1
&&
this
.
localStreams
.
indexOf
(
stream
)
>
-
1
)
{
this
.
localStreams
.
splice
(
this
.
localStreams
.
indexOf
(
stream
),
1
);
}
this
.
_maybeFireNegotiationNeeded
();
this
.
_maybeFireNegotiationNeeded
();
};
RTCPeerConnection
.
prototype
.
removeStream
=
function
(
stream
)
{
var
pc
=
this
;
stream
.
getTracks
().
forEach
(
function
(
track
)
{
var
sender
=
pc
.
getSenders
().
find
(
function
(
s
)
{
return
s
.
track
===
track
;
});
if
(
sender
)
{
pc
.
removeTrack
(
sender
);
}
}
});
};
};
RTCPeerConnection
.
prototype
.
getSenders
=
function
()
{
RTCPeerConnection
.
prototype
.
getSenders
=
function
()
{
...
@@ -433,7 +526,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -433,7 +526,7 @@ module.exports = function(window, edgeVersion) {
RTCPeerConnection
.
prototype
.
_createIceGatherer
=
function
(
sdpMLineIndex
,
RTCPeerConnection
.
prototype
.
_createIceGatherer
=
function
(
sdpMLineIndex
,
usingBundle
)
{
usingBundle
)
{
var
self
=
this
;
var
pc
=
this
;
if
(
usingBundle
&&
sdpMLineIndex
>
0
)
{
if
(
usingBundle
&&
sdpMLineIndex
>
0
)
{
return
this
.
transceivers
[
0
].
iceGatherer
;
return
this
.
transceivers
[
0
].
iceGatherer
;
}
else
if
(
this
.
_iceGatherers
.
length
)
{
}
else
if
(
this
.
_iceGatherers
.
length
)
{
...
@@ -453,8 +546,8 @@ module.exports = function(window, edgeVersion) {
...
@@ -453,8 +546,8 @@ module.exports = function(window, edgeVersion) {
// polyfill since RTCIceGatherer.state is not implemented in
// polyfill since RTCIceGatherer.state is not implemented in
// Edge 10547 yet.
// Edge 10547 yet.
iceGatherer
.
state
=
end
?
'completed'
:
'gathering'
;
iceGatherer
.
state
=
end
?
'completed'
:
'gathering'
;
if
(
self
.
transceivers
[
sdpMLineIndex
].
candidates
!==
null
)
{
if
(
pc
.
transceivers
[
sdpMLineIndex
].
candidates
!==
null
)
{
self
.
transceivers
[
sdpMLineIndex
].
candidates
.
push
(
event
.
candidate
);
pc
.
transceivers
[
sdpMLineIndex
].
candidates
.
push
(
event
.
candidate
);
}
}
};
};
iceGatherer
.
addEventListener
(
'localcandidate'
,
iceGatherer
.
addEventListener
(
'localcandidate'
,
...
@@ -464,7 +557,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -464,7 +557,7 @@ module.exports = function(window, edgeVersion) {
// start gathering from an RTCIceGatherer.
// start gathering from an RTCIceGatherer.
RTCPeerConnection
.
prototype
.
_gather
=
function
(
mid
,
sdpMLineIndex
)
{
RTCPeerConnection
.
prototype
.
_gather
=
function
(
mid
,
sdpMLineIndex
)
{
var
self
=
this
;
var
pc
=
this
;
var
iceGatherer
=
this
.
transceivers
[
sdpMLineIndex
].
iceGatherer
;
var
iceGatherer
=
this
.
transceivers
[
sdpMLineIndex
].
iceGatherer
;
if
(
iceGatherer
.
onlocalcandidate
)
{
if
(
iceGatherer
.
onlocalcandidate
)
{
return
;
return
;
...
@@ -474,7 +567,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -474,7 +567,7 @@ module.exports = function(window, edgeVersion) {
iceGatherer
.
removeEventListener
(
'localcandidate'
,
iceGatherer
.
removeEventListener
(
'localcandidate'
,
this
.
transceivers
[
sdpMLineIndex
].
bufferCandidates
);
this
.
transceivers
[
sdpMLineIndex
].
bufferCandidates
);
iceGatherer
.
onlocalcandidate
=
function
(
evt
)
{
iceGatherer
.
onlocalcandidate
=
function
(
evt
)
{
if
(
self
.
usingBundle
&&
sdpMLineIndex
>
0
)
{
if
(
pc
.
usingBundle
&&
sdpMLineIndex
>
0
)
{
// if we know that we use bundle we can drop candidates with
// if we know that we use bundle we can drop candidates with
// ѕdpMLineIndex > 0. If we don't do this then our state gets
// ѕdpMLineIndex > 0. If we don't do this then our state gets
// confused since we dispose the extra ice gatherer.
// confused since we dispose the extra ice gatherer.
...
@@ -502,7 +595,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -502,7 +595,7 @@ module.exports = function(window, edgeVersion) {
}
}
// update local description.
// update local description.
var
sections
=
SDPUtils
.
splitSections
(
self
.
localDescription
.
sdp
);
var
sections
=
SDPUtils
.
splitSections
(
pc
.
localDescription
.
sdp
);
if
(
!
end
)
{
if
(
!
end
)
{
sections
[
event
.
candidate
.
sdpMLineIndex
+
1
]
+=
sections
[
event
.
candidate
.
sdpMLineIndex
+
1
]
+=
'a='
+
event
.
candidate
.
candidate
+
'
\
r
\
n'
;
'a='
+
event
.
candidate
.
candidate
+
'
\
r
\
n'
;
...
@@ -510,32 +603,26 @@ module.exports = function(window, edgeVersion) {
...
@@ -510,32 +603,26 @@ module.exports = function(window, edgeVersion) {
sections
[
event
.
candidate
.
sdpMLineIndex
+
1
]
+=
sections
[
event
.
candidate
.
sdpMLineIndex
+
1
]
+=
'a=end-of-candidates
\
r
\
n'
;
'a=end-of-candidates
\
r
\
n'
;
}
}
self
.
localDescription
.
sdp
=
sections
.
join
(
''
);
pc
.
localDescription
.
sdp
=
sections
.
join
(
''
);
var
complete
=
self
.
transceivers
.
every
(
function
(
transceiver
)
{
var
complete
=
pc
.
transceivers
.
every
(
function
(
transceiver
)
{
return
transceiver
.
iceGatherer
&&
return
transceiver
.
iceGatherer
&&
transceiver
.
iceGatherer
.
state
===
'completed'
;
transceiver
.
iceGatherer
.
state
===
'completed'
;
});
});
if
(
self
.
iceGatheringState
!==
'gathering'
)
{
if
(
pc
.
iceGatheringState
!==
'gathering'
)
{
self
.
iceGatheringState
=
'gathering'
;
pc
.
iceGatheringState
=
'gathering'
;
self
.
_emitGatheringStateChange
();
pc
.
_emitGatheringStateChange
();
}
}
// Emit candidate. Also emit null candidate when all gatherers are
// Emit candidate. Also emit null candidate when all gatherers are
// complete.
// complete.
if
(
!
end
)
{
if
(
!
end
)
{
self
.
dispatchEvent
(
event
);
pc
.
_dispatchEvent
(
'icecandidate'
,
event
);
if
(
typeof
self
.
onicecandidate
===
'function'
)
{
self
.
onicecandidate
(
event
);
}
}
}
if
(
complete
)
{
if
(
complete
)
{
self
.
dispatchEvent
(
new
Event
(
'icecandidate'
));
pc
.
_dispatchEvent
(
'icecandidate'
,
new
Event
(
'icecandidate'
));
if
(
typeof
self
.
onicecandidate
===
'function'
)
{
pc
.
iceGatheringState
=
'complete'
;
self
.
onicecandidate
(
new
Event
(
'icecandidate'
));
pc
.
_emitGatheringStateChange
();
}
self
.
iceGatheringState
=
'complete'
;
self
.
_emitGatheringStateChange
();
}
}
};
};
...
@@ -551,21 +638,21 @@ module.exports = function(window, edgeVersion) {
...
@@ -551,21 +638,21 @@ module.exports = function(window, edgeVersion) {
// Create ICE transport and DTLS transport.
// Create ICE transport and DTLS transport.
RTCPeerConnection
.
prototype
.
_createIceAndDtlsTransports
=
function
()
{
RTCPeerConnection
.
prototype
.
_createIceAndDtlsTransports
=
function
()
{
var
self
=
this
;
var
pc
=
this
;
var
iceTransport
=
new
window
.
RTCIceTransport
(
null
);
var
iceTransport
=
new
window
.
RTCIceTransport
(
null
);
iceTransport
.
onicestatechange
=
function
()
{
iceTransport
.
onicestatechange
=
function
()
{
self
.
_updateConnectionState
();
pc
.
_updateConnectionState
();
};
};
var
dtlsTransport
=
new
window
.
RTCDtlsTransport
(
iceTransport
);
var
dtlsTransport
=
new
window
.
RTCDtlsTransport
(
iceTransport
);
dtlsTransport
.
ondtlsstatechange
=
function
()
{
dtlsTransport
.
ondtlsstatechange
=
function
()
{
self
.
_updateConnectionState
();
pc
.
_updateConnectionState
();
};
};
dtlsTransport
.
onerror
=
function
()
{
dtlsTransport
.
onerror
=
function
()
{
// onerror does not set state to failed by it
self
.
// onerror does not set state to failed by it
pc
.
Object
.
defineProperty
(
dtlsTransport
,
'state'
,
Object
.
defineProperty
(
dtlsTransport
,
'state'
,
{
value
:
'failed'
,
writable
:
true
});
{
value
:
'failed'
,
writable
:
true
});
self
.
_updateConnectionState
();
pc
.
_updateConnectionState
();
};
};
return
{
return
{
...
@@ -621,11 +708,15 @@ module.exports = function(window, edgeVersion) {
...
@@ -621,11 +708,15 @@ module.exports = function(window, edgeVersion) {
delete
p
.
rtx
;
delete
p
.
rtx
;
});
});
}
}
if
(
transceiver
.
recvEncodingParameters
.
length
)
{
params
.
encodings
=
transceiver
.
recvEncodingParameters
;
params
.
encodings
=
transceiver
.
recvEncodingParameters
;
}
params
.
rtcp
=
{
params
.
rtcp
=
{
cname
:
transceiver
.
rtcpParameters
.
cname
,
compound
:
transceiver
.
rtcpParameters
.
compound
compound
:
transceiver
.
rtcpParameters
.
compound
};
};
if
(
transceiver
.
rtcpParameters
.
cname
)
{
params
.
rtcp
.
cname
=
transceiver
.
rtcpParameters
.
cname
;
}
if
(
transceiver
.
sendEncodingParameters
.
length
)
{
if
(
transceiver
.
sendEncodingParameters
.
length
)
{
params
.
rtcp
.
ssrc
=
transceiver
.
sendEncodingParameters
[
0
].
ssrc
;
params
.
rtcp
.
ssrc
=
transceiver
.
sendEncodingParameters
[
0
].
ssrc
;
}
}
...
@@ -634,20 +725,13 @@ module.exports = function(window, edgeVersion) {
...
@@ -634,20 +725,13 @@ module.exports = function(window, edgeVersion) {
};
};
RTCPeerConnection
.
prototype
.
setLocalDescription
=
function
(
description
)
{
RTCPeerConnection
.
prototype
.
setLocalDescription
=
function
(
description
)
{
var
self
=
this
;
var
pc
=
this
;
var
args
=
arguments
;
if
(
!
isActionAllowedInSignalingState
(
'setLocalDescription'
,
if
(
!
isActionAllowedInSignalingState
(
'setLocalDescription'
,
description
.
type
,
this
.
signalingState
))
{
description
.
type
,
this
.
signalingState
)
||
this
.
_isClosed
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
return
Promise
.
reject
(
makeError
(
'InvalidStateError'
,
var
e
=
new
Error
(
'Can not set local '
+
description
.
type
+
'Can not set local '
+
description
.
type
+
' in state '
+
self
.
signalingState
);
' in state '
+
pc
.
signalingState
));
e
.
name
=
'InvalidStateError'
;
if
(
args
.
length
>
2
&&
typeof
args
[
2
]
===
'function'
)
{
args
[
2
].
apply
(
null
,
[
e
]);
}
reject
(
e
);
});
}
}
var
sections
;
var
sections
;
...
@@ -659,19 +743,19 @@ module.exports = function(window, edgeVersion) {
...
@@ -659,19 +743,19 @@ module.exports = function(window, edgeVersion) {
sessionpart
=
sections
.
shift
();
sessionpart
=
sections
.
shift
();
sections
.
forEach
(
function
(
mediaSection
,
sdpMLineIndex
)
{
sections
.
forEach
(
function
(
mediaSection
,
sdpMLineIndex
)
{
var
caps
=
SDPUtils
.
parseRtpParameters
(
mediaSection
);
var
caps
=
SDPUtils
.
parseRtpParameters
(
mediaSection
);
self
.
transceivers
[
sdpMLineIndex
].
localCapabilities
=
caps
;
pc
.
transceivers
[
sdpMLineIndex
].
localCapabilities
=
caps
;
});
});
this
.
transceivers
.
forEach
(
function
(
transceiver
,
sdpMLineIndex
)
{
this
.
transceivers
.
forEach
(
function
(
transceiver
,
sdpMLineIndex
)
{
self
.
_gather
(
transceiver
.
mid
,
sdpMLineIndex
);
pc
.
_gather
(
transceiver
.
mid
,
sdpMLineIndex
);
});
});
}
else
if
(
description
.
type
===
'answer'
)
{
}
else
if
(
description
.
type
===
'answer'
)
{
sections
=
SDPUtils
.
splitSections
(
self
.
remoteDescription
.
sdp
);
sections
=
SDPUtils
.
splitSections
(
pc
.
remoteDescription
.
sdp
);
sessionpart
=
sections
.
shift
();
sessionpart
=
sections
.
shift
();
var
isIceLite
=
SDPUtils
.
matchPrefix
(
sessionpart
,
var
isIceLite
=
SDPUtils
.
matchPrefix
(
sessionpart
,
'a=ice-lite'
).
length
>
0
;
'a=ice-lite'
).
length
>
0
;
sections
.
forEach
(
function
(
mediaSection
,
sdpMLineIndex
)
{
sections
.
forEach
(
function
(
mediaSection
,
sdpMLineIndex
)
{
var
transceiver
=
self
.
transceivers
[
sdpMLineIndex
];
var
transceiver
=
pc
.
transceivers
[
sdpMLineIndex
];
var
iceGatherer
=
transceiver
.
iceGatherer
;
var
iceGatherer
=
transceiver
.
iceGatherer
;
var
iceTransport
=
transceiver
.
iceTransport
;
var
iceTransport
=
transceiver
.
iceTransport
;
var
dtlsTransport
=
transceiver
.
dtlsTransport
;
var
dtlsTransport
=
transceiver
.
dtlsTransport
;
...
@@ -680,7 +764,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -680,7 +764,7 @@ module.exports = function(window, edgeVersion) {
// treat bundle-only as not-rejected.
// treat bundle-only as not-rejected.
var
rejected
=
SDPUtils
.
isRejected
(
mediaSection
)
&&
var
rejected
=
SDPUtils
.
isRejected
(
mediaSection
)
&&
!
SDPUtils
.
matchPrefix
(
mediaSection
,
'a=bundle-only'
).
length
===
1
;
SDPUtils
.
matchPrefix
(
mediaSection
,
'a=bundle-only'
).
length
===
0
;
if
(
!
rejected
&&
!
transceiver
.
isDatachannel
)
{
if
(
!
rejected
&&
!
transceiver
.
isDatachannel
)
{
var
remoteIceParameters
=
SDPUtils
.
getIceParameters
(
var
remoteIceParameters
=
SDPUtils
.
getIceParameters
(
...
@@ -691,8 +775,8 @@ module.exports = function(window, edgeVersion) {
...
@@ -691,8 +775,8 @@ module.exports = function(window, edgeVersion) {
remoteDtlsParameters
.
role
=
'server'
;
remoteDtlsParameters
.
role
=
'server'
;
}
}
if
(
!
self
.
usingBundle
||
sdpMLineIndex
===
0
)
{
if
(
!
pc
.
usingBundle
||
sdpMLineIndex
===
0
)
{
self
.
_gather
(
transceiver
.
mid
,
sdpMLineIndex
);
pc
.
_gather
(
transceiver
.
mid
,
sdpMLineIndex
);
if
(
iceTransport
.
state
===
'new'
)
{
if
(
iceTransport
.
state
===
'new'
)
{
iceTransport
.
start
(
iceGatherer
,
remoteIceParameters
,
iceTransport
.
start
(
iceGatherer
,
remoteIceParameters
,
isIceLite
?
'controlling'
:
'controlled'
);
isIceLite
?
'controlling'
:
'controlled'
);
...
@@ -708,7 +792,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -708,7 +792,7 @@ module.exports = function(window, edgeVersion) {
// Start the RTCRtpSender. The RTCRtpReceiver for this
// Start the RTCRtpSender. The RTCRtpReceiver for this
// transceiver has already been started in setRemoteDescription.
// transceiver has already been started in setRemoteDescription.
self
.
_transceive
(
transceiver
,
pc
.
_transceive
(
transceiver
,
params
.
codecs
.
length
>
0
,
params
.
codecs
.
length
>
0
,
false
);
false
);
}
}
...
@@ -731,34 +815,17 @@ module.exports = function(window, edgeVersion) {
...
@@ -731,34 +815,17 @@ module.exports = function(window, edgeVersion) {
'"'
);
'"'
);
}
}
// If a success callback was provided, emit ICE candidates after it
return
Promise
.
resolve
();
// has been executed. Otherwise, emit callback after the Promise is
// resolved.
var
cb
=
arguments
.
length
>
1
&&
typeof
arguments
[
1
]
===
'function'
&&
arguments
[
1
];
return
new
Promise
(
function
(
resolve
)
{
if
(
cb
)
{
cb
.
apply
(
null
);
}
resolve
();
});
};
};
RTCPeerConnection
.
prototype
.
setRemoteDescription
=
function
(
description
)
{
RTCPeerConnection
.
prototype
.
setRemoteDescription
=
function
(
description
)
{
var
self
=
this
;
var
pc
=
this
;
var
args
=
arguments
;
if
(
!
isActionAllowedInSignalingState
(
'setRemoteDescription'
,
if
(
!
isActionAllowedInSignalingState
(
'setRemoteDescription'
,
description
.
type
,
this
.
signalingState
))
{
description
.
type
,
this
.
signalingState
)
||
this
.
_isClosed
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
return
Promise
.
reject
(
makeError
(
'InvalidStateError'
,
var
e
=
new
Error
(
'Can not set remote '
+
description
.
type
+
'Can not set remote '
+
description
.
type
+
' in state '
+
self
.
signalingState
);
' in state '
+
pc
.
signalingState
));
e
.
name
=
'InvalidStateError'
;
if
(
args
.
length
>
2
&&
typeof
args
[
2
]
===
'function'
)
{
args
[
2
].
apply
(
null
,
[
e
]);
}
reject
(
e
);
});
}
}
var
streams
=
{};
var
streams
=
{};
...
@@ -787,7 +854,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -787,7 +854,7 @@ module.exports = function(window, edgeVersion) {
var
kind
=
SDPUtils
.
getKind
(
mediaSection
);
var
kind
=
SDPUtils
.
getKind
(
mediaSection
);
// treat bundle-only as not-rejected.
// treat bundle-only as not-rejected.
var
rejected
=
SDPUtils
.
isRejected
(
mediaSection
)
&&
var
rejected
=
SDPUtils
.
isRejected
(
mediaSection
)
&&
!
SDPUtils
.
matchPrefix
(
mediaSection
,
'a=bundle-only'
).
length
===
1
;
SDPUtils
.
matchPrefix
(
mediaSection
,
'a=bundle-only'
).
length
===
0
;
var
protocol
=
lines
[
0
].
substr
(
2
).
split
(
' '
)[
2
];
var
protocol
=
lines
[
0
].
substr
(
2
).
split
(
' '
)[
2
];
var
direction
=
SDPUtils
.
getDirection
(
mediaSection
,
sessionpart
);
var
direction
=
SDPUtils
.
getDirection
(
mediaSection
,
sessionpart
);
...
@@ -797,7 +864,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -797,7 +864,7 @@ module.exports = function(window, edgeVersion) {
// Reject datachannels which are not implemented yet.
// Reject datachannels which are not implemented yet.
if
(
kind
===
'application'
&&
protocol
===
'DTLS/SCTP'
)
{
if
(
kind
===
'application'
&&
protocol
===
'DTLS/SCTP'
)
{
self
.
transceivers
[
sdpMLineIndex
]
=
{
pc
.
transceivers
[
sdpMLineIndex
]
=
{
mid
:
mid
,
mid
:
mid
,
isDatachannel
:
true
isDatachannel
:
true
};
};
...
@@ -843,30 +910,30 @@ module.exports = function(window, edgeVersion) {
...
@@ -843,30 +910,30 @@ module.exports = function(window, edgeVersion) {
// Check if we can use BUNDLE and dispose transports.
// Check if we can use BUNDLE and dispose transports.
if
((
description
.
type
===
'offer'
||
description
.
type
===
'answer'
)
&&
if
((
description
.
type
===
'offer'
||
description
.
type
===
'answer'
)
&&
!
rejected
&&
usingBundle
&&
sdpMLineIndex
>
0
&&
!
rejected
&&
usingBundle
&&
sdpMLineIndex
>
0
&&
self
.
transceivers
[
sdpMLineIndex
])
{
pc
.
transceivers
[
sdpMLineIndex
])
{
self
.
_disposeIceAndDtlsTransports
(
sdpMLineIndex
);
pc
.
_disposeIceAndDtlsTransports
(
sdpMLineIndex
);
self
.
transceivers
[
sdpMLineIndex
].
iceGatherer
=
pc
.
transceivers
[
sdpMLineIndex
].
iceGatherer
=
self
.
transceivers
[
0
].
iceGatherer
;
pc
.
transceivers
[
0
].
iceGatherer
;
self
.
transceivers
[
sdpMLineIndex
].
iceTransport
=
pc
.
transceivers
[
sdpMLineIndex
].
iceTransport
=
self
.
transceivers
[
0
].
iceTransport
;
pc
.
transceivers
[
0
].
iceTransport
;
self
.
transceivers
[
sdpMLineIndex
].
dtlsTransport
=
pc
.
transceivers
[
sdpMLineIndex
].
dtlsTransport
=
self
.
transceivers
[
0
].
dtlsTransport
;
pc
.
transceivers
[
0
].
dtlsTransport
;
if
(
self
.
transceivers
[
sdpMLineIndex
].
rtpSender
)
{
if
(
pc
.
transceivers
[
sdpMLineIndex
].
rtpSender
)
{
self
.
transceivers
[
sdpMLineIndex
].
rtpSender
.
setTransport
(
pc
.
transceivers
[
sdpMLineIndex
].
rtpSender
.
setTransport
(
self
.
transceivers
[
0
].
dtlsTransport
);
pc
.
transceivers
[
0
].
dtlsTransport
);
}
}
if
(
self
.
transceivers
[
sdpMLineIndex
].
rtpReceiver
)
{
if
(
pc
.
transceivers
[
sdpMLineIndex
].
rtpReceiver
)
{
self
.
transceivers
[
sdpMLineIndex
].
rtpReceiver
.
setTransport
(
pc
.
transceivers
[
sdpMLineIndex
].
rtpReceiver
.
setTransport
(
self
.
transceivers
[
0
].
dtlsTransport
);
pc
.
transceivers
[
0
].
dtlsTransport
);
}
}
}
}
if
(
description
.
type
===
'offer'
&&
!
rejected
)
{
if
(
description
.
type
===
'offer'
&&
!
rejected
)
{
transceiver
=
self
.
transceivers
[
sdpMLineIndex
]
||
transceiver
=
pc
.
transceivers
[
sdpMLineIndex
]
||
self
.
_createTransceiver
(
kind
);
pc
.
_createTransceiver
(
kind
);
transceiver
.
mid
=
mid
;
transceiver
.
mid
=
mid
;
if
(
!
transceiver
.
iceGatherer
)
{
if
(
!
transceiver
.
iceGatherer
)
{
transceiver
.
iceGatherer
=
self
.
_createIceGatherer
(
sdpMLineIndex
,
transceiver
.
iceGatherer
=
pc
.
_createIceGatherer
(
sdpMLineIndex
,
usingBundle
);
usingBundle
);
}
}
...
@@ -895,6 +962,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -895,6 +962,7 @@ module.exports = function(window, edgeVersion) {
ssrc
:
(
2
*
sdpMLineIndex
+
2
)
*
1001
ssrc
:
(
2
*
sdpMLineIndex
+
2
)
*
1001
}];
}];
// TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams
var
isNewTrack
=
false
;
var
isNewTrack
=
false
;
if
(
direction
===
'sendrecv'
||
direction
===
'sendonly'
)
{
if
(
direction
===
'sendrecv'
||
direction
===
'sendonly'
)
{
isNewTrack
=
!
transceiver
.
rtpReceiver
;
isNewTrack
=
!
transceiver
.
rtpReceiver
;
...
@@ -905,7 +973,9 @@ module.exports = function(window, edgeVersion) {
...
@@ -905,7 +973,9 @@ module.exports = function(window, edgeVersion) {
var
stream
;
var
stream
;
track
=
rtpReceiver
.
track
;
track
=
rtpReceiver
.
track
;
// FIXME: does not work with Plan B.
// FIXME: does not work with Plan B.
if
(
remoteMsid
)
{
if
(
remoteMsid
&&
remoteMsid
.
stream
===
'-'
)
{
// no-op. a stream id of '-' means: no associated stream.
}
else
if
(
remoteMsid
)
{
if
(
!
streams
[
remoteMsid
.
stream
])
{
if
(
!
streams
[
remoteMsid
.
stream
])
{
streams
[
remoteMsid
.
stream
]
=
new
window
.
MediaStream
();
streams
[
remoteMsid
.
stream
]
=
new
window
.
MediaStream
();
Object
.
defineProperty
(
streams
[
remoteMsid
.
stream
],
'id'
,
{
Object
.
defineProperty
(
streams
[
remoteMsid
.
stream
],
'id'
,
{
...
@@ -926,9 +996,22 @@ module.exports = function(window, edgeVersion) {
...
@@ -926,9 +996,22 @@ module.exports = function(window, edgeVersion) {
}
}
stream
=
streams
.
default
;
stream
=
streams
.
default
;
}
}
stream
.
addTrack
(
track
);
if
(
stream
)
{
addTrackToStreamAndFireEvent
(
track
,
stream
);
transceiver
.
associatedRemoteMediaStreams
.
push
(
stream
);
}
receiverList
.
push
([
track
,
rtpReceiver
,
stream
]);
receiverList
.
push
([
track
,
rtpReceiver
,
stream
]);
}
}
}
else
if
(
transceiver
.
rtpReceiver
&&
transceiver
.
rtpReceiver
.
track
)
{
transceiver
.
associatedRemoteMediaStreams
.
forEach
(
function
(
s
)
{
var
nativeTrack
=
s
.
getTracks
().
find
(
function
(
t
)
{
return
t
.
id
===
transceiver
.
rtpReceiver
.
track
.
id
;
});
if
(
nativeTrack
)
{
removeTrackFromStreamAndFireEvent
(
nativeTrack
,
s
);
}
});
transceiver
.
associatedRemoteMediaStreams
=
[];
}
}
transceiver
.
localCapabilities
=
localCapabilities
;
transceiver
.
localCapabilities
=
localCapabilities
;
...
@@ -940,11 +1023,11 @@ module.exports = function(window, edgeVersion) {
...
@@ -940,11 +1023,11 @@ module.exports = function(window, edgeVersion) {
// Start the RTCRtpReceiver now. The RTPSender is started in
// Start the RTCRtpReceiver now. The RTPSender is started in
// setLocalDescription.
// setLocalDescription.
self
.
_transceive
(
self
.
transceivers
[
sdpMLineIndex
],
pc
.
_transceive
(
pc
.
transceivers
[
sdpMLineIndex
],
false
,
false
,
isNewTrack
);
isNewTrack
);
}
else
if
(
description
.
type
===
'answer'
&&
!
rejected
)
{
}
else
if
(
description
.
type
===
'answer'
&&
!
rejected
)
{
transceiver
=
self
.
transceivers
[
sdpMLineIndex
];
transceiver
=
pc
.
transceivers
[
sdpMLineIndex
];
iceGatherer
=
transceiver
.
iceGatherer
;
iceGatherer
=
transceiver
.
iceGatherer
;
iceTransport
=
transceiver
.
iceTransport
;
iceTransport
=
transceiver
.
iceTransport
;
dtlsTransport
=
transceiver
.
dtlsTransport
;
dtlsTransport
=
transceiver
.
dtlsTransport
;
...
@@ -952,11 +1035,11 @@ module.exports = function(window, edgeVersion) {
...
@@ -952,11 +1035,11 @@ module.exports = function(window, edgeVersion) {
sendEncodingParameters
=
transceiver
.
sendEncodingParameters
;
sendEncodingParameters
=
transceiver
.
sendEncodingParameters
;
localCapabilities
=
transceiver
.
localCapabilities
;
localCapabilities
=
transceiver
.
localCapabilities
;
self
.
transceivers
[
sdpMLineIndex
].
recvEncodingParameters
=
pc
.
transceivers
[
sdpMLineIndex
].
recvEncodingParameters
=
recvEncodingParameters
;
recvEncodingParameters
;
self
.
transceivers
[
sdpMLineIndex
].
remoteCapabilities
=
pc
.
transceivers
[
sdpMLineIndex
].
remoteCapabilities
=
remoteCapabilities
;
remoteCapabilities
;
self
.
transceivers
[
sdpMLineIndex
].
rtcpParameters
=
rtcpParameters
;
pc
.
transceivers
[
sdpMLineIndex
].
rtcpParameters
=
rtcpParameters
;
if
(
cands
.
length
&&
iceTransport
.
state
===
'new'
)
{
if
(
cands
.
length
&&
iceTransport
.
state
===
'new'
)
{
if
((
isIceLite
||
isComplete
)
&&
if
((
isIceLite
||
isComplete
)
&&
...
@@ -979,10 +1062,11 @@ module.exports = function(window, edgeVersion) {
...
@@ -979,10 +1062,11 @@ module.exports = function(window, edgeVersion) {
}
}
}
}
self
.
_transceive
(
transceiver
,
pc
.
_transceive
(
transceiver
,
direction
===
'sendrecv'
||
direction
===
'recvonly'
,
direction
===
'sendrecv'
||
direction
===
'recvonly'
,
direction
===
'sendrecv'
||
direction
===
'sendonly'
);
direction
===
'sendrecv'
||
direction
===
'sendonly'
);
// TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams
if
(
rtpReceiver
&&
if
(
rtpReceiver
&&
(
direction
===
'sendrecv'
||
direction
===
'sendonly'
))
{
(
direction
===
'sendrecv'
||
direction
===
'sendonly'
))
{
track
=
rtpReceiver
.
track
;
track
=
rtpReceiver
.
track
;
...
@@ -990,13 +1074,13 @@ module.exports = function(window, edgeVersion) {
...
@@ -990,13 +1074,13 @@ module.exports = function(window, edgeVersion) {
if
(
!
streams
[
remoteMsid
.
stream
])
{
if
(
!
streams
[
remoteMsid
.
stream
])
{
streams
[
remoteMsid
.
stream
]
=
new
window
.
MediaStream
();
streams
[
remoteMsid
.
stream
]
=
new
window
.
MediaStream
();
}
}
streams
[
remoteMsid
.
stream
].
addTrack
(
track
);
addTrackToStreamAndFireEvent
(
track
,
streams
[
remoteMsid
.
stream
]
);
receiverList
.
push
([
track
,
rtpReceiver
,
streams
[
remoteMsid
.
stream
]]);
receiverList
.
push
([
track
,
rtpReceiver
,
streams
[
remoteMsid
.
stream
]]);
}
else
{
}
else
{
if
(
!
streams
.
default
)
{
if
(
!
streams
.
default
)
{
streams
.
default
=
new
window
.
MediaStream
();
streams
.
default
=
new
window
.
MediaStream
();
}
}
streams
.
default
.
addTrack
(
track
);
addTrackToStreamAndFireEvent
(
track
,
streams
.
default
);
receiverList
.
push
([
track
,
rtpReceiver
,
streams
.
default
]);
receiverList
.
push
([
track
,
rtpReceiver
,
streams
.
default
]);
}
}
}
else
{
}
else
{
...
@@ -1028,15 +1112,12 @@ module.exports = function(window, edgeVersion) {
...
@@ -1028,15 +1112,12 @@ module.exports = function(window, edgeVersion) {
Object
.
keys
(
streams
).
forEach
(
function
(
sid
)
{
Object
.
keys
(
streams
).
forEach
(
function
(
sid
)
{
var
stream
=
streams
[
sid
];
var
stream
=
streams
[
sid
];
if
(
stream
.
getTracks
().
length
)
{
if
(
stream
.
getTracks
().
length
)
{
if
(
self
.
remoteStreams
.
indexOf
(
stream
)
===
-
1
)
{
if
(
pc
.
remoteStreams
.
indexOf
(
stream
)
===
-
1
)
{
self
.
remoteStreams
.
push
(
stream
);
pc
.
remoteStreams
.
push
(
stream
);
var
event
=
new
Event
(
'addstream'
);
var
event
=
new
Event
(
'addstream'
);
event
.
stream
=
stream
;
event
.
stream
=
stream
;
window
.
setTimeout
(
function
()
{
window
.
setTimeout
(
function
()
{
self
.
dispatchEvent
(
event
);
pc
.
_dispatchEvent
(
'addstream'
,
event
);
if
(
typeof
self
.
onaddstream
===
'function'
)
{
self
.
onaddstream
(
event
);
}
});
});
}
}
...
@@ -1046,28 +1127,24 @@ module.exports = function(window, edgeVersion) {
...
@@ -1046,28 +1127,24 @@ module.exports = function(window, edgeVersion) {
if
(
stream
.
id
!==
item
[
2
].
id
)
{
if
(
stream
.
id
!==
item
[
2
].
id
)
{
return
;
return
;
}
}
var
trackEvent
=
new
Event
(
'track'
);
fireAddTrack
(
pc
,
track
,
receiver
,
[
stream
]);
trackEvent
.
track
=
track
;
trackEvent
.
receiver
=
receiver
;
trackEvent
.
transceiver
=
{
receiver
:
receiver
};
trackEvent
.
streams
=
[
stream
];
window
.
setTimeout
(
function
()
{
self
.
dispatchEvent
(
trackEvent
);
if
(
typeof
self
.
ontrack
===
'function'
)
{
self
.
ontrack
(
trackEvent
);
}
});
});
}
});
});
receiverList
.
forEach
(
function
(
item
)
{
if
(
item
[
2
])
{
return
;
}
}
fireAddTrack
(
pc
,
item
[
0
],
item
[
1
],
[]);
});
});
// check whether addIceCandidate({}) was called within four seconds after
// check whether addIceCandidate({}) was called within four seconds after
// setRemoteDescription.
// setRemoteDescription.
window
.
setTimeout
(
function
()
{
window
.
setTimeout
(
function
()
{
if
(
!
(
self
&&
self
.
transceivers
))
{
if
(
!
(
pc
&&
pc
.
transceivers
))
{
return
;
return
;
}
}
self
.
transceivers
.
forEach
(
function
(
transceiver
)
{
pc
.
transceivers
.
forEach
(
function
(
transceiver
)
{
if
(
transceiver
.
iceTransport
&&
if
(
transceiver
.
iceTransport
&&
transceiver
.
iceTransport
.
state
===
'new'
&&
transceiver
.
iceTransport
.
state
===
'new'
&&
transceiver
.
iceTransport
.
getRemoteCandidates
().
length
>
0
)
{
transceiver
.
iceTransport
.
getRemoteCandidates
().
length
>
0
)
{
...
@@ -1078,12 +1155,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -1078,12 +1155,7 @@ module.exports = function(window, edgeVersion) {
});
});
},
4000
);
},
4000
);
return
new
Promise
(
function
(
resolve
)
{
return
Promise
.
resolve
();
if
(
args
.
length
>
1
&&
typeof
args
[
1
]
===
'function'
)
{
args
[
1
].
apply
(
null
);
}
resolve
();
});
};
};
RTCPeerConnection
.
prototype
.
close
=
function
()
{
RTCPeerConnection
.
prototype
.
close
=
function
()
{
...
@@ -1107,6 +1179,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -1107,6 +1179,7 @@ module.exports = function(window, edgeVersion) {
}
}
});
});
// FIXME: clean up tracks, local streams, remote streams, etc
// FIXME: clean up tracks, local streams, remote streams, etc
this
.
_isClosed
=
true
;
this
.
_updateSignalingState
(
'closed'
);
this
.
_updateSignalingState
(
'closed'
);
};
};
...
@@ -1114,29 +1187,23 @@ module.exports = function(window, edgeVersion) {
...
@@ -1114,29 +1187,23 @@ module.exports = function(window, edgeVersion) {
RTCPeerConnection
.
prototype
.
_updateSignalingState
=
function
(
newState
)
{
RTCPeerConnection
.
prototype
.
_updateSignalingState
=
function
(
newState
)
{
this
.
signalingState
=
newState
;
this
.
signalingState
=
newState
;
var
event
=
new
Event
(
'signalingstatechange'
);
var
event
=
new
Event
(
'signalingstatechange'
);
this
.
dispatchEvent
(
event
);
this
.
_dispatchEvent
(
'signalingstatechange'
,
event
);
if
(
typeof
this
.
onsignalingstatechange
===
'function'
)
{
this
.
onsignalingstatechange
(
event
);
}
};
};
// Determine whether to fire the negotiationneeded event.
// Determine whether to fire the negotiationneeded event.
RTCPeerConnection
.
prototype
.
_maybeFireNegotiationNeeded
=
function
()
{
RTCPeerConnection
.
prototype
.
_maybeFireNegotiationNeeded
=
function
()
{
var
self
=
this
;
var
pc
=
this
;
if
(
this
.
signalingState
!==
'stable'
||
this
.
needNegotiation
===
true
)
{
if
(
this
.
signalingState
!==
'stable'
||
this
.
needNegotiation
===
true
)
{
return
;
return
;
}
}
this
.
needNegotiation
=
true
;
this
.
needNegotiation
=
true
;
window
.
setTimeout
(
function
()
{
window
.
setTimeout
(
function
()
{
if
(
self
.
needNegotiation
===
false
)
{
if
(
pc
.
needNegotiation
===
false
)
{
return
;
return
;
}
}
self
.
needNegotiation
=
false
;
pc
.
needNegotiation
=
false
;
var
event
=
new
Event
(
'negotiationneeded'
);
var
event
=
new
Event
(
'negotiationneeded'
);
self
.
dispatchEvent
(
event
);
pc
.
_dispatchEvent
(
'negotiationneeded'
,
event
);
if
(
typeof
self
.
onnegotiationneeded
===
'function'
)
{
self
.
onnegotiationneeded
(
event
);
}
},
0
);
},
0
);
};
};
...
@@ -1176,22 +1243,16 @@ module.exports = function(window, edgeVersion) {
...
@@ -1176,22 +1243,16 @@ module.exports = function(window, edgeVersion) {
if
(
newState
!==
this
.
iceConnectionState
)
{
if
(
newState
!==
this
.
iceConnectionState
)
{
this
.
iceConnectionState
=
newState
;
this
.
iceConnectionState
=
newState
;
var
event
=
new
Event
(
'iceconnectionstatechange'
);
var
event
=
new
Event
(
'iceconnectionstatechange'
);
this
.
dispatchEvent
(
event
);
this
.
_dispatchEvent
(
'iceconnectionstatechange'
,
event
);
if
(
typeof
this
.
oniceconnectionstatechange
===
'function'
)
{
this
.
oniceconnectionstatechange
(
event
);
}
}
}
};
};
RTCPeerConnection
.
prototype
.
createOffer
=
function
()
{
RTCPeerConnection
.
prototype
.
createOffer
=
function
()
{
var
self
=
this
;
var
pc
=
this
;
var
args
=
arguments
;
var
offerOptions
;
if
(
this
.
_isClosed
)
{
if
(
arguments
.
length
===
1
&&
typeof
arguments
[
0
]
!==
'function'
)
{
return
Promise
.
reject
(
makeError
(
'InvalidStateError'
,
offerOptions
=
arguments
[
0
];
'Can not call createOffer after close'
));
}
else
if
(
arguments
.
length
===
3
)
{
offerOptions
=
arguments
[
2
];
}
}
var
numAudioTracks
=
this
.
transceivers
.
filter
(
function
(
t
)
{
var
numAudioTracks
=
this
.
transceivers
.
filter
(
function
(
t
)
{
...
@@ -1202,6 +1263,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -1202,6 +1263,7 @@ module.exports = function(window, edgeVersion) {
}).
length
;
}).
length
;
// Determine number of audio and video tracks we need to send/recv.
// Determine number of audio and video tracks we need to send/recv.
var
offerOptions
=
arguments
[
0
];
if
(
offerOptions
)
{
if
(
offerOptions
)
{
// Reject Chrome legacy constraints.
// Reject Chrome legacy constraints.
if
(
offerOptions
.
mandatory
||
offerOptions
.
optional
)
{
if
(
offerOptions
.
mandatory
||
offerOptions
.
optional
)
{
...
@@ -1265,8 +1327,8 @@ module.exports = function(window, edgeVersion) {
...
@@ -1265,8 +1327,8 @@ module.exports = function(window, edgeVersion) {
transceiver
.
mid
=
mid
;
transceiver
.
mid
=
mid
;
if
(
!
transceiver
.
iceGatherer
)
{
if
(
!
transceiver
.
iceGatherer
)
{
transceiver
.
iceGatherer
=
self
.
_createIceGatherer
(
sdpMLineIndex
,
transceiver
.
iceGatherer
=
pc
.
_createIceGatherer
(
sdpMLineIndex
,
self
.
usingBundle
);
pc
.
usingBundle
);
}
}
var
localCapabilities
=
window
.
RTCRtpSender
.
getCapabilities
(
kind
);
var
localCapabilities
=
window
.
RTCRtpSender
.
getCapabilities
(
kind
);
...
@@ -1320,11 +1382,11 @@ module.exports = function(window, edgeVersion) {
...
@@ -1320,11 +1382,11 @@ module.exports = function(window, edgeVersion) {
this
.
transceivers
.
forEach
(
function
(
transceiver
,
sdpMLineIndex
)
{
this
.
transceivers
.
forEach
(
function
(
transceiver
,
sdpMLineIndex
)
{
sdp
+=
writeMediaSection
(
transceiver
,
transceiver
.
localCapabilities
,
sdp
+=
writeMediaSection
(
transceiver
,
transceiver
.
localCapabilities
,
'offer'
,
transceiver
.
stream
,
self
.
_dtlsRole
);
'offer'
,
transceiver
.
stream
,
pc
.
_dtlsRole
);
sdp
+=
'a=rtcp-rsize
\
r
\
n'
;
sdp
+=
'a=rtcp-rsize
\
r
\
n'
;
if
(
transceiver
.
iceGatherer
&&
self
.
iceGatheringState
!==
'new'
&&
if
(
transceiver
.
iceGatherer
&&
pc
.
iceGatheringState
!==
'new'
&&
(
sdpMLineIndex
===
0
||
!
self
.
usingBundle
))
{
(
sdpMLineIndex
===
0
||
!
pc
.
usingBundle
))
{
transceiver
.
iceGatherer
.
getLocalCandidates
().
forEach
(
function
(
cand
)
{
transceiver
.
iceGatherer
.
getLocalCandidates
().
forEach
(
function
(
cand
)
{
cand
.
component
=
1
;
cand
.
component
=
1
;
sdp
+=
'a='
+
SDPUtils
.
writeCandidate
(
cand
)
+
'
\
r
\
n'
;
sdp
+=
'a='
+
SDPUtils
.
writeCandidate
(
cand
)
+
'
\
r
\
n'
;
...
@@ -1340,19 +1402,16 @@ module.exports = function(window, edgeVersion) {
...
@@ -1340,19 +1402,16 @@ module.exports = function(window, edgeVersion) {
type
:
'offer'
,
type
:
'offer'
,
sdp
:
sdp
sdp
:
sdp
});
});
return
new
Promise
(
function
(
resolve
)
{
return
Promise
.
resolve
(
desc
);
if
(
args
.
length
>
0
&&
typeof
args
[
0
]
===
'function'
)
{
args
[
0
].
apply
(
null
,
[
desc
]);
resolve
();
return
;
}
resolve
(
desc
);
});
};
};
RTCPeerConnection
.
prototype
.
createAnswer
=
function
()
{
RTCPeerConnection
.
prototype
.
createAnswer
=
function
()
{
var
self
=
this
;
var
pc
=
this
;
var
args
=
arguments
;
if
(
this
.
_isClosed
)
{
return
Promise
.
reject
(
makeError
(
'InvalidStateError'
,
'Can not call createAnswer after close'
));
}
var
sdp
=
SDPUtils
.
writeSessionBoilerplate
(
this
.
_sdpSessionId
,
var
sdp
=
SDPUtils
.
writeSessionBoilerplate
(
this
.
_sdpSessionId
,
this
.
_sdpSessionVersion
++
);
this
.
_sdpSessionVersion
++
);
...
@@ -1406,7 +1465,7 @@ module.exports = function(window, edgeVersion) {
...
@@ -1406,7 +1465,7 @@ module.exports = function(window, edgeVersion) {
}
}
sdp
+=
writeMediaSection
(
transceiver
,
commonCapabilities
,
sdp
+=
writeMediaSection
(
transceiver
,
commonCapabilities
,
'answer'
,
transceiver
.
stream
,
self
.
_dtlsRole
);
'answer'
,
transceiver
.
stream
,
pc
.
_dtlsRole
);
if
(
transceiver
.
rtcpParameters
&&
if
(
transceiver
.
rtcpParameters
&&
transceiver
.
rtcpParameters
.
reducedSize
)
{
transceiver
.
rtcpParameters
.
reducedSize
)
{
sdp
+=
'a=rtcp-rsize
\
r
\
n'
;
sdp
+=
'a=rtcp-rsize
\
r
\
n'
;
...
@@ -1417,18 +1476,10 @@ module.exports = function(window, edgeVersion) {
...
@@ -1417,18 +1476,10 @@ module.exports = function(window, edgeVersion) {
type
:
'answer'
,
type
:
'answer'
,
sdp
:
sdp
sdp
:
sdp
});
});
return
new
Promise
(
function
(
resolve
)
{
return
Promise
.
resolve
(
desc
);
if
(
args
.
length
>
0
&&
typeof
args
[
0
]
===
'function'
)
{
args
[
0
].
apply
(
null
,
[
desc
]);
resolve
();
return
;
}
resolve
(
desc
);
});
};
};
RTCPeerConnection
.
prototype
.
addIceCandidate
=
function
(
candidate
)
{
RTCPeerConnection
.
prototype
.
addIceCandidate
=
function
(
candidate
)
{
var
err
;
var
sections
;
var
sections
;
if
(
!
candidate
||
candidate
.
candidate
===
''
)
{
if
(
!
candidate
||
candidate
.
candidate
===
''
)
{
for
(
var
j
=
0
;
j
<
this
.
transceivers
.
length
;
j
++
)
{
for
(
var
j
=
0
;
j
<
this
.
transceivers
.
length
;
j
++
)
{
...
@@ -1446,9 +1497,8 @@ module.exports = function(window, edgeVersion) {
...
@@ -1446,9 +1497,8 @@ module.exports = function(window, edgeVersion) {
}
else
if
(
!
(
candidate
.
sdpMLineIndex
!==
undefined
||
candidate
.
sdpMid
))
{
}
else
if
(
!
(
candidate
.
sdpMLineIndex
!==
undefined
||
candidate
.
sdpMid
))
{
throw
new
TypeError
(
'sdpMLineIndex or sdpMid required'
);
throw
new
TypeError
(
'sdpMLineIndex or sdpMid required'
);
}
else
if
(
!
this
.
remoteDescription
)
{
}
else
if
(
!
this
.
remoteDescription
)
{
err
=
new
Error
(
'Can not add ICE candidate without '
+
return
Promise
.
reject
(
makeError
(
'InvalidStateError'
,
'a remote description'
);
'Can not add ICE candidate without a remote description'
));
err
.
name
=
'InvalidStateError'
;
}
else
{
}
else
{
var
sdpMLineIndex
=
candidate
.
sdpMLineIndex
;
var
sdpMLineIndex
=
candidate
.
sdpMLineIndex
;
if
(
candidate
.
sdpMid
)
{
if
(
candidate
.
sdpMid
)
{
...
@@ -1479,12 +1529,11 @@ module.exports = function(window, edgeVersion) {
...
@@ -1479,12 +1529,11 @@ module.exports = function(window, edgeVersion) {
if
(
sdpMLineIndex
===
0
||
(
sdpMLineIndex
>
0
&&
if
(
sdpMLineIndex
===
0
||
(
sdpMLineIndex
>
0
&&
transceiver
.
iceTransport
!==
this
.
transceivers
[
0
].
iceTransport
))
{
transceiver
.
iceTransport
!==
this
.
transceivers
[
0
].
iceTransport
))
{
if
(
!
maybeAddCandidate
(
transceiver
.
iceTransport
,
cand
))
{
if
(
!
maybeAddCandidate
(
transceiver
.
iceTransport
,
cand
))
{
err
=
new
Error
(
'Can not add ICE candidate'
);
return
Promise
.
reject
(
makeError
(
'OperationError'
,
err
.
name
=
'OperationError'
;
'Can not add ICE candidate'
))
;
}
}
}
}
if
(
!
err
)
{
// update the remoteDescription.
// update the remoteDescription.
var
candidateString
=
candidate
.
candidate
.
trim
();
var
candidateString
=
candidate
.
candidate
.
trim
();
if
(
candidateString
.
indexOf
(
'a='
)
===
0
)
{
if
(
candidateString
.
indexOf
(
'a='
)
===
0
)
{
...
@@ -1495,26 +1544,12 @@ module.exports = function(window, edgeVersion) {
...
@@ -1495,26 +1544,12 @@ module.exports = function(window, edgeVersion) {
(
cand
.
type
?
candidateString
:
'end-of-candidates'
)
(
cand
.
type
?
candidateString
:
'end-of-candidates'
)
+
'
\
r
\
n'
;
+
'
\
r
\
n'
;
this
.
remoteDescription
.
sdp
=
sections
.
join
(
''
);
this
.
remoteDescription
.
sdp
=
sections
.
join
(
''
);
}
}
else
{
}
else
{
err
=
new
Error
(
'Can not add ICE candidate'
);
return
Promise
.
reject
(
makeError
(
'OperationError'
,
err
.
name
=
'OperationError'
;
'Can not add ICE candidate'
))
;
}
}
}
}
var
args
=
arguments
;
return
Promise
.
resolve
();
return
new
Promise
(
function
(
resolve
,
reject
)
{
if
(
err
)
{
if
(
args
.
length
>
2
&&
typeof
args
[
2
]
===
'function'
)
{
args
[
2
].
apply
(
null
,
[
err
]);
}
reject
(
err
);
}
else
{
if
(
args
.
length
>
1
&&
typeof
args
[
1
]
===
'function'
)
{
args
[
1
].
apply
(
null
);
}
resolve
();
}
});
};
};
RTCPeerConnection
.
prototype
.
getStats
=
function
()
{
RTCPeerConnection
.
prototype
.
getStats
=
function
()
{
...
@@ -1527,8 +1562,6 @@ module.exports = function(window, edgeVersion) {
...
@@ -1527,8 +1562,6 @@ module.exports = function(window, edgeVersion) {
}
}
});
});
});
});
var
cb
=
arguments
.
length
>
1
&&
typeof
arguments
[
1
]
===
'function'
&&
arguments
[
1
];
var
fixStatsType
=
function
(
stat
)
{
var
fixStatsType
=
function
(
stat
)
{
return
{
return
{
inboundrtp
:
'inbound-rtp'
,
inboundrtp
:
'inbound-rtp'
,
...
@@ -1548,13 +1581,74 @@ module.exports = function(window, edgeVersion) {
...
@@ -1548,13 +1581,74 @@ module.exports = function(window, edgeVersion) {
results
.
set
(
id
,
result
[
id
]);
results
.
set
(
id
,
result
[
id
]);
});
});
});
});
if
(
cb
)
{
cb
.
apply
(
null
,
results
);
}
resolve
(
results
);
resolve
(
results
);
});
});
});
});
};
};
// legacy callback shims. Should be moved to adapter.js some days.
var
methods
=
[
'createOffer'
,
'createAnswer'
];
methods
.
forEach
(
function
(
method
)
{
var
nativeMethod
=
RTCPeerConnection
.
prototype
[
method
];
RTCPeerConnection
.
prototype
[
method
]
=
function
()
{
var
args
=
arguments
;
if
(
typeof
args
[
0
]
===
'function'
||
typeof
args
[
1
]
===
'function'
)
{
// legacy
return
nativeMethod
.
apply
(
this
,
[
arguments
[
2
]])
.
then
(
function
(
description
)
{
if
(
typeof
args
[
0
]
===
'function'
)
{
args
[
0
].
apply
(
null
,
[
description
]);
}
},
function
(
error
)
{
if
(
typeof
args
[
1
]
===
'function'
)
{
args
[
1
].
apply
(
null
,
[
error
]);
}
});
}
return
nativeMethod
.
apply
(
this
,
arguments
);
};
});
methods
=
[
'setLocalDescription'
,
'setRemoteDescription'
,
'addIceCandidate'
];
methods
.
forEach
(
function
(
method
)
{
var
nativeMethod
=
RTCPeerConnection
.
prototype
[
method
];
RTCPeerConnection
.
prototype
[
method
]
=
function
()
{
var
args
=
arguments
;
if
(
typeof
args
[
1
]
===
'function'
||
typeof
args
[
2
]
===
'function'
)
{
// legacy
return
nativeMethod
.
apply
(
this
,
arguments
)
.
then
(
function
()
{
if
(
typeof
args
[
1
]
===
'function'
)
{
args
[
1
].
apply
(
null
);
}
},
function
(
error
)
{
if
(
typeof
args
[
2
]
===
'function'
)
{
args
[
2
].
apply
(
null
,
[
error
]);
}
});
}
return
nativeMethod
.
apply
(
this
,
arguments
);
};
});
// getStats is special. It doesn't have a spec legacy method yet we support
// getStats(something, cb) without error callbacks.
[
'getStats'
].
forEach
(
function
(
method
)
{
var
nativeMethod
=
RTCPeerConnection
.
prototype
[
method
];
RTCPeerConnection
.
prototype
[
method
]
=
function
()
{
var
args
=
arguments
;
if
(
typeof
args
[
1
]
===
'function'
)
{
return
nativeMethod
.
apply
(
this
,
arguments
)
.
then
(
function
()
{
if
(
typeof
args
[
1
]
===
'function'
)
{
args
[
1
].
apply
(
null
);
}
});
}
return
nativeMethod
.
apply
(
this
,
arguments
);
};
});
return
RTCPeerConnection
;
return
RTCPeerConnection
;
};
};
...
@@ -2261,14 +2355,6 @@ module.exports = function(dependencies, opts) {
...
@@ -2261,14 +2355,6 @@ module.exports = function(dependencies, opts) {
var
logging
=
utils
.
log
;
var
logging
=
utils
.
log
;
var
browserDetails
=
utils
.
detectBrowser
(
window
);
var
browserDetails
=
utils
.
detectBrowser
(
window
);
// Export to the adapter global object visible in the browser.
var
adapter
=
{
browserDetails
:
browserDetails
,
extractVersion
:
utils
.
extractVersion
,
disableLog
:
utils
.
disableLog
,
disableWarnings
:
utils
.
disableWarnings
};
// Uncomment the line below if you want logging to occur, including logging
// Uncomment the line below if you want logging to occur, including logging
// for the switch statement below. Can also be turned on in the browser via
// for the switch statement below. Can also be turned on in the browser via
// adapter.disableLog(false), but then logging from the switch statement below
// adapter.disableLog(false), but then logging from the switch statement below
...
@@ -2282,6 +2368,15 @@ module.exports = function(dependencies, opts) {
...
@@ -2282,6 +2368,15 @@ module.exports = function(dependencies, opts) {
var
safariShim
=
require
(
'./safari/safari_shim'
)
||
null
;
var
safariShim
=
require
(
'./safari/safari_shim'
)
||
null
;
var
commonShim
=
require
(
'./common_shim'
)
||
null
;
var
commonShim
=
require
(
'./common_shim'
)
||
null
;
// Export to the adapter global object visible in the browser.
var
adapter
=
{
browserDetails
:
browserDetails
,
commonShim
:
commonShim
,
extractVersion
:
utils
.
extractVersion
,
disableLog
:
utils
.
disableLog
,
disableWarnings
:
utils
.
disableWarnings
};
// Shim browser if found.
// Shim browser if found.
switch
(
browserDetails
.
browser
)
{
switch
(
browserDetails
.
browser
)
{
case
'chrome'
:
case
'chrome'
:
...
@@ -2304,6 +2399,8 @@ module.exports = function(dependencies, opts) {
...
@@ -2304,6 +2399,8 @@ module.exports = function(dependencies, opts) {
chromeShim
.
shimGetSendersWithDtmf
(
window
);
chromeShim
.
shimGetSendersWithDtmf
(
window
);
commonShim
.
shimRTCIceCandidate
(
window
);
commonShim
.
shimRTCIceCandidate
(
window
);
commonShim
.
shimMaxMessageSize
(
window
);
commonShim
.
shimSendThrowTypeError
(
window
);
break
;
break
;
case
'firefox'
:
case
'firefox'
:
if
(
!
firefoxShim
||
!
firefoxShim
.
shimPeerConnection
||
if
(
!
firefoxShim
||
!
firefoxShim
.
shimPeerConnection
||
...
@@ -2323,6 +2420,8 @@ module.exports = function(dependencies, opts) {
...
@@ -2323,6 +2420,8 @@ module.exports = function(dependencies, opts) {
firefoxShim
.
shimRemoveStream
(
window
);
firefoxShim
.
shimRemoveStream
(
window
);
commonShim
.
shimRTCIceCandidate
(
window
);
commonShim
.
shimRTCIceCandidate
(
window
);
commonShim
.
shimMaxMessageSize
(
window
);
commonShim
.
shimSendThrowTypeError
(
window
);
break
;
break
;
case
'edge'
:
case
'edge'
:
if
(
!
edgeShim
||
!
edgeShim
.
shimPeerConnection
||
!
options
.
shimEdge
)
{
if
(
!
edgeShim
||
!
edgeShim
.
shimPeerConnection
||
!
options
.
shimEdge
)
{
...
@@ -2339,6 +2438,9 @@ module.exports = function(dependencies, opts) {
...
@@ -2339,6 +2438,9 @@ module.exports = function(dependencies, opts) {
edgeShim
.
shimReplaceTrack
(
window
);
edgeShim
.
shimReplaceTrack
(
window
);
// the edge shim implements the full RTCIceCandidate object.
// the edge shim implements the full RTCIceCandidate object.
commonShim
.
shimMaxMessageSize
(
window
);
commonShim
.
shimSendThrowTypeError
(
window
);
break
;
break
;
case
'safari'
:
case
'safari'
:
if
(
!
safariShim
||
!
options
.
shimSafari
)
{
if
(
!
safariShim
||
!
options
.
shimSafari
)
{
...
@@ -2359,6 +2461,8 @@ module.exports = function(dependencies, opts) {
...
@@ -2359,6 +2461,8 @@ module.exports = function(dependencies, opts) {
safariShim
.
shimCreateOfferLegacy
(
window
);
safariShim
.
shimCreateOfferLegacy
(
window
);
commonShim
.
shimRTCIceCandidate
(
window
);
commonShim
.
shimRTCIceCandidate
(
window
);
commonShim
.
shimMaxMessageSize
(
window
);
commonShim
.
shimSendThrowTypeError
(
window
);
break
;
break
;
default
:
default
:
logging
(
'Unsupported browser!'
);
logging
(
'Unsupported browser!'
);
...
@@ -2382,7 +2486,8 @@ module.exports = function(dependencies, opts) {
...
@@ -2382,7 +2486,8 @@ module.exports = function(dependencies, opts) {
var
utils
=
require
(
'../utils.js'
);
var
utils
=
require
(
'../utils.js'
);
var
logging
=
utils
.
log
;
var
logging
=
utils
.
log
;
var
chromeShim
=
{
module
.
exports
=
{
shimGetUserMedia
:
require
(
'./getusermedia'
),
shimMediaStream
:
function
(
window
)
{
shimMediaStream
:
function
(
window
)
{
window
.
MediaStream
=
window
.
MediaStream
||
window
.
webkitMediaStream
;
window
.
MediaStream
=
window
.
MediaStream
||
window
.
webkitMediaStream
;
},
},
...
@@ -2447,6 +2552,13 @@ var chromeShim = {
...
@@ -2447,6 +2552,13 @@ var chromeShim = {
}
}
return
origSetRemoteDescription
.
apply
(
pc
,
arguments
);
return
origSetRemoteDescription
.
apply
(
pc
,
arguments
);
};
};
}
else
if
(
!
(
'RTCRtpTransceiver'
in
window
))
{
utils
.
wrapPeerConnectionEvent
(
window
,
'track'
,
function
(
e
)
{
if
(
!
e
.
transceiver
)
{
e
.
transceiver
=
{
receiver
:
e
.
receiver
};
}
return
e
;
});
}
}
},
},
...
@@ -2598,12 +2710,88 @@ var chromeShim = {
...
@@ -2598,12 +2710,88 @@ var chromeShim = {
}
}
},
},
shimAddTrackRemoveTrackWithNative
:
function
(
window
)
{
// shim addTrack/removeTrack with native variants in order to make
// the interactions with legacy getLocalStreams behave as in other browsers.
// Keeps a mapping stream.id => [stream, rtpsenders...]
window
.
RTCPeerConnection
.
prototype
.
getLocalStreams
=
function
()
{
var
pc
=
this
;
this
.
_shimmedLocalStreams
=
this
.
_shimmedLocalStreams
||
{};
return
Object
.
keys
(
this
.
_shimmedLocalStreams
).
map
(
function
(
streamId
)
{
return
pc
.
_shimmedLocalStreams
[
streamId
][
0
];
});
};
var
origAddTrack
=
window
.
RTCPeerConnection
.
prototype
.
addTrack
;
window
.
RTCPeerConnection
.
prototype
.
addTrack
=
function
(
track
,
stream
)
{
if
(
!
stream
)
{
return
origAddTrack
.
apply
(
this
,
arguments
);
}
this
.
_shimmedLocalStreams
=
this
.
_shimmedLocalStreams
||
{};
var
sender
=
origAddTrack
.
apply
(
this
,
arguments
);
if
(
!
this
.
_shimmedLocalStreams
[
stream
.
id
])
{
this
.
_shimmedLocalStreams
[
stream
.
id
]
=
[
stream
,
sender
];
}
else
if
(
this
.
_shimmedLocalStreams
[
stream
.
id
].
indexOf
(
sender
)
===
-
1
)
{
this
.
_shimmedLocalStreams
[
stream
.
id
].
push
(
sender
);
}
return
sender
;
};
var
origAddStream
=
window
.
RTCPeerConnection
.
prototype
.
addStream
;
window
.
RTCPeerConnection
.
prototype
.
addStream
=
function
(
stream
)
{
var
pc
=
this
;
this
.
_shimmedLocalStreams
=
this
.
_shimmedLocalStreams
||
{};
stream
.
getTracks
().
forEach
(
function
(
track
)
{
var
alreadyExists
=
pc
.
getSenders
().
find
(
function
(
s
)
{
return
s
.
track
===
track
;
});
if
(
alreadyExists
)
{
throw
new
DOMException
(
'Track already exists.'
,
'InvalidAccessError'
);
}
});
var
existingSenders
=
pc
.
getSenders
();
origAddStream
.
apply
(
this
,
arguments
);
var
newSenders
=
pc
.
getSenders
().
filter
(
function
(
newSender
)
{
return
existingSenders
.
indexOf
(
newSender
)
===
-
1
;
});
this
.
_shimmedLocalStreams
[
stream
.
id
]
=
[
stream
].
concat
(
newSenders
);
};
var
origRemoveStream
=
window
.
RTCPeerConnection
.
prototype
.
removeStream
;
window
.
RTCPeerConnection
.
prototype
.
removeStream
=
function
(
stream
)
{
this
.
_shimmedLocalStreams
=
this
.
_shimmedLocalStreams
||
{};
delete
this
.
_shimmedLocalStreams
[
stream
.
id
];
return
origRemoveStream
.
apply
(
this
,
arguments
);
};
var
origRemoveTrack
=
window
.
RTCPeerConnection
.
prototype
.
removeTrack
;
window
.
RTCPeerConnection
.
prototype
.
removeTrack
=
function
(
sender
)
{
var
pc
=
this
;
this
.
_shimmedLocalStreams
=
this
.
_shimmedLocalStreams
||
{};
if
(
sender
)
{
Object
.
keys
(
this
.
_shimmedLocalStreams
).
forEach
(
function
(
streamId
)
{
var
idx
=
pc
.
_shimmedLocalStreams
[
streamId
].
indexOf
(
sender
);
if
(
idx
!==
-
1
)
{
pc
.
_shimmedLocalStreams
[
streamId
].
splice
(
idx
,
1
);
}
if
(
pc
.
_shimmedLocalStreams
[
streamId
].
length
===
1
)
{
delete
pc
.
_shimmedLocalStreams
[
streamId
];
}
});
}
return
origRemoveTrack
.
apply
(
this
,
arguments
);
};
},
shimAddTrackRemoveTrack
:
function
(
window
)
{
shimAddTrackRemoveTrack
:
function
(
window
)
{
var
browserDetails
=
utils
.
detectBrowser
(
window
);
var
browserDetails
=
utils
.
detectBrowser
(
window
);
// shim addTrack and removeTrack.
// shim addTrack and removeTrack.
if
(
window
.
RTCPeerConnection
.
prototype
.
addTrack
&&
if
(
window
.
RTCPeerConnection
.
prototype
.
addTrack
&&
browserDetails
.
version
>=
6
4
)
{
browserDetails
.
version
>=
6
5
)
{
return
;
return
this
.
shimAddTrackRemoveTrackWithNative
(
window
)
;
}
}
// also shim pc.getLocalStreams when addTrack is shimmed
// also shim pc.getLocalStreams when addTrack is shimmed
...
@@ -2611,11 +2799,11 @@ var chromeShim = {
...
@@ -2611,11 +2799,11 @@ var chromeShim = {
var
origGetLocalStreams
=
window
.
RTCPeerConnection
.
prototype
var
origGetLocalStreams
=
window
.
RTCPeerConnection
.
prototype
.
getLocalStreams
;
.
getLocalStreams
;
window
.
RTCPeerConnection
.
prototype
.
getLocalStreams
=
function
()
{
window
.
RTCPeerConnection
.
prototype
.
getLocalStreams
=
function
()
{
var
self
=
this
;
var
pc
=
this
;
var
nativeStreams
=
origGetLocalStreams
.
apply
(
this
);
var
nativeStreams
=
origGetLocalStreams
.
apply
(
this
);
self
.
_reverseStreams
=
self
.
_reverseStreams
||
{};
pc
.
_reverseStreams
=
pc
.
_reverseStreams
||
{};
return
nativeStreams
.
map
(
function
(
stream
)
{
return
nativeStreams
.
map
(
function
(
stream
)
{
return
self
.
_reverseStreams
[
stream
.
id
];
return
pc
.
_reverseStreams
[
stream
.
id
];
});
});
};
};
...
@@ -2841,7 +3029,7 @@ var chromeShim = {
...
@@ -2841,7 +3029,7 @@ var chromeShim = {
var
browserDetails
=
utils
.
detectBrowser
(
window
);
var
browserDetails
=
utils
.
detectBrowser
(
window
);
// The RTCPeerConnection object.
// The RTCPeerConnection object.
if
(
!
window
.
RTCPeerConnection
)
{
if
(
!
window
.
RTCPeerConnection
&&
window
.
webkitRTCPeerConnection
)
{
window
.
RTCPeerConnection
=
function
(
pcConfig
,
pcConstraints
)
{
window
.
RTCPeerConnection
=
function
(
pcConfig
,
pcConstraints
)
{
// Translate iceTransportPolicy to iceTransports,
// Translate iceTransportPolicy to iceTransports,
// see https://code.google.com/p/webrtc/issues/detail?id=4869
// see https://code.google.com/p/webrtc/issues/detail?id=4869
...
@@ -2897,7 +3085,7 @@ var chromeShim = {
...
@@ -2897,7 +3085,7 @@ var chromeShim = {
var
origGetStats
=
window
.
RTCPeerConnection
.
prototype
.
getStats
;
var
origGetStats
=
window
.
RTCPeerConnection
.
prototype
.
getStats
;
window
.
RTCPeerConnection
.
prototype
.
getStats
=
function
(
selector
,
window
.
RTCPeerConnection
.
prototype
.
getStats
=
function
(
selector
,
successCallback
,
errorCallback
)
{
successCallback
,
errorCallback
)
{
var
self
=
this
;
var
pc
=
this
;
var
args
=
arguments
;
var
args
=
arguments
;
// If selector is a function then we are in the old style stats so just
// If selector is a function then we are in the old style stats so just
...
@@ -2952,7 +3140,7 @@ var chromeShim = {
...
@@ -2952,7 +3140,7 @@ var chromeShim = {
// promise-support
// promise-support
return
new
Promise
(
function
(
resolve
,
reject
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
origGetStats
.
apply
(
self
,
[
origGetStats
.
apply
(
pc
,
[
function
(
response
)
{
function
(
response
)
{
resolve
(
makeMapStats
(
fixChromeStats_
(
response
)));
resolve
(
makeMapStats
(
fixChromeStats_
(
response
)));
},
reject
]);
},
reject
]);
...
@@ -2966,9 +3154,9 @@ var chromeShim = {
...
@@ -2966,9 +3154,9 @@ var chromeShim = {
var
nativeMethod
=
window
.
RTCPeerConnection
.
prototype
[
method
];
var
nativeMethod
=
window
.
RTCPeerConnection
.
prototype
[
method
];
window
.
RTCPeerConnection
.
prototype
[
method
]
=
function
()
{
window
.
RTCPeerConnection
.
prototype
[
method
]
=
function
()
{
var
args
=
arguments
;
var
args
=
arguments
;
var
self
=
this
;
var
pc
=
this
;
var
promise
=
new
Promise
(
function
(
resolve
,
reject
)
{
var
promise
=
new
Promise
(
function
(
resolve
,
reject
)
{
nativeMethod
.
apply
(
self
,
[
args
[
0
],
resolve
,
reject
]);
nativeMethod
.
apply
(
pc
,
[
args
[
0
],
resolve
,
reject
]);
});
});
if
(
args
.
length
<
2
)
{
if
(
args
.
length
<
2
)
{
return
promise
;
return
promise
;
...
@@ -2991,12 +3179,12 @@ var chromeShim = {
...
@@ -2991,12 +3179,12 @@ var chromeShim = {
[
'createOffer'
,
'createAnswer'
].
forEach
(
function
(
method
)
{
[
'createOffer'
,
'createAnswer'
].
forEach
(
function
(
method
)
{
var
nativeMethod
=
window
.
RTCPeerConnection
.
prototype
[
method
];
var
nativeMethod
=
window
.
RTCPeerConnection
.
prototype
[
method
];
window
.
RTCPeerConnection
.
prototype
[
method
]
=
function
()
{
window
.
RTCPeerConnection
.
prototype
[
method
]
=
function
()
{
var
self
=
this
;
var
pc
=
this
;
if
(
arguments
.
length
<
1
||
(
arguments
.
length
===
1
&&
if
(
arguments
.
length
<
1
||
(
arguments
.
length
===
1
&&
typeof
arguments
[
0
]
===
'object'
))
{
typeof
arguments
[
0
]
===
'object'
))
{
var
opts
=
arguments
.
length
===
1
?
arguments
[
0
]
:
undefined
;
var
opts
=
arguments
.
length
===
1
?
arguments
[
0
]
:
undefined
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
nativeMethod
.
apply
(
self
,
[
resolve
,
reject
,
opts
]);
nativeMethod
.
apply
(
pc
,
[
resolve
,
reject
,
opts
]);
});
});
}
}
return
nativeMethod
.
apply
(
this
,
arguments
);
return
nativeMethod
.
apply
(
this
,
arguments
);
...
@@ -3031,18 +3219,6 @@ var chromeShim = {
...
@@ -3031,18 +3219,6 @@ var chromeShim = {
}
}
};
};
// Expose public methods.
module
.
exports
=
{
shimMediaStream
:
chromeShim
.
shimMediaStream
,
shimOnTrack
:
chromeShim
.
shimOnTrack
,
shimAddTrackRemoveTrack
:
chromeShim
.
shimAddTrackRemoveTrack
,
shimGetSendersWithDtmf
:
chromeShim
.
shimGetSendersWithDtmf
,
shimSourceObject
:
chromeShim
.
shimSourceObject
,
shimPeerConnection
:
chromeShim
.
shimPeerConnection
,
shimGetUserMedia
:
require
(
'./getusermedia'
)
};
},{
"../utils.js"
:
13
,
"./getusermedia"
:
6
}],
6
:[
function
(
require
,
module
,
exports
){
},{
"../utils.js"
:
13
,
"./getusermedia"
:
6
}],
6
:[
function
(
require
,
module
,
exports
){
/*
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
...
@@ -3299,57 +3475,6 @@ module.exports = function(window) {
...
@@ -3299,57 +3475,6 @@ module.exports = function(window) {
var
SDPUtils
=
require
(
'sdp'
);
var
SDPUtils
=
require
(
'sdp'
);
var
utils
=
require
(
'./utils'
);
var
utils
=
require
(
'./utils'
);
// Wraps the peerconnection event eventNameToWrap in a function
// which returns the modified event object.
function
wrapPeerConnectionEvent
(
window
,
eventNameToWrap
,
wrapper
)
{
if
(
!
window
.
RTCPeerConnection
)
{
return
;
}
var
proto
=
window
.
RTCPeerConnection
.
prototype
;
var
nativeAddEventListener
=
proto
.
addEventListener
;
proto
.
addEventListener
=
function
(
nativeEventName
,
cb
)
{
if
(
nativeEventName
!==
eventNameToWrap
)
{
return
nativeAddEventListener
.
apply
(
this
,
arguments
);
}
var
wrappedCallback
=
function
(
e
)
{
cb
(
wrapper
(
e
));
};
this
.
_eventMap
=
this
.
_eventMap
||
{};
this
.
_eventMap
[
cb
]
=
wrappedCallback
;
return
nativeAddEventListener
.
apply
(
this
,
[
nativeEventName
,
wrappedCallback
]);
};
var
nativeRemoveEventListener
=
proto
.
removeEventListener
;
proto
.
removeEventListener
=
function
(
nativeEventName
,
cb
)
{
if
(
nativeEventName
!==
eventNameToWrap
||
!
this
.
_eventMap
||
!
this
.
_eventMap
[
cb
])
{
return
nativeRemoveEventListener
.
apply
(
this
,
arguments
);
}
var
unwrappedCb
=
this
.
_eventMap
[
cb
];
delete
this
.
_eventMap
[
cb
];
return
nativeRemoveEventListener
.
apply
(
this
,
[
nativeEventName
,
unwrappedCb
]);
};
Object
.
defineProperty
(
proto
,
'on'
+
eventNameToWrap
,
{
get
:
function
()
{
return
this
[
'_on'
+
eventNameToWrap
];
},
set
:
function
(
cb
)
{
if
(
this
[
'_on'
+
eventNameToWrap
])
{
this
.
removeEventListener
(
eventNameToWrap
,
this
[
'_on'
+
eventNameToWrap
]);
delete
this
[
'_on'
+
eventNameToWrap
];
}
if
(
cb
)
{
this
.
addEventListener
(
eventNameToWrap
,
this
[
'_on'
+
eventNameToWrap
]
=
cb
);
}
}
});
}
module
.
exports
=
{
module
.
exports
=
{
shimRTCIceCandidate
:
function
(
window
)
{
shimRTCIceCandidate
:
function
(
window
)
{
// foundation is arbitrarily chosen as an indicator for full support for
// foundation is arbitrarily chosen as an indicator for full support for
...
@@ -3388,7 +3513,7 @@ module.exports = {
...
@@ -3388,7 +3513,7 @@ module.exports = {
// Hook up the augmented candidate in onicecandidate and
// Hook up the augmented candidate in onicecandidate and
// addEventListener('icecandidate', ...)
// addEventListener('icecandidate', ...)
wrapPeerConnectionEvent
(
window
,
'icecandidate'
,
function
(
e
)
{
utils
.
wrapPeerConnectionEvent
(
window
,
'icecandidate'
,
function
(
e
)
{
if
(
e
.
candidate
)
{
if
(
e
.
candidate
)
{
Object
.
defineProperty
(
e
,
'candidate'
,
{
Object
.
defineProperty
(
e
,
'candidate'
,
{
value
:
new
window
.
RTCIceCandidate
(
e
.
candidate
),
value
:
new
window
.
RTCIceCandidate
(
e
.
candidate
),
...
@@ -3450,6 +3575,165 @@ module.exports = {
...
@@ -3450,6 +3575,165 @@ module.exports = {
}
}
return
nativeSetAttribute
.
apply
(
this
,
arguments
);
return
nativeSetAttribute
.
apply
(
this
,
arguments
);
};
};
},
shimMaxMessageSize
:
function
(
window
)
{
if
(
window
.
RTCSctpTransport
||
!
window
.
RTCPeerConnection
)
{
return
;
}
var
browserDetails
=
utils
.
detectBrowser
(
window
);
if
(
!
(
'sctp'
in
window
.
RTCPeerConnection
.
prototype
))
{
Object
.
defineProperty
(
window
.
RTCPeerConnection
.
prototype
,
'sctp'
,
{
get
:
function
()
{
return
typeof
this
.
_sctp
===
'undefined'
?
null
:
this
.
_sctp
;
}
});
}
var
sctpInDescription
=
function
(
description
)
{
var
sections
=
SDPUtils
.
splitSections
(
description
.
sdp
);
sections
.
shift
();
return
sections
.
some
(
function
(
mediaSection
)
{
var
mLine
=
SDPUtils
.
parseMLine
(
mediaSection
);
return
mLine
&&
mLine
.
kind
===
'application'
&&
mLine
.
protocol
.
indexOf
(
'SCTP'
)
!==
-
1
;
});
};
var
getRemoteFirefoxVersion
=
function
(
description
)
{
// TODO: Is there a better solution for detecting Firefox?
var
match
=
description
.
sdp
.
match
(
/mozilla...THIS_IS_SDPARTA-
(\d
+
)
/
);
if
(
match
===
null
||
match
.
length
<
2
)
{
return
-
1
;
}
var
version
=
parseInt
(
match
[
1
],
10
);
// Test for NaN (yes, this is ugly)
return
version
!==
version
?
-
1
:
version
;
};
var
getCanSendMaxMessageSize
=
function
(
remoteIsFirefox
)
{
// Every implementation we know can send at least 64 KiB.
// Note: Although Chrome is technically able to send up to 256 KiB, the
// data does not reach the other peer reliably.
// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419
var
canSendMaxMessageSize
=
65536
;
if
(
browserDetails
.
browser
===
'firefox'
)
{
if
(
browserDetails
.
version
<
57
)
{
if
(
remoteIsFirefox
===
-
1
)
{
// FF < 57 will send in 16 KiB chunks using the deprecated PPID
// fragmentation.
canSendMaxMessageSize
=
16384
;
}
else
{
// However, other FF (and RAWRTC) can reassemble PPID-fragmented
// messages. Thus, supporting ~2 GiB when sending.
canSendMaxMessageSize
=
2147483637
;
}
}
else
{
// Currently, all FF >= 57 will reset the remote maximum message size
// to the default value when a data channel is created at a later
// stage. :(
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
canSendMaxMessageSize
=
browserDetails
.
version
===
57
?
65535
:
65536
;
}
}
return
canSendMaxMessageSize
;
};
var
getMaxMessageSize
=
function
(
description
,
remoteIsFirefox
)
{
// Note: 65536 bytes is the default value from the SDP spec. Also,
// every implementation we know supports receiving 65536 bytes.
var
maxMessageSize
=
65536
;
// FF 57 has a slightly incorrect default remote max message size, so
// we need to adjust it here to avoid a failure when sending.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697
if
(
browserDetails
.
browser
===
'firefox'
&&
browserDetails
.
version
===
57
)
{
maxMessageSize
=
65535
;
}
var
match
=
SDPUtils
.
matchPrefix
(
description
.
sdp
,
'a=max-message-size:'
);
if
(
match
.
length
>
0
)
{
maxMessageSize
=
parseInt
(
match
[
0
].
substr
(
19
),
10
);
}
else
if
(
browserDetails
.
browser
===
'firefox'
&&
remoteIsFirefox
!==
-
1
)
{
// If the maximum message size is not present in the remote SDP and
// both local and remote are Firefox, the remote peer can receive
// ~2 GiB.
maxMessageSize
=
2147483637
;
}
return
maxMessageSize
;
};
var
origSetRemoteDescription
=
window
.
RTCPeerConnection
.
prototype
.
setRemoteDescription
;
window
.
RTCPeerConnection
.
prototype
.
setRemoteDescription
=
function
()
{
var
pc
=
this
;
pc
.
_sctp
=
null
;
if
(
sctpInDescription
(
arguments
[
0
]))
{
// Check if the remote is FF.
var
isFirefox
=
getRemoteFirefoxVersion
(
arguments
[
0
]);
// Get the maximum message size the local peer is capable of sending
var
canSendMMS
=
getCanSendMaxMessageSize
(
isFirefox
);
// Get the maximum message size of the remote peer.
var
remoteMMS
=
getMaxMessageSize
(
arguments
[
0
],
isFirefox
);
// Determine final maximum message size
var
maxMessageSize
;
if
(
canSendMMS
===
0
&&
remoteMMS
===
0
)
{
maxMessageSize
=
Number
.
POSITIVE_INFINITY
;
}
else
if
(
canSendMMS
===
0
||
remoteMMS
===
0
)
{
maxMessageSize
=
Math
.
max
(
canSendMMS
,
remoteMMS
);
}
else
{
maxMessageSize
=
Math
.
min
(
canSendMMS
,
remoteMMS
);
}
// Create a dummy RTCSctpTransport object and the 'maxMessageSize'
// attribute.
var
sctp
=
{};
Object
.
defineProperty
(
sctp
,
'maxMessageSize'
,
{
get
:
function
()
{
return
maxMessageSize
;
}
});
pc
.
_sctp
=
sctp
;
}
return
origSetRemoteDescription
.
apply
(
pc
,
arguments
);
};
},
shimSendThrowTypeError
:
function
(
window
)
{
// Note: Although Firefox >= 57 has a native implementation, the maximum
// message size can be reset for all data channels at a later stage.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
var
origCreateDataChannel
=
window
.
RTCPeerConnection
.
prototype
.
createDataChannel
;
window
.
RTCPeerConnection
.
prototype
.
createDataChannel
=
function
()
{
var
pc
=
this
;
var
dataChannel
=
origCreateDataChannel
.
apply
(
pc
,
arguments
);
var
origDataChannelSend
=
dataChannel
.
send
;
// Patch 'send' method
dataChannel
.
send
=
function
()
{
var
dc
=
this
;
var
data
=
arguments
[
0
];
var
length
=
data
.
length
||
data
.
size
||
data
.
byteLength
;
if
(
length
>
pc
.
sctp
.
maxMessageSize
)
{
throw
new
DOMException
(
'Message too large (can send a maximum of '
+
pc
.
sctp
.
maxMessageSize
+
' bytes)'
,
'TypeError'
);
}
return
origDataChannelSend
.
apply
(
dc
,
arguments
);
};
return
dataChannel
;
};
}
}
};
};
...
@@ -3584,7 +3868,8 @@ module.exports = function(window) {
...
@@ -3584,7 +3868,8 @@ module.exports = function(window) {
var
utils
=
require
(
'../utils'
);
var
utils
=
require
(
'../utils'
);
var
firefoxShim
=
{
module
.
exports
=
{
shimGetUserMedia
:
require
(
'./getusermedia'
),
shimOnTrack
:
function
(
window
)
{
shimOnTrack
:
function
(
window
)
{
if
(
typeof
window
===
'object'
&&
window
.
RTCPeerConnection
&&
!
(
'ontrack'
in
if
(
typeof
window
===
'object'
&&
window
.
RTCPeerConnection
&&
!
(
'ontrack'
in
window
.
RTCPeerConnection
.
prototype
))
{
window
.
RTCPeerConnection
.
prototype
))
{
...
@@ -3789,15 +4074,6 @@ var firefoxShim = {
...
@@ -3789,15 +4074,6 @@ var firefoxShim = {
}
}
};
};
// Expose public methods.
module
.
exports
=
{
shimOnTrack
:
firefoxShim
.
shimOnTrack
,
shimSourceObject
:
firefoxShim
.
shimSourceObject
,
shimPeerConnection
:
firefoxShim
.
shimPeerConnection
,
shimRemoveStream
:
firefoxShim
.
shimRemoveStream
,
shimGetUserMedia
:
require
(
'./getusermedia'
)
};
},{
"../utils"
:
13
,
"./getusermedia"
:
11
}],
11
:[
function
(
require
,
module
,
exports
){
},{
"../utils"
:
13
,
"./getusermedia"
:
11
}],
11
:[
function
(
require
,
module
,
exports
){
/*
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
...
@@ -4020,13 +4296,7 @@ module.exports = function(window) {
...
@@ -4020,13 +4296,7 @@ module.exports = function(window) {
'use strict'
;
'use strict'
;
var
utils
=
require
(
'../utils'
);
var
utils
=
require
(
'../utils'
);
var
safariShim
=
{
module
.
exports
=
{
// TODO: DrAlex, should be here, double check against LayoutTests
// TODO: once the back-end for the mac port is done, add.
// TODO: check for webkitGTK+
// shimPeerConnection: function() { },
shimLocalStreamsAPI
:
function
(
window
)
{
shimLocalStreamsAPI
:
function
(
window
)
{
if
(
typeof
window
!==
'object'
||
!
window
.
RTCPeerConnection
)
{
if
(
typeof
window
!==
'object'
||
!
window
.
RTCPeerConnection
)
{
return
;
return
;
...
@@ -4068,9 +4338,9 @@ var safariShim = {
...
@@ -4068,9 +4338,9 @@ var safariShim = {
if
(
this
.
_localStreams
.
indexOf
(
stream
)
===
-
1
)
{
if
(
this
.
_localStreams
.
indexOf
(
stream
)
===
-
1
)
{
this
.
_localStreams
.
push
(
stream
);
this
.
_localStreams
.
push
(
stream
);
}
}
var
self
=
this
;
var
pc
=
this
;
stream
.
getTracks
().
forEach
(
function
(
track
)
{
stream
.
getTracks
().
forEach
(
function
(
track
)
{
_addTrack
.
call
(
self
,
track
,
stream
);
_addTrack
.
call
(
pc
,
track
,
stream
);
});
});
};
};
...
@@ -4095,11 +4365,11 @@ var safariShim = {
...
@@ -4095,11 +4365,11 @@ var safariShim = {
return
;
return
;
}
}
this
.
_localStreams
.
splice
(
index
,
1
);
this
.
_localStreams
.
splice
(
index
,
1
);
var
self
=
this
;
var
pc
=
this
;
var
tracks
=
stream
.
getTracks
();
var
tracks
=
stream
.
getTracks
();
this
.
getSenders
().
forEach
(
function
(
sender
)
{
this
.
getSenders
().
forEach
(
function
(
sender
)
{
if
(
tracks
.
indexOf
(
sender
.
track
)
!==
-
1
)
{
if
(
tracks
.
indexOf
(
sender
.
track
)
!==
-
1
)
{
self
.
removeTrack
(
sender
);
pc
.
removeTrack
(
sender
);
}
}
});
});
};
};
...
@@ -4120,24 +4390,26 @@ var safariShim = {
...
@@ -4120,24 +4390,26 @@ var safariShim = {
return
this
.
_onaddstream
;
return
this
.
_onaddstream
;
},
},
set
:
function
(
f
)
{
set
:
function
(
f
)
{
var
pc
=
this
;
if
(
this
.
_onaddstream
)
{
if
(
this
.
_onaddstream
)
{
this
.
removeEventListener
(
'addstream'
,
this
.
_onaddstream
);
this
.
removeEventListener
(
'addstream'
,
this
.
_onaddstream
);
this
.
removeEventListener
(
'track'
,
this
.
_onaddstreampoly
);
this
.
removeEventListener
(
'track'
,
this
.
_onaddstreampoly
);
}
}
this
.
addEventListener
(
'addstream'
,
this
.
_onaddstream
=
f
);
this
.
addEventListener
(
'addstream'
,
this
.
_onaddstream
=
f
);
this
.
addEventListener
(
'track'
,
this
.
_onaddstreampoly
=
function
(
e
)
{
this
.
addEventListener
(
'track'
,
this
.
_onaddstreampoly
=
function
(
e
)
{
var
stream
=
e
.
streams
[
0
];
e
.
streams
.
forEach
(
function
(
stream
)
{
if
(
!
this
.
_remoteStreams
)
{
if
(
!
pc
.
_remoteStreams
)
{
this
.
_remoteStreams
=
[];
pc
.
_remoteStreams
=
[];
}
}
if
(
this
.
_remoteStreams
.
indexOf
(
stream
)
>=
0
)
{
if
(
pc
.
_remoteStreams
.
indexOf
(
stream
)
>=
0
)
{
return
;
return
;
}
}
this
.
_remoteStreams
.
push
(
stream
);
pc
.
_remoteStreams
.
push
(
stream
);
var
event
=
new
Event
(
'addstream'
);
var
event
=
new
Event
(
'addstream'
);
event
.
stream
=
e
.
streams
[
0
];
event
.
stream
=
stream
;
this
.
dispatchEvent
(
event
);
pc
.
dispatchEvent
(
event
);
}.
bind
(
this
));
});
});
}
}
});
});
}
}
...
@@ -4277,9 +4549,17 @@ var safariShim = {
...
@@ -4277,9 +4549,17 @@ var safariShim = {
});
});
if
(
offerOptions
.
offerToReceiveAudio
===
false
&&
audioTransceiver
)
{
if
(
offerOptions
.
offerToReceiveAudio
===
false
&&
audioTransceiver
)
{
if
(
audioTransceiver
.
direction
===
'sendrecv'
)
{
if
(
audioTransceiver
.
direction
===
'sendrecv'
)
{
if
(
audioTransceiver
.
setDirection
)
{
audioTransceiver
.
setDirection
(
'sendonly'
);
audioTransceiver
.
setDirection
(
'sendonly'
);
}
else
{
audioTransceiver
.
direction
=
'sendonly'
;
}
}
else
if
(
audioTransceiver
.
direction
===
'recvonly'
)
{
}
else
if
(
audioTransceiver
.
direction
===
'recvonly'
)
{
if
(
audioTransceiver
.
setDirection
)
{
audioTransceiver
.
setDirection
(
'inactive'
);
audioTransceiver
.
setDirection
(
'inactive'
);
}
else
{
audioTransceiver
.
direction
=
'inactive'
;
}
}
}
}
else
if
(
offerOptions
.
offerToReceiveAudio
===
true
&&
}
else
if
(
offerOptions
.
offerToReceiveAudio
===
true
&&
!
audioTransceiver
)
{
!
audioTransceiver
)
{
...
@@ -4306,19 +4586,6 @@ var safariShim = {
...
@@ -4306,19 +4586,6 @@ var safariShim = {
}
}
};
};
// Expose public methods.
module
.
exports
=
{
shimCallbacksAPI
:
safariShim
.
shimCallbacksAPI
,
shimLocalStreamsAPI
:
safariShim
.
shimLocalStreamsAPI
,
shimRemoteStreamsAPI
:
safariShim
.
shimRemoteStreamsAPI
,
shimGetUserMedia
:
safariShim
.
shimGetUserMedia
,
shimRTCIceServerUrls
:
safariShim
.
shimRTCIceServerUrls
,
shimTrackEventTransceiver
:
safariShim
.
shimTrackEventTransceiver
,
shimCreateOfferLegacy
:
safariShim
.
shimCreateOfferLegacy
// TODO
// shimPeerConnection: safariShim.shimPeerConnection
};
},{
"../utils"
:
13
}],
13
:[
function
(
require
,
module
,
exports
){
},{
"../utils"
:
13
}],
13
:[
function
(
require
,
module
,
exports
){
/*
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
...
@@ -4333,8 +4600,74 @@ module.exports = {
...
@@ -4333,8 +4600,74 @@ module.exports = {
var
logDisabled_
=
true
;
var
logDisabled_
=
true
;
var
deprecationWarnings_
=
true
;
var
deprecationWarnings_
=
true
;
/**
* Extract browser version out of the provided user agent string.
*
* @param {!string} uastring userAgent string.
* @param {!string} expr Regular expression used as match criteria.
* @param {!number} pos position in the version string to be returned.
* @return {!number} browser version.
*/
function
extractVersion
(
uastring
,
expr
,
pos
)
{
var
match
=
uastring
.
match
(
expr
);
return
match
&&
match
.
length
>=
pos
&&
parseInt
(
match
[
pos
],
10
);
}
// Wraps the peerconnection event eventNameToWrap in a function
// which returns the modified event object.
function
wrapPeerConnectionEvent
(
window
,
eventNameToWrap
,
wrapper
)
{
if
(
!
window
.
RTCPeerConnection
)
{
return
;
}
var
proto
=
window
.
RTCPeerConnection
.
prototype
;
var
nativeAddEventListener
=
proto
.
addEventListener
;
proto
.
addEventListener
=
function
(
nativeEventName
,
cb
)
{
if
(
nativeEventName
!==
eventNameToWrap
)
{
return
nativeAddEventListener
.
apply
(
this
,
arguments
);
}
var
wrappedCallback
=
function
(
e
)
{
cb
(
wrapper
(
e
));
};
this
.
_eventMap
=
this
.
_eventMap
||
{};
this
.
_eventMap
[
cb
]
=
wrappedCallback
;
return
nativeAddEventListener
.
apply
(
this
,
[
nativeEventName
,
wrappedCallback
]);
};
var
nativeRemoveEventListener
=
proto
.
removeEventListener
;
proto
.
removeEventListener
=
function
(
nativeEventName
,
cb
)
{
if
(
nativeEventName
!==
eventNameToWrap
||
!
this
.
_eventMap
||
!
this
.
_eventMap
[
cb
])
{
return
nativeRemoveEventListener
.
apply
(
this
,
arguments
);
}
var
unwrappedCb
=
this
.
_eventMap
[
cb
];
delete
this
.
_eventMap
[
cb
];
return
nativeRemoveEventListener
.
apply
(
this
,
[
nativeEventName
,
unwrappedCb
]);
};
Object
.
defineProperty
(
proto
,
'on'
+
eventNameToWrap
,
{
get
:
function
()
{
return
this
[
'_on'
+
eventNameToWrap
];
},
set
:
function
(
cb
)
{
if
(
this
[
'_on'
+
eventNameToWrap
])
{
this
.
removeEventListener
(
eventNameToWrap
,
this
[
'_on'
+
eventNameToWrap
]);
delete
this
[
'_on'
+
eventNameToWrap
];
}
if
(
cb
)
{
this
.
addEventListener
(
eventNameToWrap
,
this
[
'_on'
+
eventNameToWrap
]
=
cb
);
}
}
});
}
// Utility methods.
// Utility methods.
var
utils
=
{
module
.
exports
=
{
extractVersion
:
extractVersion
,
wrapPeerConnectionEvent
:
wrapPeerConnectionEvent
,
disableLog
:
function
(
bool
)
{
disableLog
:
function
(
bool
)
{
if
(
typeof
bool
!==
'boolean'
)
{
if
(
typeof
bool
!==
'boolean'
)
{
return
new
Error
(
'Argument type: '
+
typeof
bool
+
return
new
Error
(
'Argument type: '
+
typeof
bool
+
...
@@ -4380,19 +4713,6 @@ var utils = {
...
@@ -4380,19 +4713,6 @@ var utils = {
' instead.'
);
' instead.'
);
},
},
/**
* Extract browser version out of the provided user agent string.
*
* @param {!string} uastring userAgent string.
* @param {!string} expr Regular expression used as match criteria.
* @param {!number} pos position in the version string to be returned.
* @return {!number} browser version.
*/
extractVersion
:
function
(
uastring
,
expr
,
pos
)
{
var
match
=
uastring
.
match
(
expr
);
return
match
&&
match
.
length
>=
pos
&&
parseInt
(
match
[
pos
],
10
);
},
/**
/**
* Browser detector.
* Browser detector.
*
*
...
@@ -4413,38 +4733,25 @@ var utils = {
...
@@ -4413,38 +4733,25 @@ var utils = {
return
result
;
return
result
;
}
}
// Firefox.
if
(
navigator
.
mozGetUserMedia
)
{
// Firefox.
if
(
navigator
.
mozGetUserMedia
)
{
result
.
browser
=
'firefox'
;
result
.
browser
=
'firefox'
;
result
.
version
=
this
.
extractVersion
(
navigator
.
userAgent
,
result
.
version
=
extractVersion
(
navigator
.
userAgent
,
/Firefox
\/(\d
+
)\.
/
,
1
);
/Firefox
\/(\d
+
)\.
/
,
1
);
}
else
if
(
navigator
.
webkitGetUserMedia
)
{
}
else
if
(
navigator
.
webkitGetUserMedia
)
{
// Chrome, Chromium, Webview, Opera
, all use the chrome shim for now
// Chrome, Chromium, Webview, Opera
.
if
(
window
.
webkitRTCPeerConnection
)
{
// Version matches Chrome/WebRTC version.
result
.
browser
=
'chrome'
;
result
.
browser
=
'chrome'
;
result
.
version
=
this
.
extractVersion
(
navigator
.
userAgent
,
result
.
version
=
extractVersion
(
navigator
.
userAgent
,
/Chrom
(
e|ium
)\/(\d
+
)\.
/
,
2
);
/Chrom
(
e|ium
)\/(\d
+
)\.
/
,
2
);
}
else
{
// Safari (in an unpublished version) or unknown webkit-based.
if
(
navigator
.
userAgent
.
match
(
/Version
\/(\d
+
)
.
(\d
+
)
/
))
{
result
.
browser
=
'safari'
;
result
.
version
=
this
.
extractVersion
(
navigator
.
userAgent
,
/AppleWebKit
\/(\d
+
)\.
/
,
1
);
}
else
{
// unknown webkit-based browser.
result
.
browser
=
'Unsupported webkit-based browser '
+
'with GUM support but no WebRTC support.'
;
return
result
;
}
}
}
else
if
(
navigator
.
mediaDevices
&&
}
else
if
(
navigator
.
mediaDevices
&&
navigator
.
userAgent
.
match
(
/Edge
\/(\d
+
)
.
(\d
+
)
$/
))
{
// Edge.
navigator
.
userAgent
.
match
(
/Edge
\/(\d
+
)
.
(\d
+
)
$/
))
{
// Edge.
result
.
browser
=
'edge'
;
result
.
browser
=
'edge'
;
result
.
version
=
this
.
extractVersion
(
navigator
.
userAgent
,
result
.
version
=
extractVersion
(
navigator
.
userAgent
,
/Edge
\/(\d
+
)
.
(\d
+
)
$/
,
2
);
/Edge
\/(\d
+
)
.
(\d
+
)
$/
,
2
);
}
else
if
(
navigator
.
mediaDevices
&&
}
else
if
(
navigator
.
mediaDevices
&&
navigator
.
userAgent
.
match
(
/AppleWebKit
\/(\d
+
)\.
/
))
{
navigator
.
userAgent
.
match
(
/AppleWebKit
\/(\d
+
)\.
/
))
{
// Safari.
// Safari, with webkitGetUserMedia removed.
result
.
browser
=
'safari'
;
result
.
browser
=
'safari'
;
result
.
version
=
this
.
extractVersion
(
navigator
.
userAgent
,
result
.
version
=
extractVersion
(
navigator
.
userAgent
,
/AppleWebKit
\/(\d
+
)\.
/
,
1
);
/AppleWebKit
\/(\d
+
)\.
/
,
1
);
}
else
{
// Default fallthrough: not supported.
}
else
{
// Default fallthrough: not supported.
result
.
browser
=
'Not a supported browser.'
;
result
.
browser
=
'Not a supported browser.'
;
...
@@ -4452,19 +4759,7 @@ var utils = {
...
@@ -4452,19 +4759,7 @@ var utils = {
}
}
return
result
;
return
result
;
},
}
};
// Export.
module
.
exports
=
{
log
:
utils
.
log
,
deprecated
:
utils
.
deprecated
,
disableLog
:
utils
.
disableLog
,
disableWarnings
:
utils
.
disableWarnings
,
extractVersion
:
utils
.
extractVersion
,
shimCreateObjectURL
:
utils
.
shimCreateObjectURL
,
detectBrowser
:
utils
.
detectBrowser
.
bind
(
utils
)
};
};
},{}]},{},[
3
])(
3
)
},{}]},{},[
3
])(
3
)
...
...
html5/verto/video_demo-live_canvas/js/verto-min.js
浏览文件 @
5fa0a04b
This diff was suppressed by a .gitattributes entry.
html5/verto/video_demo/js/verto-min.js
浏览文件 @
5fa0a04b
This diff was suppressed by a .gitattributes entry.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论