<!doctype html> <!-- To quickly iterate when developing this test, use --use-fake-ui-for-media-stream for Chrome and set the media.navigator.permission.disabled property to true in Firefox. You must either have a webcam/mic available on the system or use for instance --use-fake-device-for-media-stream for Chrome. --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>RTCPeerConnection Connection Test</title> </head> <body> <div id="log"></div> <div> <video id="local-view" autoplay="autoplay"></video> <video id="remote-view" autoplay="autoplay"/> </video> </div> <!-- These files are in place when executing on W3C. --> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/common/vendor-prefix.js" data-prefixed-objects= '[{"ancestors":["navigator"], "name":"getUserMedia"}]' data-prefixed-prototypes= '[{"ancestors":["HTMLMediaElement"],"name":"srcObject"}]'> </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 RTCPeerConnection(null); gFirstConnection.onicecandidate = onIceCandidateToFirst; gFirstConnection.addStream(localStream); gFirstConnection.createOffer(onOfferCreated, failed('createOffer')); var videoTag = document.getElementById('local-view'); videoTag.srcObject = 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 RTCPeerConnection(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(); }; var onIceCandidateToFirst = test.step_func(function(event) { // If event.candidate is null = no more candidates. if (event.candidate) { gSecondConnection.addIceCandidate(event.candidate); } }); var onIceCandidateToSecond = test.step_func(function(event) { if (event.candidate) { gFirstConnection.addIceCandidate(event.candidate); } }); var onRemoteStream = test.step_func(function(event) { var videoTag = document.getElementById('remote-view'); videoTag.srcObject = 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.getUserMedia({ video: true, audio: true }, getUserMediaOkCallback, failed('getUserMedia')); }); </script> </body> </html>