@webarkit/ar-nft
Version:
WebAR Javscript library for markerless AR
158 lines • 5.64 kB
JavaScript
export class CameraViewRenderer {
canvas_process;
context_process;
_video;
_facing;
vw;
vh;
w;
h;
pw;
ph;
ox;
oy;
target;
targetFrameRate = 60;
imageDataCache;
_frame;
lastCache = 0;
constructor(video) {
this.canvas_process = document.createElement("canvas");
this.context_process = this.canvas_process.getContext("2d", { alpha: false, willReadFrequently: true });
this._video = video;
this.target = window || global;
this._frame = 0;
}
get facing() {
return this._facing;
}
get height() {
return this.vh;
}
get width() {
return this.vw;
}
get video() {
return this._video;
}
get frame() {
return this._frame;
}
get canvasProcess() {
return this.canvas_process;
}
get contextProcess() {
return this.context_process;
}
getFrame() {
return this._frame;
}
getImage() {
const now = Date.now();
if (now - this.lastCache > 1000 / this.targetFrameRate) {
this.context_process.drawImage(this.video, 0, 0, this.vw, this.vh, this.ox, this.oy, this.w, this.h);
const imageData = this.context_process.getImageData(0, 0, this.pw, this.ph);
if (this.imageDataCache == null) {
this.imageDataCache = imageData.data;
}
else {
this.imageDataCache.set(imageData.data);
}
this.lastCache = now;
this._frame++;
}
return new ImageData(this.imageDataCache.slice(), this.pw, this.ph);
}
get image() {
const now = Date.now();
if (now - this.lastCache > 1000 / this.targetFrameRate) {
this.context_process.drawImage(this.video, 0, 0, this.vw, this.vh, this.ox, this.oy, this.w, this.h);
const imageData = this.context_process.getImageData(0, 0, this.pw, this.ph);
if (this.imageDataCache == null) {
this.imageDataCache = imageData.data;
}
else {
this.imageDataCache.set(imageData.data);
}
this.lastCache = now;
this._frame++;
}
return new ImageData(this.imageDataCache.slice(), this.pw, this.ph);
}
prepareImage() {
this.vw = this._video.videoWidth;
this.vh = this._video.videoHeight;
const pscale = 320 / Math.max(this.vw, (this.vh / 3) * 4);
this.w = Math.floor(this.vw * pscale);
this.h = Math.floor(this.vh * pscale);
this.pw = Math.floor(Math.max(this.w, (this.h / 3) * 4));
this.ph = Math.floor(Math.max(this.h, (this.w / 4) * 3));
this.ox = Math.floor((this.pw - this.w) / 2);
this.oy = Math.floor((this.ph - this.h) / 2);
this.canvas_process.width = this.pw;
this.canvas_process.height = this.ph;
this.context_process.fillStyle = "black";
this.context_process.fillRect(0, 0, this.pw, this.ph);
}
async initialize(videoSettings) {
this._facing = videoSettings.facingMode || "environment";
if (videoSettings.targetFrameRate != null) {
this.targetFrameRate = videoSettings.targetFrameRate;
}
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
try {
const hint = {
audio: false,
video: {
facingMode: this._facing,
width: { min: videoSettings.width.min, max: videoSettings.width.max },
},
};
if (navigator.mediaDevices.enumerateDevices) {
const devices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = [];
let videoDeviceIndex = 0;
devices.forEach(function (device) {
if (device.kind == "videoinput") {
videoDevices[videoDeviceIndex++] = device.deviceId;
}
});
if (videoDevices.length > 1) {
hint.video.deviceId = { exact: videoDevices[videoDevices.length - 1] };
}
}
this._video.srcObject = await navigator.mediaDevices.getUserMedia(hint);
this._video = await new Promise((resolve) => {
this._video.onloadedmetadata = () => resolve(this._video);
});
this.prepareImage();
return true;
}
catch (error) {
return Promise.reject(error);
}
}
else {
return Promise.reject("Sorry, Your device does not support this experience.");
}
}
destroy() {
const video = this._video;
this.target.addEventListener("stopVideoStreaming", function () {
const stream = video.srcObject;
console.log("stop streaming");
if (stream !== null && stream !== undefined) {
const tracks = stream.getTracks();
tracks.forEach(function (track) {
track.stop();
});
video.srcObject = null;
let currentAR = document.getElementById("app");
if (currentAR !== null && currentAR !== undefined) {
currentAR.remove();
}
}
});
}
}
//# sourceMappingURL=CameraViewRenderer.js.map