'use strict';
import Thing from './thing.js';
const DEFAULT_WIDTH = 150;
const DEFAULT_HEIGHT = (DEFAULT_WIDTH * 3) / 4;
const WEBCAM_INDICATOR = 'WEBCAM';
/**
* @class WebVideo
* @extends Thing
*/
class WebVideo extends Thing {
static WEBCAM = WEBCAM_INDICATOR;
type = 'WebVideo';
/**
* Constructs a WebVideo.
* @constructor
* @param {string} filename
* @example
* const webCam = new WebVideo('WEBCAM');
*/
constructor(filename) {
super();
if (typeof filename !== 'string') {
throw new TypeError(
'You must pass a string to `' +
"new WebVideo(filename)` that has the video's location."
);
}
var vid = document.createElement('video');
this.width = DEFAULT_WIDTH;
this.height = DEFAULT_HEIGHT;
this.isWebCam = filename === WEBCAM_INDICATOR;
this.browserSupportsVideo = !!vid.canPlayType;
if (this.browserSupportsVideo) {
this.video = vid;
if (!this.isWebCam) {
this.video.src = filename;
} else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices
.getUserMedia({ video: true })
.then(stream => {
this.video.srcObject = stream;
this.video.play();
})
.catch(function (error) {
throw new Error('Web camera access was denied: ' + error);
});
} else {
throw new TypeError('Your browser does not support web camera access');
}
this.filename = filename;
this.video.autoplay = true;
this.video.loop = false;
// Treat cross origin URLs as same origin. Allows for videos from different
// origins to be loaded and played, as long as that origin allows us to load
// the given video resource.
this.video.crossOrigin = 'anonymous';
}
}
/**
* Draws the WebVideo in the canvas.
*
* @param {CanvasRenderingContext2D} context - Context to draw on.
*/
draw(context) {
if (!this.browserSupportsVideo) {
return;
}
super.draw(context, () => {
context.drawImage(this.video, 0, 0, this.width, this.height);
});
}
/**
* Checks if the passed point is contained in the WebVideo.
*
* @alias WebVideo#containsPoint
* @param {number} x - The x coordinate of the point being tested.
* @param {number} y - The y coordinate of the point being tested.
* @returns {boolean} Whether the passed point is contained in the WebVideo.
*/
_containsPoint(x, y) {
if (this.browserSupportsVideo) {
x += this.width * this.anchor.horizontal;
y += this.height * this.anchor.vertical;
return (
x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height
);
}
return false;
}
/**
* Gets the width of the WebVideo.
*
* @returns {number} Width of the WebVideo.
*/
getWidth() {
return this.width;
}
/**
* Gets the height of the WebVideo.
*
* @returns {number} Height of the WebVideo.
*/
getHeight() {
return this.height;
}
/**
* Sets the size of the WebVideo.
*
* @param {number} width - The desired width of the resulting WebVideo.
* @param {number} height - The desired height of the resulting WebVideo.
*/
setSize(width, height) {
this.width = width;
this.height = height;
}
/**
* Sets whether the WebVideo should start playing automatically once loaded.
*
* @param {boolean} autoplay - True/false whether the video should start playing automatically.
*/
setAutoplay(autoplay) {
if (this.browserSupportsVideo) {
this.video.autoplay = autoplay;
}
}
/**
* Sets whether the WebVideo should loop and play again once finished.
*
* @param {boolean} loop - True/false whether the video should loop.
*/
setLoop(loop) {
if (this.browserSupportsVideo) {
this.video.loop = loop;
}
}
/**
* Sets whether the WebVideo is muted or not.
*
* @param {boolean} muted - True/false whether the video should be muted.
*/
setMuted(muted) {
if (this.browserSupportsVideo) {
this.video.muted = muted;
}
}
/**
* Starts playing the WebVideo.
*/
play() {
if (this.browserSupportsVideo) {
this.video.play();
}
}
/**
* Pauses the WebVideo.
*/
pause() {
if (this.browserSupportsVideo) {
this.video.pause();
}
}
/**
* Stops the WebVideo.
*/
stop() {
if (this.browserSupportsVideo) {
this.video.pause();
this.video.currentTime = 0;
if (this.isWebCam && this.video.srcObject) {
this.video.srcObject.getTracks().forEach(function (track) {
track.stop();
});
}
}
}
/**
* Returns whether the WebVideo is currently playing.
*
* @returns {boolean} True if the video is playing, false if it is not.
*/
isPlaying() {
if (this.browserSupportsVideo) {
return !(this.video.paused || this.video.ended);
}
return false;
}
/**
* Returns whether the WebVideo is currently muted.
*
* @returns {boolean} True if the video is muted, false if it is not.
*/
isMuted() {
if (this.browserSupportsVideo) {
return this.video.muted;
}
return false;
}
/**
* Defines a function to call once the video has loaded enough and is ready to play.
* @param {Function} fn A function to call when the video is ready to play.
*/
onReadyToPlay(fn) {
if (this.browserSupportsVideo) {
this.video.oncanplay = fn;
}
}
}
export default WebVideo;