Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8357)

Unified Diff: chrome/test/data/webrtc/manual/peerconnection_manual.js

Issue 609733002: Replace peerconnection.html with a redirect to github. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed HTML errors Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/test/data/webrtc/manual/peerconnection_manual.js
diff --git a/chrome/test/data/webrtc/manual/peerconnection_manual.js b/chrome/test/data/webrtc/manual/peerconnection_manual.js
deleted file mode 100644
index 2823e4d1dca12fd6a1851a2fbb32e6e8c99ed21f..0000000000000000000000000000000000000000
--- a/chrome/test/data/webrtc/manual/peerconnection_manual.js
+++ /dev/null
@@ -1,1425 +0,0 @@
-/**
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
- /**
- * See http://dev.w3.org/2011/webrtc/editor/getusermedia.html for more
- * information on getUserMedia. See
- * http://dev.w3.org/2011/webrtc/editor/webrtc.html for more information on
- * peerconnection and webrtc in general.
- */
-
-/** TODO(jansson) give it a better name
- * Global namespace object.
- */
-var global = {};
-
-/**
- * We need a STUN server for some API calls.
- * @private
- */
-var STUN_SERVER = 'stun.l.google.com:19302';
-
-/** @private */
-global.transformOutgoingSdp = function(sdp) { return sdp; };
-
-/** @private */
-global.dataStatusCallback = function(status) {};
-
-/** @private */
-global.dataCallback = function(data) {};
-
-/** @private */
-global.dtmfOnToneChange = function(tone) {};
-
-/**
- * Used as a shortcut for finding DOM elements by ID.
- * @param {string} id is a case-sensitive string representing the unique ID of
- * the element being sought.
- * @return {object} id returns the element object specified as a parameter
- */
-$ = function(id) {
- return document.getElementById(id);
-};
-
-/**
- * Prepopulate constraints from JS to the UI. Enumerate devices available
- * via getUserMedia, register elements to be used for local storage.
- */
-window.onload = function() {
- hookupDataChannelCallbacks_();
- hookupDtmfSenderCallback_();
- updateGetUserMediaConstraints();
- setupLocalStorageFieldValues();
- acceptIncomingCalls();
- setPeerConnectionConstraints();
- if ($('get-devices-onload').checked == true) {
- getDevices();
- }
-};
-
-/**
- * Disconnect before the tab is closed.
- */
-window.onbeforeunload = function() {
- disconnect_();
-};
-
-/** TODO (jansson) Fix the event assigment to allow the elements to have more
- * than one event assigned to it (currently replaces existing events).
- * A list of element id's to be registered for local storage.
- */
-function setupLocalStorageFieldValues() {
- registerLocalStorage_('pc-server');
- registerLocalStorage_('pc-createanswer-constraints');
- registerLocalStorage_('pc-createoffer-constraints');
- registerLocalStorage_('get-devices-onload');
-}
-
-// Public HTML functions
-
-// The *Here functions are called from peerconnection.html and will make calls
-// into our underlying JavaScript library with the values from the page
-// (have to be named differently to avoid name clashes with existing functions).
-
-function getUserMediaFromHere() {
- var constraints = $('getusermedia-constraints').value;
- try {
- doGetUserMedia_(constraints);
- } catch (exception) {
- print_('getUserMedia says: ' + exception);
- }
-}
-
-function connectFromHere() {
- var server = $('pc-server').value;
- if ($('peer-id').value == '') {
- // Generate a random name to distinguish us from other tabs:
- $('peer-id').value = 'peer_' + Math.floor(Math.random() * 10000);
- print_('Our name from now on will be ' + $('peer-id').value);
- }
- connect(server, $('peer-id').value);
-}
-
-function negotiateCallFromHere() {
- // Set the global variables with values from our UI.
- setCreateOfferConstraints(getEvaluatedJavaScript_(
- $('pc-createoffer-constraints').value));
- setCreateAnswerConstraints(getEvaluatedJavaScript_(
- $('pc-createanswer-constraints').value));
-
- ensureHasPeerConnection_();
- negotiateCall_();
-}
-
-function addLocalStreamFromHere() {
- ensureHasPeerConnection_();
- addLocalStream();
-}
-
-function removeLocalStreamFromHere() {
- removeLocalStream();
-}
-
-function hangUpFromHere() {
- hangUp();
- acceptIncomingCalls();
-}
-
-function toggleRemoteVideoFromHere() {
- toggleRemoteStream(function(remoteStream) {
- return remoteStream.getVideoTracks()[0];
- }, 'video');
-}
-
-function toggleRemoteAudioFromHere() {
- toggleRemoteStream(function(remoteStream) {
- return remoteStream.getAudioTracks()[0];
- }, 'audio');
-}
-
-function toggleLocalVideoFromHere() {
- toggleLocalStream(function(localStream) {
- return localStream.getVideoTracks()[0];
- }, 'video');
-}
-
-function toggleLocalAudioFromHere() {
- toggleLocalStream(function(localStream) {
- return localStream.getAudioTracks()[0];
- }, 'audio');
-}
-
-function stopLocalFromHere() {
- stopLocalStream();
-}
-
-function createDataChannelFromHere() {
- ensureHasPeerConnection_();
- createDataChannelOnPeerConnection();
-}
-
-function closeDataChannelFromHere() {
- ensureHasPeerConnection_();
- closeDataChannelOnPeerConnection();
-}
-
-function sendDataFromHere() {
- var data = $('data-channel-send').value;
- sendDataOnChannel(data);
-}
-
-function createDtmfSenderFromHere() {
- ensureHasPeerConnection_();
- createDtmfSenderOnPeerConnection();
-}
-
-function insertDtmfFromHere() {
- var tones = $('dtmf-tones').value;
- var duration = $('dtmf-tones-duration').value;
- var gap = $('dtmf-tones-gap').value;
- insertDtmfOnSender(tones, duration, gap);
-}
-
-function forceIsacChanged() {
- var forceIsac = $('force-isac').checked;
- if (forceIsac) {
- forceIsac_();
- } else {
- dontTouchSdp_();
- }
-}
-
-/**
- * Updates the constraints in the getusermedia-constraints text box with a
- * MediaStreamConstraints string. This string is created based on the state
- * of the 'audiosrc' and 'videosrc' checkboxes.
- * If device enumeration is supported and device source id's are not null they
- * will be added to the constraints string.
- */
-function updateGetUserMediaConstraints() {
- var selectedAudioDevice = $('audiosrc');
- var selectedVideoDevice = $('videosrc');
- var constraints = {audio: $('audio').checked,
- video: $('video').checked
- };
-
- if ($('video').checked) {
- // Default optional constraints placed here.
- constraints.video = {optional: [{minWidth: $('video-width').value},
- {minHeight: $('video-height').value},
- {googLeakyBucket: true}]};
- }
-
- if (!selectedAudioDevice.disabled && !selectedAudioDevice.disabled) {
- var devices = getSourcesFromField_(selectedAudioDevice,
- selectedVideoDevice);
-
- if ($('audio').checked) {
- if (devices.audioId != null)
- constraints.audio = {optional: [{sourceId: devices.audioId}]};
- }
-
- if ($('video').checked) {
- if (devices.videoId != null)
- constraints.video.optional.push({sourceId: devices.videoId});
- }
- }
-
- if ($('screencapture').checked) {
- var constraints = {
- audio: $('audio').checked,
- video: {mandatory: {chromeMediaSource: 'screen',
- maxWidth: screen.width,
- maxHeight: screen.height}}
- };
- if ($('audio').checked)
- warning_('Audio for screencapture is not implemented yet, please ' +
- 'try to set audio = false prior requesting screencapture');
- }
-
- $('getusermedia-constraints').value = JSON.stringify(constraints, null, ' ');
-}
-
-function showServerHelp() {
- alert('You need to build and run a peerconnection_server on some ' +
- 'suitable machine. To build it in chrome, just run make/ninja ' +
- 'peerconnection_server. Otherwise, read in https://code.google' +
- '.com/searchframe#xSWYf0NTG_Q/trunk/peerconnection/README&q=REA' +
- 'DME%20package:webrtc%5C.googlecode%5C.com.');
-}
-
-function clearLog() {
- $('messages').innerHTML = '';
- $('debug').innerHTML = '';
-}
-
-/**
- * Stops the local stream.
- */
-function stopLocalStream() {
- if (global.localStream == null)
- error_('Tried to stop local stream, ' +
- 'but media access is not granted.');
-
- global.localStream.stop();
-}
-
-/**
- * Adds the current local media stream to a peer connection.
- * @param {RTCPeerConnection} peerConnection
- */
-function addLocalStreamToPeerConnection(peerConnection) {
- if (global.localStream == null)
- error_('Tried to add local stream to peer connection, but there is no ' +
- 'stream yet.');
- try {
- peerConnection.addStream(global.localStream, global.addStreamConstraints);
- } catch (exception) {
- error_('Failed to add stream with constraints ' +
- global.addStreamConstraints + ': ' + exception);
- }
- print_('Added local stream.');
-}
-
-/**
- * Removes the local stream from the peer connection.
- * @param {rtcpeerconnection} peerConnection
- */
-function removeLocalStreamFromPeerConnection(peerConnection) {
- if (global.localStream == null)
- error_('Tried to remove local stream from peer connection, but there is ' +
- 'no stream yet.');
- try {
- peerConnection.removeStream(global.localStream);
- } catch (exception) {
- error_('Could not remove stream: ' + exception);
- }
- print_('Removed local stream.');
-}
-
-/**
- * Enumerates the audio and video devices available in Chrome and adds the
- * devices to the HTML elements with Id 'audiosrc' and 'videosrc'.
- * Checks if device enumeration is supported and if the 'audiosrc' + 'videosrc'
- * elements exists, if not a debug printout will be displayed.
- * If the device label is empty, audio/video + sequence number will be used to
- * populate the name. Also makes sure the children has been loaded in order
- * to update the constraints.
- */
-function getDevices() {
- selectedAudioDevice = $('audiosrc');
- selectedVideoDevice = $('videosrc');
- selectedAudioDevice.innerHTML = '';
- selectedVideoDevice.innerHTML = '';
-
- try {
- eval(MediaStreamTrack.getSources(function() {}));
- } catch (exception) {
- selectedAudioDevice.disabled = true;
- selectedVideoDevice.disabled = true;
- $('get-devices').disabled = true;
- $('get-devices-onload').disabled = true;
- updateGetUserMediaConstraints();
- error_('Device enumeration not supported. ' + exception);
- }
-
- MediaStreamTrack.getSources(function(devices) {
- for (var i = 0; i < devices.length; i++) {
- var option = document.createElement('option');
- option.value = devices[i].id;
- option.text = devices[i].label;
-
- if (devices[i].kind == 'audio') {
- if (option.text == '') {
- option.text = devices[i].id;
- }
- selectedAudioDevice.appendChild(option);
- } else if (devices[i].kind == 'video') {
- if (option.text == '') {
- option.text = devices[i].id;
- }
- selectedVideoDevice.appendChild(option);
- } else {
- error_('Device type ' + devices[i].kind + ' not recognized, ' +
- 'cannot enumerate device. Currently only device types' +
- '\'audio\' and \'video\' are supported');
- updateGetUserMediaConstraints();
- return;
- }
- }
- });
-
- checkIfDeviceDropdownsArePopulated_();
-}
-
-/**
- * Sets the transform to apply just before setting the local description and
- * sending to the peer.
- * @param {function} transformFunction A function which takes one SDP string as
- * argument and returns the modified SDP string.
- */
-function setOutgoingSdpTransform(transformFunction) {
- global.transformOutgoingSdp = transformFunction;
-}
-
-/**
- * Sets the MediaConstraints to be used for PeerConnection createAnswer() calls.
- * @param {string} mediaConstraints The constraints, as defined in the
- * PeerConnection JS API spec.
- */
-function setCreateAnswerConstraints(mediaConstraints) {
- global.createAnswerConstraints = mediaConstraints;
-}
-
-/**
- * Sets the MediaConstraints to be used for PeerConnection createOffer() calls.
- * @param {string} mediaConstraints The constraints, as defined in the
- * PeerConnection JS API spec.
- */
-function setCreateOfferConstraints(mediaConstraints) {
- global.createOfferConstraints = mediaConstraints;
-}
-
-/**
- * Sets the callback functions that will receive DataChannel readyState updates
- * and received data.
- * @param {function} status_callback The function that will receive a string
- * with
- * the current DataChannel readyState.
- * @param {function} data_callback The function that will a string with data
- * received from the remote peer.
- */
-function setDataCallbacks(status_callback, data_callback) {
- global.dataStatusCallback = status_callback;
- global.dataCallback = data_callback;
-}
-
-/**
- * Sends data on an active DataChannel.
- * @param {string} data The string that will be sent to the remote peer.
- */
-function sendDataOnChannel(data) {
- if (global.dataChannel == null)
- error_('Trying to send data, but there is no DataChannel.');
- global.dataChannel.send(data);
-}
-
-/**
- * Sets the callback function that will receive DTMF sender ontonechange events.
- * @param {function} ontonechange The function that will receive a string with
- * the tone that has just begun playout.
- */
-function setOnToneChange(ontonechange) {
- global.dtmfOnToneChange = ontonechange;
-}
-
-/**
- * Inserts DTMF tones on an active DTMF sender.
- * @param {string} tones to be sent.
- * @param {string} duration duration of the tones to be sent.
- * @param {string} interToneGap gap between the tones to be sent.
- */
-function insertDtmf(tones, duration, interToneGap) {
- if (global.dtmfSender == null)
- error_('Trying to send DTMF, but there is no DTMF sender.');
- global.dtmfSender.insertDTMF(tones, duration, interToneGap);
-}
-
-function handleMessage(peerConnection, message) {
- var parsed_msg = JSON.parse(message);
- if (parsed_msg.type) {
- var session_description = new RTCSessionDescription(parsed_msg);
- peerConnection.setRemoteDescription(
- session_description,
- function() { success_('setRemoteDescription'); },
- function(error) { error_('setRemoteDescription', error); });
- if (session_description.type == 'offer') {
- print_('createAnswer with constraints: ' +
- JSON.stringify(global.createAnswerConstraints, null, ' '));
- peerConnection.createAnswer(
- setLocalAndSendMessage_,
- function(error) { error_('createAnswer', error); },
- global.createAnswerConstraints);
- }
- return;
- } else if (parsed_msg.candidate) {
- var candidate = new RTCIceCandidate(parsed_msg);
- peerConnection.addIceCandidate(candidate,
- function() { success_('addIceCandidate'); },
- function(error) { error_('addIceCandidate', error); }
- );
- return;
- }
- error_('unknown message received');
-}
-
-/**
- * Sets the peerConnection constraints based on checkboxes.
- * TODO (jansson) Make it possible to use the text field for constraints like
- * for getUserMedia.
- */
-function setPeerConnectionConstraints() {
- // Only added optional for now.
- global.pcConstraints = {
- optional: []
- };
-
- global.pcConstraints.optional.push(
- {googCpuOveruseDetection: $('cpuoveruse-detection').checked});
-
- global.pcConstraints.optional.push(
- {RtpDataChannels: $('data-channel-type-rtp').checked});
-
- $('pc-constraints').value = JSON.stringify(global.pcConstraints, null, ' ');
-}
-
-function createPeerConnection(stun_server) {
- servers = {iceServers: [{url: 'stun:' + stun_server}]};
- try {
- peerConnection = new RTCPeerConnection(servers, global.pcConstraints);
- } catch (exception) {
- error_('Failed to create peer connection: ' + exception);
- }
- peerConnection.onaddstream = addStreamCallback_;
- peerConnection.onremovestream = removeStreamCallback_;
- peerConnection.onicecandidate = iceCallback_;
- peerConnection.ondatachannel = onCreateDataChannelCallback_;
- return peerConnection;
-}
-
-function setupCall(peerConnection) {
- print_('createOffer with constraints: ' +
- JSON.stringify(global.createOfferConstraints, null, ' '));
- peerConnection.createOffer(
- setLocalAndSendMessage_,
- function(error) { error_('createOffer', error); },
- global.createOfferConstraints);
-}
-
-function answerCall(peerConnection, message) {
- handleMessage(peerConnection, message);
-}
-
-function createDataChannel(peerConnection, label) {
- if (global.dataChannel != null && global.dataChannel.readyState != 'closed')
- error_('Creating DataChannel, but we already have one.');
-
- global.dataChannel = peerConnection.createDataChannel(label,
- { reliable: false });
- print_('DataChannel with label ' + global.dataChannel.label + ' initiated ' +
- 'locally.');
- hookupDataChannelEvents();
-}
-
-function closeDataChannel(peerConnection) {
- if (global.dataChannel == null)
- error_('Closing DataChannel, but none exists.');
- print_('DataChannel with label ' + global.dataChannel.label +
- ' is beeing closed.');
- global.dataChannel.close();
-}
-
-function createDtmfSender(peerConnection) {
- if (global.dtmfSender != null)
- error_('Creating DTMF sender, but we already have one.');
-
- var localStream = global.localStream;
- if (localStream == null)
- error_('Creating DTMF sender but local stream is null.');
- local_audio_track = localStream.getAudioTracks()[0];
- global.dtmfSender = peerConnection.createDTMFSender(local_audio_track);
- global.dtmfSender.ontonechange = global.dtmfOnToneChange;
-}
-
-/**
- * Connects to the provided peerconnection_server.
- *
- * @param {string} serverUrl The server URL in string form without an ending
- * slash, something like http://localhost:8888.
- * @param {string} clientName The name to use when connecting to the server.
- */
-function connect(serverUrl, clientName) {
- if (global.ourPeerId != null)
- error_('connecting, but is already connected.');
-
- print_('Connecting to ' + serverUrl + ' as ' + clientName);
- global.serverUrl = serverUrl;
- global.ourClientName = clientName;
-
- request = new XMLHttpRequest();
- request.open('GET', serverUrl + '/sign_in?' + clientName, true);
- print_(serverUrl + '/sign_in?' + clientName);
- request.onreadystatechange = function() {
- connectCallback_(request);
- };
- request.send();
-}
-
-/**
- * Checks if the remote peer has connected. Returns peer-connected if that is
- * the case, otherwise no-peer-connected.
- */
-function remotePeerIsConnected() {
- if (global.remotePeerId == null)
- print_('no-peer-connected');
- else
- print_('peer-connected');
-}
-
-/**
- * Creates a peer connection. Must be called before most other public functions
- * in this file.
- */
-function preparePeerConnection() {
- if (global.peerConnection != null)
- error_('creating peer connection, but we already have one.');
-
- global.peerConnection = createPeerConnection(STUN_SERVER);
- success_('ok-peerconnection-created');
-}
-
-/**
- * Adds the local stream to the peer connection. You will have to re-negotiate
- * the call for this to take effect in the call.
- */
-function addLocalStream() {
- if (global.peerConnection == null)
- error_('adding local stream, but we have no peer connection.');
-
- addLocalStreamToPeerConnection(global.peerConnection);
- print_('ok-added');
-}
-
-/**
- * Removes the local stream from the peer connection. You will have to
- * re-negotiate the call for this to take effect in the call.
- */
-function removeLocalStream() {
- if (global.peerConnection == null)
- error_('attempting to remove local stream, but no call is up');
-
- removeLocalStreamFromPeerConnection(global.peerConnection);
- print_('ok-local-stream-removed');
-}
-
-/**
- * (see getReadyState_)
- */
-function getPeerConnectionReadyState() {
- print_(getReadyState_());
-}
-
-/**
- * Toggles the remote audio stream's enabled state on the peer connection, given
- * that a call is active. Returns ok-[typeToToggle]-toggled-to-[true/false]
- * on success.
- *
- * @param {function} selectAudioOrVideoTrack A function that takes a remote
- * stream as argument and returns a track (e.g. either the video or audio
- * track).
- * @param {function} typeToToggle Either "audio" or "video" depending on what
- * the selector function selects.
- */
-function toggleRemoteStream(selectAudioOrVideoTrack, typeToToggle) {
- if (global.peerConnection == null)
- error_('Tried to toggle remote stream, but have no peer connection.');
- if (global.peerConnection.getRemoteStreams().length == 0)
- error_('Tried to toggle remote stream, but not receiving any stream.');
-
- var track = selectAudioOrVideoTrack(
- global.peerConnection.getRemoteStreams()[0]);
- toggle_(track, 'remote', typeToToggle);
-}
-
-/**
- * See documentation on toggleRemoteStream (this function is the same except
- * we are looking at local streams).
- */
-function toggleLocalStream(selectAudioOrVideoTrack, typeToToggle) {
- if (global.peerConnection == null)
- error_('Tried to toggle local stream, but have no peer connection.');
- if (global.peerConnection.getLocalStreams().length == 0)
- error_('Tried to toggle local stream, but there is no local stream in ' +
- 'the call.');
-
- var track = selectAudioOrVideoTrack(
- global.peerConnection.getLocalStreams()[0]);
- toggle_(track, 'local', typeToToggle);
-}
-
-/**
- * Hangs up a started call. Returns ok-call-hung-up on success. This tab will
- * not accept any incoming calls after this call.
- */
-function hangUp() {
- if (global.peerConnection == null)
- error_('hanging up, but has no peer connection');
- if (getReadyState_() != 'active')
- error_('hanging up, but ready state is not active (no call up).');
- sendToPeer(global.remotePeerId, 'BYE');
- closeCall_();
- global.acceptsIncomingCalls = false;
- print_('ok-call-hung-up');
-}
-
-/**
- * Start accepting incoming calls.
- */
-function acceptIncomingCalls() {
- global.acceptsIncomingCalls = true;
-}
-
-/**
- * Creates a DataChannel on the current PeerConnection. Only one DataChannel can
- * be created on each PeerConnection.
- * Returns ok-datachannel-created on success.
- */
-function createDataChannelOnPeerConnection() {
- if (global.peerConnection == null)
- error_('Tried to create data channel, but have no peer connection.');
-
- createDataChannel(global.peerConnection, global.ourClientName);
- print_('ok-datachannel-created');
-}
-
-/**
- * Close the DataChannel on the current PeerConnection.
- * Returns ok-datachannel-close on success.
- */
-function closeDataChannelOnPeerConnection() {
- if (global.peerConnection == null)
- error_('Tried to close data channel, but have no peer connection.');
-
- closeDataChannel(global.peerConnection);
- print_('ok-datachannel-close');
-}
-
-/**
- * Creates a DTMF sender on the current PeerConnection.
- * Returns ok-dtmfsender-created on success.
- */
-function createDtmfSenderOnPeerConnection() {
- if (global.peerConnection == null)
- error_('Tried to create DTMF sender, but have no peer connection.');
-
- createDtmfSender(global.peerConnection);
- print_('ok-dtmfsender-created');
-}
-
-/**
- * Send DTMF tones on the global.dtmfSender.
- * Returns ok-dtmf-sent on success.
- */
-function insertDtmfOnSender(tones, duration, interToneGap) {
- if (global.dtmfSender == null)
- error_('Tried to insert DTMF tones, but have no DTMF sender.');
-
- insertDtmf(tones, duration, interToneGap);
- print_('ok-dtmf-sent');
-}
-
-/**
- * Sends a message to a peer through the peerconnection_server.
- */
-function sendToPeer(peer, message) {
- var messageToLog = message.sdp ? message.sdp : message;
- print_('Sending message ' + messageToLog + ' to peer ' + peer + '.');
-
- var request = new XMLHttpRequest();
- var url = global.serverUrl + '/message?peer_id=' + global.ourPeerId + '&to=' +
- peer;
- request.open('POST', url, false);
- request.setRequestHeader('Content-Type', 'text/plain');
- request.send(message);
-}
-
-/**
- * @param {!string} videoTagId The ID of the video tag to update.
- * @param {!number} width of the video to update the video tag, if width or
- * height is 0, size will be taken from videoTag.videoWidth.
- * @param {!number} height of the video to update the video tag, if width or
- * height is 0 size will be taken from the videoTag.videoHeight.
- */
-function updateVideoTagSize(videoTagId, width, height) {
- var videoTag = $(videoTagId);
- if (width > 0 || height > 0) {
- videoTag.width = width;
- videoTag.height = height;
- }
- else {
- if (videoTag.videoWidth > 0 || videoTag.videoHeight > 0) {
- videoTag.width = videoTag.videoWidth;
- videoTag.height = videoTag.videoHeight;
- print_('Set video tag "' + videoTagId + '" size to ' + videoTag.width +
- 'x' + videoTag.height);
- }
- else {
- print_('"' + videoTagId + '" video stream size is 0, skipping resize');
- }
- }
- displayVideoSize_(videoTag);
-}
-
-// Internals.
-
-/**
- * Disconnects from the peerconnection server. Returns ok-disconnected on
- * success.
- */
-function disconnect_() {
- if (global.ourPeerId == null)
- return;
-
- request = new XMLHttpRequest();
- request.open('GET', global.serverUrl + '/sign_out?peer_id=' +
- global.ourPeerId, false);
- request.send();
- global.ourPeerId = null;
- print_('ok-disconnected');
-}
-
-/**
-* Returns true if we are disconnected from peerconnection_server.
-*/
-function isDisconnected_() {
- return global.ourPeerId == null;
-}
-
-/**
- * @private
- * @return {!string} The current peer connection's ready state, or
- * 'no-peer-connection' if there is no peer connection up.
- *
- * NOTE: The PeerConnection states are changing and until chromium has
- * implemented the new states we have to use this interim solution of
- * always assuming that the PeerConnection is 'active'.
- */
-function getReadyState_() {
- if (global.peerConnection == null)
- return 'no-peer-connection';
-
- return 'active';
-}
-
-/**
- * This function asks permission to use the webcam and mic from the browser. It
- * will return ok-requested to the test. This does not mean the request was
- * approved though. The test will then have to click past the dialog that
- * appears in Chrome, which will run either the OK or failed callback as a
- * a result. To see which callback was called, use obtainGetUserMediaResult_().
- * @private
- * @param {string} constraints Defines what to be requested, with mandatory
- * and optional constraints defined. The contents of this parameter depends
- * on the WebRTC version. This should be JavaScript code that we eval().
- */
-function doGetUserMedia_(constraints) {
- if (!getUserMedia) {
- print_('Browser does not support WebRTC.');
- return;
- }
- try {
- var evaluatedConstraints;
- eval('evaluatedConstraints = ' + constraints);
- } catch (exception) {
- error_('Not valid JavaScript expression: ' + constraints);
- }
- print_('Requesting doGetUserMedia: constraints: ' + constraints);
- getUserMedia(evaluatedConstraints, getUserMediaOkCallback_,
- getUserMediaFailedCallback_);
-}
-
-/**
- * Must be called after calling doGetUserMedia.
- * @private
- * @return {string} Returns not-called-yet if we have not yet been called back
- * by WebRTC. Otherwise it returns either ok-got-stream or
- * failed-with-error-x (where x is the error code from the error
- * callback) depending on which callback got called by WebRTC.
- */
-function obtainGetUserMediaResult_() {
- if (global.requestWebcamAndMicrophoneResult == null)
- global.requestWebcamAndMicrophoneResult = ' not called yet';
-
- return global.requestWebcamAndMicrophoneResult;
-
-}
-
-/**
- * Negotiates a call with the other side. This will create a peer connection on
- * the other side if there isn't one.
- *
- * To call this method we need to be aware of the other side, e.g. we must be
- * connected to peerconnection_server and we must have exactly one peer on that
- * server.
- *
- * This method may be called any number of times. If you haven't added any
- * streams to the call, an "empty" call will result. The method will return
- * ok-negotiating immediately to the test if the negotiation was successfully
- * sent.
- * @private
- */
-function negotiateCall_() {
- if (global.peerConnection == null)
- error_('Negotiating call, but we have no peer connection.');
- if (global.ourPeerId == null)
- error_('Negotiating call, but not connected.');
- if (global.remotePeerId == null)
- error_('Negotiating call, but missing remote peer.');
-
- setupCall(global.peerConnection);
- print_('ok-negotiating');
-}
-
-/**
- * This provides the selected source id from the objects in the parameters
- * provided to this function. If the audioSelect or video_select objects does
- * not have any HTMLOptions children it will return null in the source object.
- * @param {!object} audioSelect HTML drop down element with audio devices added
- * as HTMLOptionsCollection children.
- * @param {!object} videoSelect HTML drop down element with audio devices added
- * as HTMLOptionsCollection children.
- * @return {!object} source contains audio and video source ID from
- * the selected devices in the drop down menu elements.
- * @private
- */
-function getSourcesFromField_(audioSelect, videoSelect) {
- var source = {
- audioId: null,
- videoId: null
- };
- if (audioSelect.options.length > 0) {
- source.audioId = audioSelect.options[audioSelect.selectedIndex].value;
- }
- if (videoSelect.options.length > 0) {
- source.videoId = videoSelect.options[videoSelect.selectedIndex].value;
- }
- return source;
-}
-
-/**
- * @private
- * @param {NavigatorUserMediaError} error Error containing details.
- */
-function getUserMediaFailedCallback_(error) {
- error_('GetUserMedia failed with error: ' + error.name);
-}
-
-/** @private */
-function iceCallback_(event) {
- if (event.candidate)
- sendToPeer(global.remotePeerId, JSON.stringify(event.candidate));
-}
-
-/** @private */
-function setLocalAndSendMessage_(session_description) {
- session_description.sdp =
- global.transformOutgoingSdp(session_description.sdp);
- global.peerConnection.setLocalDescription(
- session_description,
- function() { success_('setLocalDescription'); },
- function(error) { error_('setLocalDescription', error); });
- print_('Sending SDP message:\n' + session_description.sdp);
- sendToPeer(global.remotePeerId, JSON.stringify(session_description));
-}
-
-/** @private */
-function addStreamCallback_(event) {
- print_('Receiving remote stream...');
- var videoTag = document.getElementById('remote-view');
- attachMediaStream(videoTag, event.stream);
-
- window.addEventListener('loadedmetadata', function() {
- displayVideoSize_(videoTag);}, true);
-}
-
-/** @private */
-function removeStreamCallback_(event) {
- print_('Call ended.');
- document.getElementById('remote-view').src = '';
-}
-
-/** @private */
-function onCreateDataChannelCallback_(event) {
- if (global.dataChannel != null && global.dataChannel.readyState != 'closed') {
- error_('Received DataChannel, but we already have one.');
- }
-
- global.dataChannel = event.channel;
- print_('DataChannel with label ' + global.dataChannel.label +
- ' initiated by remote peer.');
- hookupDataChannelEvents();
-}
-
-/** @private */
-function hookupDataChannelEvents() {
- global.dataChannel.onmessage = global.dataCallback;
- global.dataChannel.onopen = onDataChannelReadyStateChange_;
- global.dataChannel.onclose = onDataChannelReadyStateChange_;
- // Trigger global.dataStatusCallback so an application is notified
- // about the created data channel.
- onDataChannelReadyStateChange_();
-}
-
-/** @private */
-function onDataChannelReadyStateChange_() {
- var readyState = global.dataChannel.readyState;
- print_('DataChannel state:' + readyState);
- global.dataStatusCallback(readyState);
- // Display dataChannel.id only when dataChannel is active/open.
- if (global.dataChannel.readyState == 'open') {
- $('data-channel-id').value = global.dataChannel.id;
- } else if (global.dataChannel.readyState == 'closed') {
- $('data-channel-id').value = '';
- }
-}
-
-/**
- * @private
- * @param {MediaStream} stream Media stream.
- */
-function getUserMediaOkCallback_(stream) {
- global.localStream = stream;
- global.requestWebcamAndMicrophoneResult = 'ok-got-stream';
- success_('getUserMedia');
-
- if (stream.getVideoTracks().length > 0) {
- // Show the video tag if we did request video in the getUserMedia call.
- var videoTag = $('local-view');
- attachMediaStream(videoTag, stream);
-
- window.addEventListener('loadedmetadata', function() {
- displayVideoSize_(videoTag);}, true);
-
- // Throw an error when no video is sent from camera but gUM returns OK.
- stream.getVideoTracks()[0].onended = function() {
- error_(global.localStream + ' getUserMedia successful but ' +
- 'MediaStreamTrack.onended event fired, no frames from camera.');
- };
-
- // Print information on track going to mute or back from it.
- stream.getVideoTracks()[0].onmute = function() {
- error_(global.localStream + ' MediaStreamTrack.onmute event has fired, ' +
- 'no frames to the track.');
- };
- stream.getVideoTracks()[0].onunmute = function() {
- warning_(global.localStream + ' MediaStreamTrack.onunmute event has ' +
- 'fired.');
- };
- }
-}
-
-/**
- * @private
- * @param {string} videoTag The ID of the video tag + stream used to
- * write the size to a HTML tag based on id if the div's exists.
- */
-function displayVideoSize_(videoTag) {
- if ($(videoTag.id + '-stream-size') && $(videoTag.id + '-size')) {
- if (videoTag.videoWidth > 0 || videoTag.videoHeight > 0) {
- $(videoTag.id + '-stream-size').innerHTML = '(stream size: ' +
- videoTag.videoWidth + 'x' +
- videoTag.videoHeight + ')';
- $(videoTag.id + '-size').innerHTML = videoTag.width + 'x' +
- videoTag.height;
- }
- } else {
- print_('Skipping updating -stream-size and -size tags due to div\'s ' +
- 'are missing');
- }
-}
-
-/**
- * Checks if the 'audiosrc' and 'videosrc' drop down menu elements has had all
- * of its children appended in order to provide device ID's to the function
- * 'updateGetUserMediaConstraints()', used in turn to populate the getUserMedia
- * constraints text box when the page has loaded.
- * @private
- */
-function checkIfDeviceDropdownsArePopulated_() {
- if (document.addEventListener) {
- $('audiosrc').addEventListener('DOMNodeInserted',
- updateGetUserMediaConstraints, false);
- $('videosrc').addEventListener('DOMNodeInserted',
- updateGetUserMediaConstraints, false);
- } else {
- print_('addEventListener is not supported by your browser, cannot update ' +
- 'device source ID\'s automatically. Select a device from the audio' +
- ' or video source drop down menu to update device source id\'s');
- }
-}
-
-/**
- * Register an input element to use local storage to remember its state between
- * sessions (using local storage). Only input elements are supported.
- * @private
- * @param {!string} element_id to be used as a key for local storage and the id
- * of the element to store the state for.
- */
-function registerLocalStorage_(element_id) {
- var element = $(element_id);
- if (element.tagName != 'INPUT') {
- error_('You can only use registerLocalStorage_ for input elements. ' +
- 'Element \"' + element.tagName + '\" is not an input element. ');
- }
-
- if (localStorage.getItem(element.id) == null) {
- storeLocalStorageField_(element);
- } else {
- getLocalStorageField_(element);
- }
-
- // Registers the appropriate events for input elements.
- if (element.type == 'checkbox') {
- element.onclick = function() { storeLocalStorageField_(this); };
- } else if (element.type == 'text') {
- element.onblur = function() { storeLocalStorageField_(this); };
- } else {
- error_('Unsupportered input type: ' + '\"' + element.type + '\"');
- }
-}
-
-/**
- * Fetches the stored values from local storage and updates checkbox status.
- * @private
- * @param {!Object} element of which id is representing the key parameter for
- * local storage.
- */
-function getLocalStorageField_(element) {
- // Makes sure the checkbox status is matching the local storage value.
- if (element.type == 'checkbox') {
- element.checked = (localStorage.getItem(element.id) == 'true');
- } else if (element.type == 'text') {
- element.value = localStorage.getItem(element.id);
- } else {
- error_('Unsupportered input type: ' + '\"' + element.type + '\"');
- }
-}
-
-/**
- * Stores the string value of the element object using local storage.
- * @private
- * @param {!Object} element of which id is representing the key parameter for
- * local storage.
- */
-function storeLocalStorageField_(element) {
- if (element.type == 'checkbox') {
- localStorage.setItem(element.id, element.checked);
- } else if (element.type == 'text') {
- localStorage.setItem(element.id, element.value);
- }
-}
-
-/**
- * Create the peer connection if none is up (this is just convenience to
- * avoid having a separate button for that).
- * @private
- */
-function ensureHasPeerConnection_() {
- if (getReadyState_() == 'no-peer-connection') {
- preparePeerConnection();
- }
-}
-
-/**
- * @private
- * @param {string} message Text to print.
- */
-function print_(message) {
- print_handler_(message, 'messages', 'black');
-}
-
-/**
- * @private
- * @param {string} message Text to print.
- */
-function success_(message) {
- print_handler_(message, 'messages', 'green');
-}
-
-/**
- * @private
- * @param {string} message Text to print.
- */
-function warning_(message) {
- print_handler_(message, 'debug', 'orange');
-}
-
-/**
- * @private
- * @param {string} message Text to print.
- */
-function error_(message) {
- print_handler_(message, 'debug', 'red');
-}
-
-/**
- * @private
- * @param {string} message Text to print.
- * @param {string} textField Element ID of where to print.
- * @param {string} color Color of the text.
- */
-function print_handler_(message, textField, color) {
- if (color == 'green' )
- message += ' success';
-
- $(textField).innerHTML += '<span style="color:' + color + ';">' + message +
- '</span><br>'
- console.log(message);
-
- if (color == 'red' )
- throw new Error(message);
-}
-
-/**
- * @private
- * @param {string} stringRepresentation JavaScript as a string.
- * @return {Object} The PeerConnection constraints as a JavaScript dictionary.
- */
-function getEvaluatedJavaScript_(stringRepresentation) {
- try {
- var evaluatedJavaScript;
- eval('evaluatedJavaScript = ' + stringRepresentation);
- return evaluatedJavaScript;
- } catch (exception) {
- error_('Not valid JavaScript expression: ' + stringRepresentation);
- }
-}
-
-/**
- * Swaps lines within a SDP message.
- * @private
- * @param {string} sdp The full SDP message.
- * @param {string} line The line to swap with swapWith.
- * @param {string} swapWith The other line.
- * @return {string} The altered SDP message.
- */
-function swapSdpLines_(sdp, line, swapWith) {
- var lines = sdp.split('\r\n');
- var lineStart = lines.indexOf(line);
- var swapLineStart = lines.indexOf(swapWith);
- if (lineStart == -1 || swapLineStart == -1)
- return sdp; // This generally happens on the first message.
-
- var tmp = lines[lineStart];
- lines[lineStart] = lines[swapLineStart];
- lines[swapLineStart] = tmp;
-
- return lines.join('\r\n');
-}
-
-/** @private */
-function forceIsac_() {
- setOutgoingSdpTransform(function(sdp) {
- // Remove all other codecs (not the video codecs though).
- sdp = sdp.replace(/m=audio (\d+) RTP\/SAVPF.*\r\n/g,
- 'm=audio $1 RTP/SAVPF 104\r\n');
- sdp = sdp.replace('a=fmtp:111 minptime=10', 'a=fmtp:104 minptime=10');
- sdp = sdp.replace(/a=rtpmap:(?!104)\d{1,3} (?!VP8|red|ulpfec).*\r\n/g, '');
- return sdp;
- });
-}
-
-/** @private */
-function dontTouchSdp_() {
- setOutgoingSdpTransform(function(sdp) { return sdp; });
-}
-
-/** @private */
-function hookupDataChannelCallbacks_() {
- setDataCallbacks(function(status) {
- $('data-channel-status').value = status;
- },
- function(data_message) {
- print_('Received ' + data_message.data);
- $('data-channel-receive').value =
- data_message.data + '\n' + $('data-channel-receive').value;
- });
-}
-
-/** @private */
-function hookupDtmfSenderCallback_() {
- setOnToneChange(function(tone) {
- print_('Sent DTMF tone: ' + tone.tone);
- $('dtmf-tones-sent').value =
- tone.tone + '\n' + $('dtmf-tones-sent').value;
- });
-}
-
-/** @private */
-function toggle_(track, localOrRemote, audioOrVideo) {
- if (!track)
- error_('Tried to toggle ' + localOrRemote + ' ' + audioOrVideo +
- ' stream, but has no such stream.');
-
- track.enabled = !track.enabled;
- print_('ok-' + audioOrVideo + '-toggled-to-' + track.enabled);
-}
-
-/** @private */
-function connectCallback_(request) {
- print_('Connect callback: ' + request.status + ', ' + request.readyState);
- if (request.status == 0) {
- print_('peerconnection_server doesn\'t seem to be up.');
- error_('failed connecting to peerConnection server');
- }
- if (request.readyState == 4 && request.status == 200) {
- global.ourPeerId = parseOurPeerId_(request.responseText);
- global.remotePeerId = parseRemotePeerIdIfConnected_(request.responseText);
- startHangingGet_(global.serverUrl, global.ourPeerId);
- print_('ok-connected');
- }
-}
-
-/** @private */
-function parseOurPeerId_(responseText) {
- // According to peerconnection_server's protocol.
- var peerList = responseText.split('\n');
- return parseInt(peerList[0].split(',')[1]);
-}
-
-/** @private */
-function parseRemotePeerIdIfConnected_(responseText) {
- var peerList = responseText.split('\n');
- if (peerList.length == 1) {
- // No peers have connected yet - we'll get their id later in a notification.
- return null;
- }
- var remotePeerId = null;
- for (var i = 0; i < peerList.length; i++) {
- if (peerList[i].length == 0)
- continue;
-
- var parsed = peerList[i].split(',');
- var name = parsed[0];
- var id = parsed[1];
-
- if (id != global.ourPeerId) {
- print_('Found remote peer with name ' + name + ', id ' +
- id + ' when connecting.');
-
- // There should be at most one remote peer in this test.
- if (remotePeerId != null)
- error_('Expected just one remote peer in this test: ' +
- 'found several.');
-
- // Found a remote peer.
- remotePeerId = id;
- }
- }
- return remotePeerId;
-}
-
-/** @private */
-function startHangingGet_(server, ourId) {
- if (isDisconnected_())
- return;
-
- hangingGetRequest = new XMLHttpRequest();
- hangingGetRequest.onreadystatechange = function() {
- hangingGetCallback_(hangingGetRequest, server, ourId);
- };
- hangingGetRequest.ontimeout = function() {
- hangingGetTimeoutCallback_(hangingGetRequest, server, ourId);
- };
- callUrl = server + '/wait?peer_id=' + ourId;
- print_('Sending ' + callUrl);
- hangingGetRequest.open('GET', callUrl, true);
- hangingGetRequest.send();
-}
-
-/** @private */
-function hangingGetCallback_(hangingGetRequest, server, ourId) {
- if (hangingGetRequest.readyState != 4 || hangingGetRequest.status == 0) {
- // Code 0 is not possible if the server actually responded. Ignore.
- return;
- }
- if (hangingGetRequest.status != 200) {
- error_('Error ' + hangingGetRequest.status + ' from server: ' +
- hangingGetRequest.statusText);
- }
- var targetId = readResponseHeader_(hangingGetRequest, 'Pragma');
- if (targetId == ourId)
- handleServerNotification_(hangingGetRequest.responseText);
- else
- handlePeerMessage_(targetId, hangingGetRequest.responseText);
-
- hangingGetRequest.abort();
- restartHangingGet_(server, ourId);
-}
-
-/** @private */
-function hangingGetTimeoutCallback_(hangingGetRequest, server, ourId) {
- print_('Hanging GET times out, re-issuing...');
- hangingGetRequest.abort();
- restartHangingGet_(server, ourId);
-}
-
-/** @private */
-function handleServerNotification_(message) {
- var parsed = message.split(',');
- if (parseInt(parsed[2]) == 1) {
- // Peer connected - this must be our remote peer, and it must mean we
- // connected before them (except if we happened to connect to the server
- // at precisely the same moment).
- print_('Found remote peer with name ' + parsed[0] + ', id ' + parsed[1] +
- ' when connecting.');
- global.remotePeerId = parseInt(parsed[1]);
- }
-}
-
-/** @private */
-function closeCall_() {
- if (global.peerConnection == null)
- debug_('Closing call, but no call active.');
- global.peerConnection.close();
- global.peerConnection = null;
-}
-
-/** @private */
-function handlePeerMessage_(peerId, message) {
- print_('Received message from peer ' + peerId + ': ' + message);
- if (peerId != global.remotePeerId) {
- error_('Received notification from unknown peer ' + peerId +
- ' (only know about ' + global.remotePeerId + '.');
- }
- if (message.search('BYE') == 0) {
- print_('Received BYE from peer: closing call');
- closeCall_();
- return;
- }
- if (global.peerConnection == null && global.acceptsIncomingCalls) {
- // The other side is calling us.
- print_('We are being called: answer...');
-
- global.peerConnection = createPeerConnection(STUN_SERVER);
-
- if ($('auto-add-stream-oncall') &&
- obtainGetUserMediaResult_() == 'ok-got-stream') {
- print_('We have a local stream, so hook it up automatically.');
- addLocalStreamToPeerConnection(global.peerConnection);
- }
- answerCall(global.peerConnection, message);
- return;
- }
- handleMessage(global.peerConnection, message);
-}
-
-/** @private */
-function restartHangingGet_(server, ourId) {
- window.setTimeout(function() {
- startHangingGet_(server, ourId);
- }, 0);
-}
-
-/** @private */
-function readResponseHeader_(request, key) {
- var value = request.getResponseHeader(key);
- if (value == null || value.length == 0) {
- error_('Received empty value ' + value +
- ' for response header key ' + key + '.');
- }
- return parseInt(value);
-}
« no previous file with comments | « chrome/test/data/webrtc/manual/peerconnection-multi.html ('k') | chrome/test/data/webrtc/manual/stylesheet.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698