| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| |
| <!-- |
| To quickly iterate when developing this test, make sure you select |
| 'Always allow this site to use this webcam' option in the dropdown menu of |
| Chrome when it's requesting access to your webcam. |
| Notice that this requires the site you're browsing to use HTTPS. |
| |
| Without that, the test might timeout before you have had the chance to accept |
| access to the webcam. |
| --> |
| |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <title>PeerConnection Connection Test</title> |
| |
| <script src="https://w3c-test.org/resources/testharness.js"></script> |
| |
| <script type="text/javascript"> |
| var test = async_test('Can set up a basic WebRTC call.', {timeout: 5000}); |
| var gFirstConnection = null; |
| var gSecondConnection = null; |
| |
| function getUserMediaOkCallback(localStream) { |
| gFirstConnection = new webkitRTCPeerConnection(null, null); |
| gFirstConnection.onicecandidate = onIceCandidateToFirst; |
| gFirstConnection.addStream(localStream); |
| gFirstConnection.createOffer(onOfferCreated); |
| |
| var videoTag = document.getElementById('local-view'); |
| videoTag.src = webkitURL.createObjectURL(localStream); |
| }; |
| |
| var onOfferCreated = test.step_func(function(offer) { |
| gFirstConnection.setLocalDescription(offer); |
| |
| // This would normally go across the application's signaling solution. |
| // In our case, the "signaling" is to call this function. |
| receiveCall(offer.sdp); |
| }); |
| |
| function receiveCall(offerSdp) { |
| gSecondConnection = new webkitRTCPeerConnection(null, null); |
| gSecondConnection.onicecandidate = onIceCandidateToSecond; |
| gSecondConnection.onaddstream = onRemoteStream; |
| |
| var parsedOffer = new RTCSessionDescription({ type: 'offer', |
| sdp: offerSdp }); |
| gSecondConnection.setRemoteDescription(parsedOffer); |
| |
| gSecondConnection.createAnswer(onAnswerCreated, |
| failed('createAnswer')); |
| }; |
| |
| var onAnswerCreated = test.step_func(function(answer) { |
| gSecondConnection.setLocalDescription(answer); |
| |
| // Similarly, this would go over the application's signaling solution. |
| handleAnswer(answer.sdp); |
| }); |
| |
| function handleAnswer(answerSdp) { |
| var parsedAnswer = new RTCSessionDescription({ type: 'answer', |
| sdp: answerSdp }); |
| gFirstConnection.setRemoteDescription(parsedAnswer); |
| |
| // Call negotiated: done. |
| test.done(); |
| }; |
| |
| // Note: the ice candidate handlers are special. We can not wrap them in test |
| // steps since that seems to cause some kind of starvation that prevents the |
| // call of being set up. Unfortunately we cannot report errors in here. |
| var onIceCandidateToFirst = function(event) { |
| // If event.candidate is null = no more candidates. |
| if (event.candidate) { |
| var candidate = new RTCIceCandidate(event.candidate); |
| gSecondConnection.addIceCandidate(candidate); |
| } |
| }; |
| |
| var onIceCandidateToSecond = function(event) { |
| if (event.candidate) { |
| var candidate = new RTCIceCandidate(event.candidate); |
| gFirstConnection.addIceCandidate(candidate); |
| } |
| }; |
| |
| var onRemoteStream = test.step_func(function(event) { |
| var videoTag = document.getElementById('remote-view'); |
| videoTag.src = webkitURL.createObjectURL(event.stream); |
| }); |
| |
| // Returns a suitable error callback. |
| function failed(function_name) { |
| return test.step_func(function() { |
| assert_unreached('WebRTC called error callback for ' + function_name); |
| }); |
| } |
| |
| // This function starts the test. |
| test.step(function() { |
| navigator.webkitGetUserMedia({ video: true, audio: true }, |
| getUserMediaOkCallback, |
| failed('getUserMedia')); |
| }); |
| </script> |
| </head> |
| |
| <body> |
| |
| <div> |
| <video width="320" height="240" id="remote-view" autoplay="autoplay"></video> |
| <video width="320" height="240" id="local-view" autoplay="autoplay"></video> |
| </div> |
| <div id="log"></div> |
| </body> |
| </html> |