Files
Bjornulf_custom_nodes/web/js/video_preview.js
justumen 39dfb0220a 0.77
2025-03-19 17:36:25 +01:00

104 lines
4.1 KiB
JavaScript

import { api } from '../../../scripts/api.js';
import { app } from "../../../scripts/app.js";
// Function to display the video preview
function displayVideoPreview(component, filename, category, autoplay, mute, loop) {
let videoWidget = component._videoWidget;
// Create the video widget if it doesn't exist
if (!videoWidget) {
const container = document.createElement("div");
const currentNode = component;
// Add the DOM widget to the component
videoWidget = component.addDOMWidget("videopreview", "preview", container, {
serialize: false,
hideOnZoom: false,
getValue() {
return container.value;
},
setValue(v) {
container.value = v;
},
});
// Define how the widget computes its size
videoWidget.computeSize = function(width) {
if (this.aspectRatio && !this.parentElement.hidden) {
let height = (currentNode.size[0] - 20) / this.aspectRatio + 10;
return [width, height > 0 ? height : 0];
}
return [width, -4];
};
// Initialize widget properties
videoWidget.value = { hidden: false, paused: false, params: {} };
videoWidget.parentElement = document.createElement("div");
videoWidget.parentElement.className = "video_preview";
videoWidget.parentElement.style.width = "100%";
container.appendChild(videoWidget.parentElement);
// Create the video element
videoWidget.videoElement = document.createElement("video");
videoWidget.videoElement.controls = true;
videoWidget.videoElement.style.width = "100%";
// Update aspect ratio when metadata is loaded
videoWidget.videoElement.addEventListener("loadedmetadata", () => {
videoWidget.aspectRatio = videoWidget.videoElement.videoWidth / videoWidget.videoElement.videoHeight;
adjustSize(component);
});
// Hide the video on error
videoWidget.videoElement.addEventListener("error", () => {
videoWidget.parentElement.hidden = true;
adjustSize(component);
});
videoWidget.parentElement.hidden = videoWidget.value.hidden;
videoWidget.parentElement.appendChild(videoWidget.videoElement);
component._videoWidget = videoWidget; // Store for reuse
}
// Set video source and properties
const params = {
"filename": filename,
"subfolder": category,
"type": "output",
"rand": Math.random().toString().slice(2, 12) // Cache-busting random parameter
};
const urlParams = new URLSearchParams(params);
videoWidget.videoElement.src = `api/view?${urlParams.toString()}`;
videoWidget.videoElement.muted = mute;
videoWidget.videoElement.autoplay = autoplay && !videoWidget.value.paused && !videoWidget.value.hidden;
videoWidget.videoElement.loop = loop;
// Adjust the component size after setting the video
adjustSize(component);
}
// Function to adjust the component size
function adjustSize(component) {
const newSize = component.computeSize([component.size[0], component.size[1]]);
component.setSize([component.size[0], newSize[1]]);
component?.graph?.setDirtyCanvas(true);
}
// Register the extension
app.registerExtension({
name: "Bjornulf.VideoPreview",
async beforeRegisterNodeDef(nodeType, nodeData, appInstance) {
if (nodeData?.name === "Bjornulf_VideoPreview") {
nodeType.prototype.onExecuted = function(data) {
// Retrieve widget values with defaults
const autoplay = this.widgets.find(w => w.name === "autoplay")?.value ?? false;
const mute = this.widgets.find(w => w.name === "mute")?.value ?? true;
const loop = this.widgets.find(w => w.name === "loop")?.value ?? false;
// Display the video preview with the retrieved values
displayVideoPreview(this, data.video[0], data.video[1], autoplay, mute, loop);
};
}
}
});