Files
ryanontheinside-ComfyUI_Rea…/web/js/webcam.js

106 lines
4.9 KiB
JavaScript

import { app } from "../../../scripts/app.js";
//TODO: fix occlusion of dimension editing popups
app.registerExtension({
name: "Core.FastWebcam",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name === "FastWebcamCapture") {
console.log("Registering FastWebcamCapture node type");
// Store webcam stream at extension level to avoid reinitializing
let webcamStream = null;
let webcamVideo = null;
// Initialize webcam once for all nodes
const initWebcam = async () => {
// console.log("Initializing global webcam stream...");
if (!webcamStream) {
try {
webcamStream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: false
});
// console.log("Got media stream:", webcamStream);
webcamVideo = document.createElement("video");
webcamVideo.srcObject = webcamStream;
webcamVideo.style.display = 'none';
document.body.appendChild(webcamVideo);
await webcamVideo.play();
console.log("Video playing. Video state:", {
paused: webcamVideo.paused,
readyState: webcamVideo.readyState,
videoWidth: webcamVideo.videoWidth,
videoHeight: webcamVideo.videoHeight
});
} catch (error) {
// console.error("Webcam initialization error:", error);
throw error;
}
}
return { stream: webcamStream, video: webcamVideo };
};
nodeType.prototype.getCustomWidgets = function() {
// console.log("Getting custom widgets");
return {
WEBCAM: (node, inputName) => {
// console.log("Creating WEBCAM widget");
const container = document.createElement("div");
container.style.background = "rgba(0,0,0,0.25)";
container.style.textAlign = "center";
const statusLabel = document.createElement("div");
statusLabel.textContent = "Webcam Ready";
container.appendChild(statusLabel);
const widget = node.addDOMWidget(inputName, "WEBCAM", container);
return { widget };
}
};
};
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function() {
// console.log("Node created");
const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
const camera = this.widgets.find((w) => w.name === "image");
const w = this.widgets.find((w) => w.name === "width");
const h = this.widgets.find((w) => w.name === "height");
const canvas = document.createElement("canvas");
camera.serializeValue = async () => {
// console.log("Serializing camera value");
// Only initialize webcam when actually needed
if (!webcamVideo || webcamVideo.paused || webcamVideo.readyState !== 4) {
// console.log("Initializing webcam for first use...");
const { video } = await initWebcam();
webcamVideo = video;
}
console.log("Capturing frame from video:", {
paused: webcamVideo.paused,
readyState: webcamVideo.readyState,
videoWidth: webcamVideo.videoWidth,
videoHeight: webcamVideo.videoHeight
});
canvas.width = w.value || webcamVideo.videoWidth || 640;
canvas.height = h.value || webcamVideo.videoHeight || 480;
const ctx = canvas.getContext("2d");
ctx.drawImage(webcamVideo, 0, 0, canvas.width, canvas.height);
const dataUrl = canvas.toDataURL("image/png");
// console.log("Successfully captured and converted frame to data URL");
return dataUrl;
};
return r;
};
}
}
});