mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 03:01:54 +00:00
Fix video preview widget computed min height (#3043)
Co-authored-by: filtered <176114999+webfiltered@users.noreply.github.com>
This commit is contained in:
@@ -2,15 +2,15 @@ import type { LGraphNode } from '@comfyorg/litegraph'
|
|||||||
|
|
||||||
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
|
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
|
||||||
|
|
||||||
const VIDEO_WIDGET_NAME = 'video-preview' as const
|
const VIDEO_WIDGET_NAME = 'video-preview'
|
||||||
const VIDEO_DEFAULT_OPTIONS = {
|
const VIDEO_DEFAULT_OPTIONS = {
|
||||||
playsInline: true,
|
playsInline: true,
|
||||||
controls: true,
|
controls: true,
|
||||||
loop: true
|
loop: true
|
||||||
} as const
|
} as const
|
||||||
const MEDIA_LOAD_TIMEOUT = 8192 as const
|
const MEDIA_LOAD_TIMEOUT = 8192
|
||||||
const MAX_RETRIES = 1 as const
|
const MAX_RETRIES = 1
|
||||||
const VIDEO_PIXEL_OFFSET = 64 as const
|
const DEFAULT_VIDEO_SIZE = 256
|
||||||
|
|
||||||
type MediaElement = HTMLImageElement | HTMLVideoElement
|
type MediaElement = HTMLImageElement | HTMLVideoElement
|
||||||
|
|
||||||
@@ -127,12 +127,26 @@ export const useNodeImage = (node: LGraphNode) => {
|
|||||||
*/
|
*/
|
||||||
export const useNodeVideo = (node: LGraphNode) => {
|
export const useNodeVideo = (node: LGraphNode) => {
|
||||||
node.previewMediaType = 'video'
|
node.previewMediaType = 'video'
|
||||||
|
let minHeight = DEFAULT_VIDEO_SIZE
|
||||||
|
let minWidth = DEFAULT_VIDEO_SIZE
|
||||||
|
|
||||||
|
const setMinDimensions = (video: HTMLVideoElement) => {
|
||||||
|
const intrinsicAspectRatio = video.videoWidth / video.videoHeight
|
||||||
|
if (!intrinsicAspectRatio || isNaN(intrinsicAspectRatio)) return
|
||||||
|
|
||||||
|
// Set min. height s.t. video spans node's x-axis while maintaining aspect ratio
|
||||||
|
minWidth = node.size?.[0] || DEFAULT_VIDEO_SIZE
|
||||||
|
minHeight = Math.max(minWidth / intrinsicAspectRatio, 64)
|
||||||
|
}
|
||||||
|
|
||||||
const loadElement = (url: string): Promise<HTMLVideoElement | null> =>
|
const loadElement = (url: string): Promise<HTMLVideoElement | null> =>
|
||||||
new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
const video = document.createElement('video')
|
const video = document.createElement('video')
|
||||||
Object.assign(video, VIDEO_DEFAULT_OPTIONS)
|
Object.assign(video, VIDEO_DEFAULT_OPTIONS)
|
||||||
video.onloadeddata = () => resolve(video)
|
video.onloadeddata = () => {
|
||||||
|
setMinDimensions(video)
|
||||||
|
resolve(video)
|
||||||
|
}
|
||||||
video.onerror = () => resolve(null)
|
video.onerror = () => resolve(null)
|
||||||
video.src = url
|
video.src = url
|
||||||
})
|
})
|
||||||
@@ -140,10 +154,14 @@ export const useNodeVideo = (node: LGraphNode) => {
|
|||||||
const addVideoDomWidget = (container: HTMLElement) => {
|
const addVideoDomWidget = (container: HTMLElement) => {
|
||||||
const hasWidget = node.widgets?.some((w) => w.name === VIDEO_WIDGET_NAME)
|
const hasWidget = node.widgets?.some((w) => w.name === VIDEO_WIDGET_NAME)
|
||||||
if (!hasWidget) {
|
if (!hasWidget) {
|
||||||
node.addDOMWidget(VIDEO_WIDGET_NAME, 'video', container, {
|
const widget = node.addDOMWidget(VIDEO_WIDGET_NAME, 'video', container, {
|
||||||
hideOnZoom: false,
|
hideOnZoom: false,
|
||||||
serialize: false
|
serialize: false
|
||||||
})
|
})
|
||||||
|
widget.computeLayoutSize = () => ({
|
||||||
|
minHeight,
|
||||||
|
minWidth
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +175,6 @@ export const useNodeVideo = (node: LGraphNode) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
node.videoContainer.replaceChildren(videoElement)
|
node.videoContainer.replaceChildren(videoElement)
|
||||||
node.imageOffset = VIDEO_PIXEL_OFFSET
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return useNodePreview(node, {
|
return useNodePreview(node, {
|
||||||
|
|||||||
Reference in New Issue
Block a user