Last active
June 19, 2018 13:40
-
-
Save neiltron/d5154c9e9d15c80de9b50fdf3dbdeb0a to your computer and use it in GitHub Desktop.
Using a webcam as a THREE VideoTexture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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