327:14066d6ee9ac
Anton Shestakov <av6@dwimlabs.net>, Sat, 14 Jul 2018 23:19:59 +0800
webrtc: use newer getUserMedia()

previous change 317:d7821033e3c0

coffee/webrtc.coffee

Permissions: -rw-r--r--

Other formats: Feeds:
class Tram.WebRTCInterface
lstream: null
rstream: null
constructor: (@contact) ->
@peerJid = @contact.get('jid')
init: (@initiator, constraints) ->
if constraints.audio || constraints.video
navigator.mediaDevices.getUserMedia(constraints).then(@connect, @fail)
else
@connect()
connect: (stream) =>
@call = calls.add(jid: @peerJid, contact: @contact)
@pc = new RTCPeerConnection(iceServers: Tram.config.iceServers)
if stream?
@lstream = stream
@pc.addStream(stream)
@call.set('local/stream', stream)
@pc.onicecandidate = (event) =>
if event.candidate
@sendPayload(event.candidate, 'ice')
@pc.onaddstream = (event) =>
@rstream = event.stream
@call.set('remote/stream', event.stream)
@contact.set('callstate', 'established')
if @initiator
@sendIntent('initiate')
else
@createOffer()
onPayload: (stanza) ->
if not @call?
return
el = stanza.getElementsByTagNameNS(Tram.NS.WEBRTC, 'payload')[0]
signal = JSON.parse(el.firstChild.nodeValue)
if signal.sdp
if signal.type is 'offer'
@receiveOffer(signal)
else if signal.type is 'answer'
@receiveAnswer(signal)
else if signal.candidate
@pc.addIceCandidate(new RTCIceCandidate(signal))
sendPayload: (data, type) ->
payload = JSON.stringify(data)
msg = $msg(to: @peerJid, type: 'chat')
.c('payload', xmlns: Tram.NS.WEBRTC, type: type).t(payload)
X.conn.send(msg.tree())
sendIntent: (intent) ->
msg = $msg(to: @peerJid, type: 'chat')
.c('intent', xmlns: Tram.NS.WEBRTC).t(intent)
X.conn.send(msg.tree())
createOffer: ->
@pc.createOffer((offer) =>
@pc.setLocalDescription(offer, =>
@sendPayload(@pc.localDescription, 'offer')
, @fail)
, @fail)
receiveOffer: (offer) ->
@pc.setRemoteDescription(new RTCSessionDescription(offer), =>
@pc.createAnswer((answer) =>
@pc.setLocalDescription(answer, =>
@sendPayload(@pc.localDescription, 'answer')
, @fail)
, @fail)
, @fail)
receiveAnswer: (answer) ->
@pc.setRemoteDescription(new RTCSessionDescription(answer))
fail: =>
@disconnect()
@contact.unset('callstate')
disconnect: ->
if @call?
@call.unset('remote/stream')
@call.unset('local/stream')
calls.remove(@call)
if @rstream?
@stopStream(@rstream)
#@pc?.removeStream?(@rstream)
if @lstream?
@stopStream(@lstream)
#@pc?.removeStream?(@lstream)
if @pc?
@pc.close()
@pc = null
stopStream: (stream) ->
if stream.getAudioTracks?
for track in stream.getAudioTracks()
track.stop?()
if stream.getVideoTracks?
for track in stream.getVideoTracks()
track.stop?()
stream.stop?()