Files
Bjornulf_custom_nodes/web/js/concat_videos.js
justumen 038842e80e 0.61
2024-11-27 14:37:10 +01:00

117 lines
4.9 KiB
JavaScript

import { app } from "../../../scripts/app.js";
app.registerExtension({
name: "Bjornulf.ConcatVideos",
async nodeCreated(node) {
if (node.comfyClass === "Bjornulf_ConcatVideos") {
// Initialize properties if not already set
node.properties = node.properties || {};
// Default output filename
const defaultOutputFilename = "concatenated.mp4";
// Ensure `output_filename` is initialized in properties
if (!node.properties.output_filename) {
node.properties.output_filename = defaultOutputFilename;
}
// Store the original serialize/configure methods
const originalSerialize = node.serialize;
const originalConfigure = node.configure;
// Override serialize to save `output_filename` and inputs
node.serialize = function() {
const data = originalSerialize ? originalSerialize.call(this) : {};
data.video_inputs = this.inputs
.filter(input => input.name.startsWith("video_path_"))
.map(input => ({
name: input.name,
type: input.type,
link: input.link || null,
}));
data.properties = { ...this.properties };
return data;
};
// Override configure to restore `output_filename` and inputs
node.configure = function(data) {
if (originalConfigure) {
originalConfigure.call(this, data);
}
if (data.video_inputs) {
data.video_inputs.forEach(inputData => {
if (!this.inputs.find(input => input.name === inputData.name)) {
const newInput = this.addInput(inputData.name, inputData.type);
newInput.link = inputData.link || null;
}
});
}
node.properties = { ...node.properties, ...data.properties };
// Ensure `output_filename` is always consistent
if (!node.properties.output_filename) {
node.properties.output_filename = defaultOutputFilename;
}
return true;
};
const updateInputs = () => {
const initialWidth = node.size[0];
const numVideosWidget = node.widgets.find(w => w.name === "number_of_videos");
if (!numVideosWidget) return;
const numVideos = numVideosWidget.value;
// Store existing connections before modifying inputs
const existingConnections = {};
node.inputs.forEach(input => {
if (input.link !== null) {
existingConnections[input.name] = input.link;
}
});
// Clear and update inputs
node.inputs = node.inputs.filter(input => !input.name.startsWith("video_path_"));
for (let i = 1; i <= numVideos; i++) {
const inputName = `video_path_${i}`;
const newInput = node.addInput(inputName, "STRING");
if (existingConnections[inputName] !== undefined) {
newInput.link = existingConnections[inputName];
}
}
// Synchronize `output_filename` with properties and widget
const outputFilenameWidget = node.widgets.find(w => w.name === "output_filename");
if (outputFilenameWidget) {
outputFilenameWidget.value = node.properties.output_filename;
}
// Adjust size and redraw
node.setSize(node.computeSize());
node.size[0] = Math.max(initialWidth, 200);
app.graph.setDirtyCanvas(true);
};
// Set up widget callbacks
const numVideosWidget = node.widgets.find(w => w.name === "number_of_videos");
if (numVideosWidget) {
numVideosWidget.callback = updateInputs;
}
// Ensure `output_filename` is properly initialized on node creation
let outputFilenameWidget = node.widgets.find(w => w.name === "output_filename");
if (!outputFilenameWidget) {
outputFilenameWidget = node.addWidget("string", "output_filename", node.properties.output_filename, value => {
node.properties.output_filename = value || defaultOutputFilename;
});
} else {
// Synchronize widget value with properties
outputFilenameWidget.value = node.properties.output_filename || defaultOutputFilename;
}
// Initialize inputs on node creation
requestAnimationFrame(updateInputs);
}
}
});