You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.3 KiB
JavaScript
140 lines
4.3 KiB
JavaScript
![]()
10 years ago
|
const merge = require('lodash/object/merge');
|
||
![]()
11 years ago
|
|
||
![]()
10 years ago
|
var streamRef,
|
||
|
loadedDataHandler;
|
||
![]()
10 years ago
|
|
||
![]()
10 years ago
|
/**
|
||
|
* Wraps browser-specific getUserMedia
|
||
|
* @param {Object} constraints
|
||
|
* @param {Object} success Callback
|
||
|
* @param {Object} failure Callback
|
||
|
*/
|
||
|
function getUserMedia(constraints, success, failure) {
|
||
|
if (typeof navigator.getUserMedia !== 'undefined') {
|
||
|
navigator.getUserMedia(constraints, function (stream) {
|
||
|
streamRef = stream;
|
||
|
var videoSrc = (window.URL && window.URL.createObjectURL(stream)) || stream;
|
||
|
success.apply(null, [videoSrc]);
|
||
|
}, failure);
|
||
|
} else {
|
||
|
failure(new TypeError("getUserMedia not available"));
|
||
![]()
11 years ago
|
}
|
||
![]()
10 years ago
|
}
|
||
![]()
11 years ago
|
|
||
![]()
10 years ago
|
function loadedData(video, callback) {
|
||
|
var attempts = 10;
|
||
![]()
10 years ago
|
|
||
![]()
10 years ago
|
function checkVideo() {
|
||
|
if (attempts > 0) {
|
||
|
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
||
|
console.log(video.videoWidth + "px x " + video.videoHeight + "px");
|
||
|
callback();
|
||
![]()
10 years ago
|
} else {
|
||
![]()
10 years ago
|
window.setTimeout(checkVideo, 500);
|
||
![]()
10 years ago
|
}
|
||
![]()
10 years ago
|
} else {
|
||
|
callback('Unable to play video stream. Is webcam working?');
|
||
![]()
10 years ago
|
}
|
||
![]()
10 years ago
|
attempts--;
|
||
![]()
10 years ago
|
}
|
||
![]()
10 years ago
|
checkVideo();
|
||
|
}
|
||
![]()
10 years ago
|
|
||
![]()
10 years ago
|
/**
|
||
|
* Tries to attach the camera-stream to a given video-element
|
||
|
* and calls the callback function when the content is ready
|
||
|
* @param {Object} constraints
|
||
|
* @param {Object} video
|
||
|
* @param {Object} callback
|
||
|
*/
|
||
|
function initCamera(constraints, video, callback) {
|
||
|
getUserMedia(constraints, function(src) {
|
||
|
video.src = src;
|
||
|
if (loadedDataHandler) {
|
||
|
video.removeEventListener("loadeddata", loadedDataHandler, false);
|
||
|
}
|
||
|
loadedDataHandler = loadedData.bind(null, video, callback);
|
||
|
video.addEventListener('loadeddata', loadedDataHandler, false);
|
||
|
video.play();
|
||
|
}, function(e) {
|
||
|
callback(e);
|
||
|
});
|
||
|
}
|
||
![]()
11 years ago
|
|
||
![]()
10 years ago
|
/**
|
||
|
* Normalizes the incoming constraints to satisfy the current browser
|
||
|
* @param config
|
||
|
* @param cb Callback which is called whenever constraints are created
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
function normalizeConstraints(config, cb) {
|
||
|
var constraints = {
|
||
|
audio: false,
|
||
|
video: true
|
||
|
},
|
||
|
videoConstraints = merge({
|
||
|
width: 640,
|
||
|
height: 480,
|
||
|
minAspectRatio: 0,
|
||
|
maxAspectRatio: 100,
|
||
|
facing: "environment"
|
||
|
}, config);
|
||
![]()
11 years ago
|
|
||
![]()
10 years ago
|
if ( typeof MediaStreamTrack !== 'undefined' && typeof MediaStreamTrack.getSources !== 'undefined') {
|
||
|
MediaStreamTrack.getSources(function(sourceInfos) {
|
||
|
var videoSourceId;
|
||
![]()
10 years ago
|
for (var i = 0; i < sourceInfos.length; ++i) {
|
||
![]()
10 years ago
|
var sourceInfo = sourceInfos[i];
|
||
![]()
10 years ago
|
if (sourceInfo.kind === "video" && sourceInfo.facing === videoConstraints.facing) {
|
||
![]()
10 years ago
|
videoSourceId = sourceInfo.id;
|
||
![]()
11 years ago
|
}
|
||
![]()
10 years ago
|
}
|
||
![]()
11 years ago
|
constraints.video = {
|
||
![]()
10 years ago
|
mandatory: {
|
||
|
minWidth: videoConstraints.width,
|
||
|
minHeight: videoConstraints.height,
|
||
|
minAspectRatio: videoConstraints.minAspectRatio,
|
||
|
maxAspectRatio: videoConstraints.maxAspectRatio
|
||
|
},
|
||
|
optional: [{
|
||
|
sourceId: videoSourceId
|
||
|
}]
|
||
![]()
11 years ago
|
};
|
||
|
return cb(constraints);
|
||
|
});
|
||
![]()
10 years ago
|
} else {
|
||
|
constraints.video = {
|
||
|
mediaSource: "camera",
|
||
|
width: { min: videoConstraints.width, max: videoConstraints.width },
|
||
|
height: { min: videoConstraints.height, max: videoConstraints.height },
|
||
|
require: ["width", "height"]
|
||
|
};
|
||
|
return cb(constraints);
|
||
![]()
11 years ago
|
}
|
||
![]()
10 years ago
|
}
|
||
![]()
11 years ago
|
|
||
![]()
10 years ago
|
/**
|
||
|
* Requests the back-facing camera of the user. The callback is called
|
||
|
* whenever the stream is ready to be consumed, or if an error occures.
|
||
|
* @param {Object} video
|
||
|
* @param {Object} callback
|
||
|
*/
|
||
|
function request(video, videoConstraints, callback) {
|
||
|
normalizeConstraints(videoConstraints, function(constraints) {
|
||
|
initCamera(constraints, video, callback);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
export default {
|
||
![]()
10 years ago
|
request: function(video, constraints, callback) {
|
||
![]()
10 years ago
|
request(video, constraints, callback);
|
||
|
},
|
||
![]()
10 years ago
|
release: function() {
|
||
![]()
10 years ago
|
var tracks = streamRef && streamRef.getVideoTracks();
|
||
|
if (tracks.length) {
|
||
|
tracks[0].stop();
|
||
![]()
11 years ago
|
}
|
||
![]()
10 years ago
|
streamRef = null;
|
||
|
}
|
||
|
};
|