Implement enhanced media preview functionality in ComfyUI

- Added support for video previews alongside existing image previews.
- Introduced helper functions to detect video URLs and display media accordingly.
- Updated URL widget handling to show the appropriate media type based on the input URL.
- Improved error handling for media loading failures.

This change enhances the user experience by providing a seamless way to preview both images and videos.
This commit is contained in:
KarrixLee
2025-06-08 19:31:47 +08:00
parent 52d876fa67
commit 46010e1dd5
+77 -8
View File
@@ -734,36 +734,105 @@ const ext = {
});
// console.log("load image");
},
{ serialize: false },
{ serialize: false }
);
console.log(node.widgets);
// Helper function to detect if URL is a video
function isVideoUrl(url) {
const videoExtensions = [
".mp4",
".webm",
".ogg",
".mov",
".avi",
".mkv",
".m4v",
];
const urlLower = url.toLowerCase();
return videoExtensions.some((ext) => urlLower.includes(ext));
}
console.log("urlWidget", urlWidget);
// Enhanced media preview functionality
function showMedia(url) {
if (isVideoUrl(url)) {
showVideo(url);
} else {
showImage(url);
}
}
// Add image preview functionality
// Original image preview functionality
function showImage(url) {
const img = new Image();
img.onload = () => {
node.imgs = [img];
node.videos = []; // Clear any videos
app.graph.setDirtyCanvas(true);
node.setSizeForImage?.();
};
img.onerror = () => {
node.imgs = [];
node.videos = [];
app.graph.setDirtyCanvas(true);
};
img.src = url;
}
// New video preview functionality
function showVideo(url) {
const video = document.createElement("video");
video.src = url;
video.controls = true;
video.muted = true; // Muted by default for autoplay policies
video.style.maxWidth = "100%";
video.style.maxHeight = "200px"; // Limit height in node preview
video.onloadedmetadata = () => {
// Create a canvas to capture video frame for thumbnail
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// Seek to 1 second or 10% of duration for thumbnail
const seekTime = Math.min(1, video.duration * 0.1);
video.currentTime = seekTime;
};
video.onseeked = () => {
// Capture frame as thumbnail
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0);
// Convert to image for ComfyUI display
const img = new Image();
img.onload = () => {
node.imgs = [img];
node.videos = [video]; // Store video element for potential playback
app.graph.setDirtyCanvas(true);
node.setSizeForImage?.();
};
img.src = canvas.toDataURL();
};
video.onerror = () => {
node.imgs = [];
node.videos = [];
app.graph.setDirtyCanvas(true);
};
}
// Set up URL widget value handling
let default_value = urlWidget.value;
Object.defineProperty(urlWidget, "value", {
set: function (value) {
this._real_value = value;
// Preview image when URL changes
// Preview media when URL changes
if (value) {
showImage(value);
showMedia(value);
}
},
get: function () {
@@ -771,10 +840,10 @@ const ext = {
},
});
// Show initial image if URL exists
// Show initial media if URL exists
requestAnimationFrame(() => {
if (urlWidget.value) {
showImage(urlWidget.value);
showMedia(urlWidget.value);
}
});