Skip to content

Instantly share code, notes, and snippets.

@neiltron
Last active June 19, 2018 13:40
Show Gist options
  • Save neiltron/d5154c9e9d15c80de9b50fdf3dbdeb0a to your computer and use it in GitHub Desktop.
Save neiltron/d5154c9e9d15c80de9b50fdf3dbdeb0a to your computer and use it in GitHub Desktop.
Using a webcam as a THREE VideoTexture
// npm install this for convenience
var getUserMedia = require('getusermedia');
// usage:
// Webcam.initCamera({
// fallbackVideo: '/assets/video_mobile.mp4', // optional
// videoElement: someDOMElement, // (optional, defaults to document.querySelector('video')),
// facingMode: "environment", // defaults to "environment", which is rear cam
// });
//
// const myMaterial = new THREE.MeshBasicMaterial({
// map: Webcam.videoTexture
// });
class Webcam {
initCamera (opts = {}) {
this.fallbackVideo = opts.fallbackVideo;
this.facingMode = opts.facingMode || "user"; // choose front/rear camera on mobile
this.video = opts.videoElement || document.querySelector('video');
this.video.pause();
this.video.style.width = window.innerWidth;
this.video.style.height = window.innerHeight;
this.video.autoplay = true;
this.video.muted = true;
this.video.playsinline = true;
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
this.videoTexture = new THREE.VideoTexture(this.video);
this.videoTexture.minFilter = THREE.LinearFilter;
this.startVideo();
}
startVideo () {
getUserMedia({
video: {
facingMode: this.facingMode
},
audio: false
}, (err, stream) => {
if (err) { //user rejected webcam access or webcam isn't available
if (this.fallbackVideo) {
this.video.src = this.fallbackVideo;
}
} else {
try {
this.video.srcObject = stream;
} catch (error) {
this.video.src = URL.createObjectURL(stream);
}
}
this.video.play();
setTimeout(() => {
this.canvas.width = this.video.videoWidth;
this.canvas.height = this.video.videoHeight;
}, 100);
});
}
// used to get a single frame from video
// accepts a callback function which will have an image passed to it
// e.g., Webcam.getFrame((img) => {
// MyTexture.image = img;
// MyTexture.needsUpdate = true;
// });
getFrame (cb) {
this.ctx.drawImage(this.video, 0, 0);
let img = document.createElement('img');
let url;
img.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
this.canvas.toBlob(blob => {
url = URL.createObjectURL(blob);
img.src = url;
if (typeof cb === 'function') {
cb.call(this, img);
}
})
}
};
export default new Webcam();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment