Files
uetuluk-comfyui-webcam-node/js/node.js
T
2024-03-01 13:58:58 +08:00

189 lines
6.2 KiB
JavaScript

import { app } from "../../../scripts/app.js";
import { api } from "../../../scripts/api.js";
import { $el } from "../../../scripts/ui.js";
function get_position_style(ctx, widget_width, y, node_height) {
const MARGIN = 4; // the margin around the html element
/* Create a transform that deals with all the scrolling and zooming */
const elRect = ctx.canvas.getBoundingClientRect();
const transform = new DOMMatrix()
.scaleSelf(
elRect.width / ctx.canvas.width,
elRect.height / ctx.canvas.height
)
.multiplySelf(ctx.getTransform())
.translateSelf(MARGIN, MARGIN + y);
return {
transformOrigin: "0 0",
transform: transform,
left: `0px`,
top: `0px`,
position: "absolute",
maxWidth: `${widget_width - MARGIN * 2}px`,
maxHeight: `${node_height - MARGIN * 2}px`, // we're assuming we have the whole height of the node
width: `auto`,
height: `auto`,
};
}
app.registerExtension({
name: "webcam.capture.extension",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeType.comfyClass == "webcam_capture_node") {
console.log("Starting webcam capture extension");
const orig_nodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
console.log("webcam node created");
const widget = {
// type: inputdata[0], // whatever
name: "webcam", // whatever
draw(ctx, node, widget_width, y) {
Object.assign(
this.inputEl.style,
get_position_style(ctx, widget_width, y, node.size[1])
); // assign the required style when we are drawn
},
};
const widget3 = {
// type: inputdata[0], // whatever
name: "webcam_stop", // whatever
draw(ctx, node, widget_width, y) {
Object.assign(
this.inputEl.style,
get_position_style(ctx, widget_width, y, node.size[1])
); // assign the required style when we are drawn
},
};
const widget2 = {
// type: inputdata[0], // whatever
name: "webcam_image", // whatever
draw(ctx, node, widget_width, y) {
Object.assign(
this.inputEl.style,
get_position_style(ctx, widget_width, y + 50, node.size[1])
); // assign the required style when we are drawn
},
};
// ui.js
widget.inputEl = document.createElement("button");
widget.inputEl = document.createElement("button");
widget.inputEl.textContent = "Start Capture";
widget.inputEl.className = "start-capture";
widget3.inputEl = document.createElement("button");
widget3.inputEl.textContent = "Stop Capture";
widget3.inputEl.className = "stop-capture";
widget2.inputEl = document.createElement("img");
// widget.inputEl.className = "test";
// widget.inputEl.textContent = "Capture Image";
let captureInterval;
widget.inputEl.onclick = async () => {
if (captureInterval) {
console.log("Capture already started.");
return;
}
// $el("button", {
// textContent: "Capture Image",
// onclick: async () => {
try {
captureInterval = setInterval(async () => {
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 512, height: 512 },
audio: false,
});
console.log(stream);
const video = document.createElement("video");
video.srcObject = stream;
video.play();
// Wait for the video to start playing
await new Promise((resolve) => (video.onplaying = resolve));
// add delay to allow camera to adjust to light
await new Promise((resolve) => setTimeout(resolve, 300));
// Stop the video stream
stream.getTracks().forEach((track) => track.stop());
// Capture the image
const canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const ctx = canvas.getContext("2d");
ctx.drawImage(video, 0, 0);
// Set the image to the widget
widget2.inputEl.src = canvas.toDataURL("image/png");
// Convert canvas to image blob and send to backend
canvas.toBlob((blob) => {
// const formData = new FormData();
// formData.append("image_data", blob);
console.log(blob);
api
.fetchApi("/webcam_capture", {
method: "POST",
body: blob,
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) =>
console.error("Error uploading image:", error)
);
});
}, 1000);
} catch (error) {
console.error("Error capturing image:", error);
}
};
// });
widget3.inputEl.onclick = () => {
if (captureInterval) {
clearInterval(captureInterval);
captureInterval = null;
console.log("Capture stopped.");
}
};
document.body.appendChild(widget.inputEl);
document.body.appendChild(widget2.inputEl);
document.body.appendChild(widget3.inputEl);
// console.log(widget);
this.addCustomWidget(widget);
this.addCustomWidget(widget2);
this.addCustomWidget(widget3);
this.onRemoved = function () {
widget.inputEl.remove();
widget2.inputEl.remove();
widget3.inputEl.remove();
};
this.serialize_widgets = false;
orig_nodeCreated?.apply(this, arguments);
console.log(this);
// if (node.box) {
// node.box.appendChild(captureButton);
// }
// // Add the capture button to the node's UI
// node.titlebar.appendChild(captureButton);
};
}
},
});