vikasmarwaha@webrtc.org | 98fce15 | 2013-02-27 23:22:10 +0000 | [diff] [blame] | 1 | <!DOCTYPE html> |
| 2 | <html> |
| 3 | <head> |
| 4 | <title>PeerConnection Demo 1</title> |
| 5 | <!-- Load the polyfill to switch-hit between Chrome and Firefox --> |
| 6 | <script src="../../base/adapter.js"></script> |
| 7 | <style> |
| 8 | video { |
| 9 | border:5px solid black; |
| 10 | width:480px; |
| 11 | height:360px; |
| 12 | } |
| 13 | button { |
| 14 | font: 18px sans-serif; |
| 15 | padding: 8px; |
| 16 | } |
| 17 | textarea { |
| 18 | font-family: monospace; |
| 19 | margin: 2px; |
| 20 | width:480px; |
| 21 | height:640px; |
| 22 | } |
| 23 | </style> |
| 24 | </head> |
| 25 | <body> |
vikasmarwaha@webrtc.org | da0f708 | 2013-03-11 16:58:07 +0000 | [diff] [blame] | 26 | <video id="vid1" autoplay="true" muted="true"></video> |
vikasmarwaha@webrtc.org | 98fce15 | 2013-02-27 23:22:10 +0000 | [diff] [blame] | 27 | <video id="vid2" autoplay></video> |
| 28 | <video id="vid3" autoplay></video> |
| 29 | <br> |
| 30 | <button id="btn1" onclick="start()">Start</button> |
| 31 | <button id="btn2" onclick="call()">Call</button> |
| 32 | <button id="btn3" onclick="hangup()">Hang Up</button> |
| 33 | <br> |
| 34 | <script> |
| 35 | //var vid1 = document.getElementById("vid1"); |
| 36 | //var vid2 = document.getElementById("vid2"); |
| 37 | btn1.disabled = false; |
| 38 | btn2.disabled = true; |
| 39 | btn3.disabled = true; |
| 40 | var pc1_local, pc1_remote; |
| 41 | var pc2_local, pc2_remote; |
| 42 | var localstream; |
| 43 | var sdpConstraints = {'mandatory': { |
| 44 | 'OfferToReceiveAudio':true, |
| 45 | 'OfferToReceiveVideo':true }}; |
| 46 | |
vikasmarwaha@webrtc.org | 98fce15 | 2013-02-27 23:22:10 +0000 | [diff] [blame] | 47 | function gotStream(stream){ |
| 48 | trace("Received local stream"); |
| 49 | // Call the polyfill wrapper to attach the media stream to this element. |
| 50 | attachMediaStream(vid1, stream); |
| 51 | localstream = stream; |
| 52 | btn2.disabled = false; |
| 53 | } |
| 54 | |
| 55 | function start() { |
| 56 | trace("Requesting local stream"); |
| 57 | btn1.disabled = true; |
| 58 | // Call into getUserMedia via the polyfill (adapter.js). |
| 59 | getUserMedia({audio:true, video:true}, |
| 60 | gotStream, function() {}); |
| 61 | } |
| 62 | |
| 63 | function call() { |
| 64 | btn2.disabled = true; |
| 65 | btn3.disabled = false; |
| 66 | trace("Starting calls"); |
| 67 | videoTracks = localstream.getVideoTracks(); |
| 68 | audioTracks = localstream.getAudioTracks(); |
| 69 | if (videoTracks.length > 0) |
| 70 | trace("Using Video device: " + videoTracks[0].label); |
| 71 | if (audioTracks.length > 0) |
| 72 | trace("Using Audio device: " + audioTracks[0].label); |
| 73 | |
| 74 | // Create an RTCPeerConnection via the polyfill (adapter.js). |
| 75 | var servers = null; |
| 76 | pc1_local = new RTCPeerConnection(servers); |
| 77 | pc1_remote = new RTCPeerConnection(servers); |
| 78 | pc1_remote.onaddstream = gotRemoteStream1; |
| 79 | pc1_local.onicecandidate = iceCallback1Local; |
| 80 | pc1_remote.onicecandidate = iceCallback1Remote; |
| 81 | trace("PC1: created local and remote peer connection objects"); |
| 82 | |
| 83 | pc2_local = new RTCPeerConnection(servers); |
| 84 | pc2_remote = new RTCPeerConnection(servers); |
| 85 | pc2_remote.onaddstream = gotRemoteStream2; |
| 86 | pc2_local.onicecandidate = iceCallback2Local; |
| 87 | pc2_remote.onicecandidate = iceCallback2Remote; |
| 88 | trace("PC2: created local and remote peer connection objects"); |
| 89 | |
| 90 | pc1_local.addStream(localstream); |
| 91 | trace("Adding local stream to pc1_local"); |
| 92 | pc1_local.createOffer(gotDescription1Local); |
| 93 | |
| 94 | pc2_local.addStream(localstream); |
| 95 | trace("Adding local stream to pc2_local"); |
| 96 | pc2_local.createOffer(gotDescription2Local); |
| 97 | } |
| 98 | |
| 99 | function gotDescription1Local(desc) { |
| 100 | pc1_local.setLocalDescription(desc); |
| 101 | trace("Offer from pc1_local \n" + desc.sdp); |
| 102 | pc1_remote.setRemoteDescription(desc); |
| 103 | // Since the "remote" side has no media stream we need |
| 104 | // to pass in the right constraints in order for it to |
| 105 | // accept the incoming offer of audio and video. |
| 106 | pc1_remote.createAnswer(gotDescription1Remote, null, sdpConstraints); |
| 107 | } |
| 108 | |
| 109 | function gotDescription1Remote(desc) { |
| 110 | pc1_remote.setLocalDescription(desc); |
| 111 | trace("Answer from pc1_remote \n" + desc.sdp); |
| 112 | pc1_local.setRemoteDescription(desc); |
| 113 | } |
| 114 | |
| 115 | function gotDescription2Local(desc) { |
| 116 | pc2_local.setLocalDescription(desc); |
| 117 | trace("Offer from pc2_local \n" + desc.sdp); |
| 118 | pc2_remote.setRemoteDescription(desc); |
| 119 | // Since the "remote" side has no media stream we need |
| 120 | // to pass in the right constraints in order for it to |
| 121 | // accept the incoming offer of audio and video. |
| 122 | pc2_remote.createAnswer(gotDescription2Remote, null, sdpConstraints); |
| 123 | } |
| 124 | |
| 125 | function gotDescription2Remote(desc) { |
| 126 | pc2_remote.setLocalDescription(desc); |
| 127 | trace("Answer from pc2_remote \n" + desc.sdp); |
| 128 | pc2_local.setRemoteDescription(desc); |
| 129 | } |
| 130 | |
| 131 | function hangup() { |
| 132 | trace("Ending calls"); |
| 133 | pc1_local.close(); |
| 134 | pc1_remote.close(); |
| 135 | pc2_local.close(); |
| 136 | pc2_remote.close(); |
| 137 | pc1_local = pc1_remote = null; |
| 138 | pc2_local = pc2_remote = null; |
| 139 | btn3.disabled = true; |
| 140 | btn2.disabled = false; |
| 141 | } |
| 142 | |
| 143 | function gotRemoteStream1(e) { |
| 144 | vid2.src = webkitURL.createObjectURL(e.stream); |
| 145 | trace("PC1: Received remote stream"); |
| 146 | } |
| 147 | |
| 148 | function gotRemoteStream2(e) { |
| 149 | vid3.src = webkitURL.createObjectURL(e.stream); |
| 150 | trace("PC2: Received remote stream"); |
| 151 | } |
| 152 | |
| 153 | function iceCallback1Local(event) { |
| 154 | handleCandidate(event.candidate, pc1_remote, "PC1: ", "local"); |
| 155 | } |
| 156 | |
| 157 | function iceCallback1Remote(event) { |
| 158 | handleCandidate(event.candidate, pc1_local, "PC1: ", "remote"); |
| 159 | } |
| 160 | |
| 161 | function iceCallback2Local(event) { |
| 162 | handleCandidate(event.candidate, pc2_remote, "PC2: ", "local"); |
| 163 | } |
| 164 | |
| 165 | function iceCallback2Remote(event) { |
| 166 | handleCandidate(event.candidate, pc2_local, "PC2: ", "remote"); |
| 167 | } |
| 168 | |
| 169 | function handleCandidate(candidate, dest, prefix, type) { |
| 170 | if (candidate) { |
| 171 | dest.addIceCandidate(new RTCIceCandidate(candidate)); |
| 172 | trace(prefix + "New " + type + " ICE candidate: " + candidate.candidate); |
| 173 | } |
| 174 | } |
| 175 | </script> |
| 176 | </body> |
| 177 | </html> |
| 178 | |
| 179 | |