From 04f7484f7d47b597a353995d7f131a2e753fa310 Mon Sep 17 00:00:00 2001 From: Felix Zapata Date: Thu, 25 May 2017 10:58:00 +0200 Subject: [PATCH 1/2] feat(iosRTC): add support for cordova ios rtc plugin --- .../erizoClient/src/Connection.js | 10 + .../erizoClient/src/webrtc-stacks/iOSStack.js | 211 ++++++++++++++++++ erizo_controller/erizoClient/tools/compile.sh | 2 +- .../erizoClient/tools/compileDebug.sh | 1 + .../erizoClient/tools/compilefc.sh | 2 +- 5 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 erizo_controller/erizoClient/src/webrtc-stacks/iOSStack.js diff --git a/erizo_controller/erizoClient/src/Connection.js b/erizo_controller/erizoClient/src/Connection.js index 4a17b35c24..9294a79d8f 100644 --- a/erizo_controller/erizoClient/src/Connection.js +++ b/erizo_controller/erizoClient/src/Connection.js @@ -20,6 +20,9 @@ Erizo.Connection = function (spec) { } else if (that.browser === 'bowser'){ L.Logger.debug('Bowser Stack'); that = Erizo.BowserStack(spec); + } else if (that.browser === 'ios'){ + L.Logger.debug("iOS Stack"); + that = Erizo.iOSStack(spec); } else if (that.browser === 'chrome-stable') { L.Logger.debug('Chrome Stable Stack'); that = Erizo.ChromeStableStack(spec); @@ -54,6 +57,8 @@ Erizo.getBrowser = function () { } } else if (window.navigator.userAgent.match('Safari') !== null) { browser = 'bowser'; + } else if (window.navigator.userAgent.match("AppleWebKit") !== null && cordova) { + browser = "ios"; } else if (window.navigator.userAgent.match('AppleWebKit') !== null) { browser = 'bowser'; } @@ -63,6 +68,11 @@ Erizo.getBrowser = function () { Erizo.GetUserMedia = function (config, callback, error) { var promise; + + if (Erizo.getBrowser() === 'ios') { + navigator.getUserMedia = cordova.plugins.iosrtc.getUserMedia; + } + navigator.getMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || diff --git a/erizo_controller/erizoClient/src/webrtc-stacks/iOSStack.js b/erizo_controller/erizoClient/src/webrtc-stacks/iOSStack.js new file mode 100644 index 0000000000..43c5981d02 --- /dev/null +++ b/erizo_controller/erizoClient/src/webrtc-stacks/iOSStack.js @@ -0,0 +1,211 @@ +/*global window, console, RTCSessionDescription, RoapConnection, webkitRTCPeerConnection*/ + +var Erizo = Erizo || {}; + +Erizo.iOSStack = function (spec) { + "use strict"; + + var that = {}, + WebkitRTCPeerConnection = cordova.plugins.iosrtc.RTCPeerConnection, + RTCSessionDescription = cordova.plugins.iosrtc.RTCSessionDescription, + RTCIceCandidate = cordova.plugins.iosrtc.RTCIceCandidate; + + that.pc_config = { + "iceServers": [] + }; + + that.con = {'optional': [{'DtlsSrtpKeyAgreement': true}]}; + + if (spec.stunServerUrl !== undefined) { + that.pc_config.iceServers.push({"url": spec.stunServerUrl}); + } + + if ((spec.turnServer || {}).url) { + that.pc_config.iceServers.push({"username": spec.turnServer.username, "credential": spec.turnServer.password, "url": spec.turnServer.url}); + } + + if (spec.audio === undefined) { + spec.audio = true; + } + + if (spec.video === undefined) { + spec.video = true; + } + + that.mediaConstraints = { + 'offerToReceiveVideo': spec.video, + 'offerToReceiveAudio': spec.audio + }; + + that.peerConnection = new WebkitRTCPeerConnection(that.pc_config, that.con); + + spec.remoteDescriptionSet = false; + + var setMaxBW = function (sdp) { + if (spec.maxVideoBW) { + var a = sdp.match(/m=video.*\r\n/); + if (a == null){ + a = sdp.match(/m=video.*\n/); + } + if (a && (a.length > 0)) { + var r = a[0] + "b=AS:" + spec.maxVideoBW + "\r\n"; + sdp = sdp.replace(a[0], r); + } + } + + if (spec.maxAudioBW) { + var a = sdp.match(/m=audio.*\r\n/); + if (a == null){ + a = sdp.match(/m=audio.*\n/); + } + if (a && (a.length > 0)) { + var r = a[0] + "b=AS:" + spec.maxAudioBW + "\r\n"; + sdp = sdp.replace(a[0], r); + } + } + + return sdp; + }; + + /** + * Closes the connection. + */ + that.close = function () { + that.state = 'closed'; + that.peerConnection.close(); + }; + + spec.localCandidates = []; + + that.peerConnection.onicecandidate = function (event) { + if (event.candidate) { + if (!event.candidate.candidate.match(/a=/)) { + event.candidate.candidate ="a="+event.candidate.candidate; + }; + + + if (spec.remoteDescriptionSet) { + spec.callback({type:'candidate', candidate: event.candidate}); + } else { + spec.localCandidates.push(event.candidate); +// console.log("Local Candidates stored: ", spec.localCandidates.length, spec.localCandidates); + } + + } else { + + // spec.callback(that.peerConnection.localDescription); + console.log("End of candidates." , that.peerConnection.localDescription); + } + }; + + that.peerConnection.onaddstream = function (stream) { + if (that.onaddstream) { + that.onaddstream(stream); + } + }; + + that.peerConnection.onremovestream = function (stream) { + if (that.onremovestream) { + that.onremovestream(stream); + } + }; + + var errorCallback = function(message){ + console.log("Error in Stack ", message); + } + + var localDesc; + + var setLocalDesc = function (sessionDescription) { + sessionDescription.sdp = setMaxBW(sessionDescription.sdp); +// sessionDescription.sdp = sessionDescription.sdp.replace(/a=ice-options:google-ice\r\n/g, ""); + console.log("Set local description", sessionDescription.sdp); + localDesc = sessionDescription; + that.peerConnection.setLocalDescription(localDesc, function(){ + console.log("The final LocalDesc", that.peerConnection.localDescription); + spec.callback(that.peerConnection.localDescription); + }, errorCallback); + //that.peerConnection.setLocalDescription(sessionDescription); + } + + var setLocalDescp2p = function (sessionDescription) { + sessionDescription.sdp = setMaxBW(sessionDescription.sdp); +// sessionDescription.sdp = sessionDescription.sdp.replace(/a=ice-options:google-ice\r\n/g, ""); + spec.callback(sessionDescription); + localDesc = sessionDescription; + that.peerConnection.setLocalDescription(sessionDescription); + } + + that.createOffer = function (isSubscribe) { + if (isSubscribe===true) + that.peerConnection.createOffer(setLocalDesc, errorCallback, that.mediaConstraints); + else + that.peerConnection.createOffer(setLocalDesc, errorCallback); + + }; + + that.addStream = function (stream) { + that.peerConnection.addStream(stream); + }; + spec.remoteCandidates = []; + + + that.processSignalingMessage = function (msg) { + console.log("Process Signaling Message", msg); + + if (msg.type === 'offer') { + msg.sdp = setMaxBW(msg.sdp); + that.peerConnection.setRemoteDescription(new RTCSessionDescription(msg)); + that.peerConnection.createAnswer(setLocalDescp2p, null, that.mediaConstraints); + spec.remoteDescriptionSet = true; + + } else if (msg.type === 'answer') { + + console.log("Set remote description", msg.sdp); + + msg.sdp = setMaxBW(msg.sdp); + + that.peerConnection.setRemoteDescription(new RTCSessionDescription(msg), function() { + spec.remoteDescriptionSet = true; + console.log("Candidates to be added: ", spec.remoteCandidates.length); + while (spec.remoteCandidates.length > 0) { + console.log("Candidate :",spec.remoteCandidates[spec.remoteCandidates.length-1]); + that.peerConnection.addIceCandidate(spec.remoteCandidates.shift(), function(){}, errorCallback); + + } +// console.log("Local candidates to send:" , spec.localCandidates.length); + while(spec.localCandidates.length > 0) { + spec.callback({type:'candidate', candidate: spec.localCandidates.shift()}); + } + + }, function(){console.log("Error Setting Remote Description");}); + + } else if (msg.type === 'candidate') { + console.log("Message with candidate"); + try { + var obj; + if (typeof(msg.candidate) === 'object') { + obj = msg.candidate; + } else { + obj = JSON.parse(msg.candidate); + } +// obj.candidate = obj.candidate.replace(/ generation 0/g, ""); +// obj.candidate = obj.candidate.replace(/ udp /g, " UDP "); + obj.candidate = obj.candidate.replace(/a=/g, ""); + obj.sdpMLineIndex = parseInt(obj.sdpMLineIndex); + obj.sdpMLineIndex = obj.sdpMid=="audio"?0:1; + var candidate = new RTCIceCandidate(obj); + console.log("Remote Candidate",candidate); + if (spec.remoteDescriptionSet) { + that.peerConnection.addIceCandidate(candidate, function(){}, errorCallback); + } else { + spec.remoteCandidates.push(candidate); + } + } catch(e) { + L.Logger.error("Error parsing candidate", msg.candidate); + } + } + } + + return that; +}; \ No newline at end of file diff --git a/erizo_controller/erizoClient/tools/compile.sh b/erizo_controller/erizoClient/tools/compile.sh index 4cae7d9384..246b373646 100755 --- a/erizo_controller/erizoClient/tools/compile.sh +++ b/erizo_controller/erizoClient/tools/compile.sh @@ -2,4 +2,4 @@ set -e -java -jar compiler.jar --js ../lib/socket.io.js --js ../src/Events.js --js ../src/webrtc-stacks/FcStack.js --js ../src/webrtc-stacks/BowserStack.js --js ../src/webrtc-stacks/FirefoxStack.js --js ../src/webrtc-stacks/ChromeStableStack.js --js ../src/webrtc-stacks/ChromeCanaryStack.js --js ../src/Connection.js --js ../src/Stream.js --js ../src/Room.js --js ../src/utils/L.Logger.js --js ../src/utils/L.Base64.js --js ../src/utils/L.Resizer.js --js ../src/views/View.js --js ../src/views/VideoPlayer.js --js ../src/views/AudioPlayer.js --js ../src/views/Bar.js --js ../src/views/Speaker.js --js_output_file ../dist/erizo.js +java -jar compiler.jar --js ../lib/socket.io.js --js ../src/Events.js --js ../src/webrtc-stacks/FcStack.js --js ../src/webrtc-stacks/BowserStack.js --js ../src/webrtc-stacks/FirefoxStack.js --js ../src/webrtc-stacks/ChromeStableStack.js --js ../src/webrtc-stacks/ChromeCanaryStack.js --js ../src/webrtc-stacks/iOSStack.js --js ../src/Connection.js --js ../src/Stream.js --js ../src/Room.js --js ../src/utils/L.Logger.js --js ../src/utils/L.Base64.js --js ../src/utils/L.Resizer.js --js ../src/views/View.js --js ../src/views/VideoPlayer.js --js ../src/views/AudioPlayer.js --js ../src/views/Bar.js --js ../src/views/Speaker.js --js_output_file ../dist/erizo.js diff --git a/erizo_controller/erizoClient/tools/compileDebug.sh b/erizo_controller/erizoClient/tools/compileDebug.sh index fd3ed69cc4..68945bf5e2 100755 --- a/erizo_controller/erizoClient/tools/compileDebug.sh +++ b/erizo_controller/erizoClient/tools/compileDebug.sh @@ -11,6 +11,7 @@ cat ../src/webrtc-stacks/ChromeStableStack.js >> $FILE cat ../src/webrtc-stacks/ChromeCanaryStack.js >> $FILE cat ../src/webrtc-stacks/FirefoxStack.js >> $FILE cat ../src/webrtc-stacks/BowserStack.js >> $FILE +cat ../src/webrtc-stacks/iOSStack.js >> $FILE cat ../src/Connection.js >> $FILE cat ../src/Stream.js >> $FILE cat ../src/Room.js >> $FILE diff --git a/erizo_controller/erizoClient/tools/compilefc.sh b/erizo_controller/erizoClient/tools/compilefc.sh index dca7dbd37f..93edd10ec0 100755 --- a/erizo_controller/erizoClient/tools/compilefc.sh +++ b/erizo_controller/erizoClient/tools/compilefc.sh @@ -8,7 +8,7 @@ fi mkdir ../build -java -jar compiler.jar --js ../src/Events.js --js ../src/webrtc-stacks/FcStack.js --js ../src/webrtc-stacks/ChromeStableStack.js --js ../src/webrtc-stacks/ChromeCanaryStack.js --js ../src/Connection.js --js ../src/Stream.js --js ../src/Room.js --js ../src/utils/L.Logger.js --js ../src/utils/L.Base64.js --js ../src/views/View.js --js ../src/views/VideoPlayer.js --js ../src/views/AudioPlayer.js --js ../src/views/Bar.js --js ../src/views/Speaker.js --js_output_file ../build/erizofc.js +java -jar compiler.jar --js ../src/Events.js --js ../src/webrtc-stacks/FcStack.js --js ../src/webrtc-stacks/ChromeStableStack.js --js ../src/webrtc-stacks/ChromeCanaryStack.js --js ../src/webrtc-stacks/iOSStack.js --js ../src/Connection.js --js ../src/Stream.js --js ../src/Room.js --js ../src/utils/L.Logger.js --js ../src/utils/L.Base64.js --js ../src/views/View.js --js ../src/views/VideoPlayer.js --js ../src/views/AudioPlayer.js --js ../src/views/Bar.js --js ../src/views/Speaker.js --js_output_file ../build/erizofc.js TARGET=../dist/erizofc.js From 0f2e59a099f2377fe249926f85f59dcab1c9033d Mon Sep 17 00:00:00 2001 From: Felix Zapata Date: Fri, 26 May 2017 09:56:59 +0200 Subject: [PATCH 2/2] feat(compilefc.sh): undo the previous changes --- erizo_controller/erizoClient/tools/compilefc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erizo_controller/erizoClient/tools/compilefc.sh b/erizo_controller/erizoClient/tools/compilefc.sh index 93edd10ec0..dca7dbd37f 100755 --- a/erizo_controller/erizoClient/tools/compilefc.sh +++ b/erizo_controller/erizoClient/tools/compilefc.sh @@ -8,7 +8,7 @@ fi mkdir ../build -java -jar compiler.jar --js ../src/Events.js --js ../src/webrtc-stacks/FcStack.js --js ../src/webrtc-stacks/ChromeStableStack.js --js ../src/webrtc-stacks/ChromeCanaryStack.js --js ../src/webrtc-stacks/iOSStack.js --js ../src/Connection.js --js ../src/Stream.js --js ../src/Room.js --js ../src/utils/L.Logger.js --js ../src/utils/L.Base64.js --js ../src/views/View.js --js ../src/views/VideoPlayer.js --js ../src/views/AudioPlayer.js --js ../src/views/Bar.js --js ../src/views/Speaker.js --js_output_file ../build/erizofc.js +java -jar compiler.jar --js ../src/Events.js --js ../src/webrtc-stacks/FcStack.js --js ../src/webrtc-stacks/ChromeStableStack.js --js ../src/webrtc-stacks/ChromeCanaryStack.js --js ../src/Connection.js --js ../src/Stream.js --js ../src/Room.js --js ../src/utils/L.Logger.js --js ../src/utils/L.Base64.js --js ../src/views/View.js --js ../src/views/VideoPlayer.js --js ../src/views/AudioPlayer.js --js ../src/views/Bar.js --js ../src/views/Speaker.js --js_output_file ../build/erizofc.js TARGET=../dist/erizofc.js