blob: 20d26028f068779af6b2cbfde8e3d419d439bd91 [file] [log] [blame]
/**
* Copyright (c) 2012 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.
*/
/**
* Keeps track of our local stream (e.g. what our local webcam is streaming).
* @private
*/
var gLocalStream = null;
/**
* The MediaConstraints to use when connecting the local stream with a peer
* connection.
* @private
*/
var gAddStreamConstraints = {};
/**
* String which keeps track of what happened when we requested user media.
* @private
*/
var gRequestWebcamAndMicrophoneResult = 'not-called-yet';
/**
* Used as a shortcut. Moved to the top of the page due to race conditions.
* @param {string} id is a case-sensitive string representing the unique ID of
* the element being sought.
* @return {string} id returns the element object specified as a parameter
*/
$ = function(id) {
return document.getElementById(id);
};
/**
* This function asks permission to use the webcam and mic from the browser.
* Its callbacks will return either request-callback-granted or
* request-callback-denied depending on the outcome. If the caller does not
* successfully resolve the request by granting or denying, the test will hang.
* To verify which callback was called, use obtainGetUserMediaResult().
*
* @param {!object} constraints Defines what to be requested, with mandatory
* and optional constraints defined. The contents of this parameter depends
* on the WebRTC version.
*/
function doGetUserMedia(constraints) {
if (!getUserMedia) {
returnToTest('Browser does not support WebRTC.');
return;
}
debug('Requesting doGetUserMedia: constraints: ' +
JSON.stringify(constraints, null, 0).replace(/[\r\n]/g, ''));
getUserMedia(constraints,
function(stream) {
ensureGotAllExpectedStreams_(stream, constraints);
getUserMediaOkCallback_(stream);
},
getUserMediaFailedCallback_);
}
/**
* Must be called after calling doGetUserMedia.
* @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() {
returnToTest(gRequestWebcamAndMicrophoneResult);
var ret = gRequestWebcamAndMicrophoneResult;
// Reset for the next call.
gRequestWebcamAndMicrophoneResult = 'not-called-yet';
return ret;
}
/**
* Stops all tracks of the last acquired local stream.
*/
function stopLocalStream() {
if (gLocalStream == null)
throw failTest('Tried to stop local stream, ' +
'but media access is not granted.');
gLocalStream.getVideoTracks().forEach(function(track) {
track.stop();
});
gLocalStream.getAudioTracks().forEach(function(track) {
track.stop();
});
gLocalStream = null;
gRequestWebcamAndMicrophoneResult = 'not-called-yet';
returnToTest('ok-stopped');
}
// Functions callable from other JavaScript modules.
/**
* Adds the current local media stream to a peer connection.
* @param {RTCPeerConnection} peerConnection
*/
function addLocalStreamToPeerConnection(peerConnection) {
if (gLocalStream == null)
throw failTest('Tried to add local stream to peer connection, ' +
'but there is no stream yet.');
try {
peerConnection.addStream(gLocalStream, gAddStreamConstraints);
} catch (exception) {
throw failTest('Failed to add stream with constraints ' +
gAddStreamConstraints + ': ' + exception);
}
debug('Added local stream.');
}
/**
* @return {string} Returns the current local stream - |gLocalStream|.
*/
function getLocalStream() {
return gLocalStream;
}
// Internals.
/**
* @private
* @param {!MediaStream} stream Media stream from getUserMedia.
* @param {!object} constraints The getUserMedia constraints object.
*/
function ensureGotAllExpectedStreams_(stream, constraints) {
if (constraints['video'] && stream.getVideoTracks().length == 0) {
gRequestWebcamAndMicrophoneResult = 'failed-to-get-video';
throw ('Requested video, but did not receive a video stream from ' +
'getUserMedia. Perhaps the machine you are running on ' +
'does not have a webcam.');
}
if (constraints['audio'] && stream.getAudioTracks().length == 0) {
gRequestWebcamAndMicrophoneResult = 'failed-to-get-audio';
throw ('Requested audio, but did not receive an audio stream ' +
'from getUserMedia. Perhaps the machine you are running ' +
'on does not have audio devices.');
}
}
/**
* @private
* @param {MediaStream} stream Media stream.
*/
function getUserMediaOkCallback_(stream) {
gLocalStream = stream;
gRequestWebcamAndMicrophoneResult = 'ok-got-stream';
attachMediaStream($('local-view'), stream);
returnToTest('request-callback-granted');
}
/**
* @private
* @param {NavigatorUserMediaError} error Error containing details.
*/
function getUserMediaFailedCallback_(error) {
// Translate from the old error to the new. Remove when rename fully deployed.
var errorName = error.name;
debug('GetUserMedia FAILED: Maybe the camera is in use by another process?');
gRequestWebcamAndMicrophoneResult = 'failed-with-error-' + errorName;
debug(gRequestWebcamAndMicrophoneResult);
returnToTest('request-callback-denied');
}