|
|
|
@ -56,6 +56,7 @@ const VIDEO_BASIC_PARAMETER_NAMES = [ |
|
|
|
...VIDEO_DURATION_PARAMETER_NAMES, |
|
|
|
...VIDEO_RESOLUTION_PARAMETER_NAMES, |
|
|
|
]; |
|
|
|
const VIDEO_LOAD_RETRY_DELAYS_MS = [600, 1600]; |
|
|
|
|
|
|
|
function isSameSelectedModel(a: SelectedModel | undefined, b: SelectedModel | undefined): boolean { |
|
|
|
return Boolean(a?.provider && b?.provider && a.provider === b.provider && a.modelId === b.modelId); |
|
|
|
@ -159,6 +160,7 @@ export function GenerateVideoNodeView({ id, data, selected }: GenerateVideoNodeV |
|
|
|
const [isBrowseDialogOpen, setIsBrowseDialogOpen] = useState(false); |
|
|
|
const [isLoadingCarouselVideo, setIsLoadingCarouselVideo] = useState(false); |
|
|
|
const [isPreviewOpen, setIsPreviewOpen] = useState(false); |
|
|
|
const [videoRetryNonce, setVideoRetryNonce] = useState(0); |
|
|
|
const [settingsTab, setSettingsTab] = useState<"primary" | "fallback">("primary"); |
|
|
|
const showFallbackSettings = !popiProviderMode && !!nodeData.fallbackModel; |
|
|
|
|
|
|
|
@ -171,6 +173,10 @@ export function GenerateVideoNodeView({ id, data, selected }: GenerateVideoNodeV |
|
|
|
const videoBlobUrl = useVideoBlobUrl(nodeData.outputVideo ?? null); |
|
|
|
const videoAutoplayRef = useVideoAutoplay(id, selected); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
setVideoRetryNonce(0); |
|
|
|
}, [videoBlobUrl]); |
|
|
|
|
|
|
|
// Inline parameters infrastructure
|
|
|
|
const { inlineParametersEnabled } = useInlineParameters(); |
|
|
|
// Video generation settings now live in the selected-node composer. Rendering
|
|
|
|
@ -938,13 +944,23 @@ export function GenerateVideoNodeView({ id, data, selected }: GenerateVideoNodeV |
|
|
|
<> |
|
|
|
<video |
|
|
|
ref={videoAutoplayRef} |
|
|
|
key={nodeData.videoHistory?.[nodeData.selectedVideoHistoryIndex || 0]?.id} |
|
|
|
key={`${nodeData.videoHistory?.[nodeData.selectedVideoHistoryIndex || 0]?.id ?? nodeData.outputVideo}-${videoRetryNonce}`} |
|
|
|
src={videoBlobUrl ?? undefined} |
|
|
|
controls |
|
|
|
loop |
|
|
|
muted |
|
|
|
className="w-full h-full object-contain" |
|
|
|
playsInline |
|
|
|
onLoadedMetadata={() => setVideoRetryNonce(0)} |
|
|
|
onError={() => { |
|
|
|
const retryIndex = videoRetryNonce; |
|
|
|
const retryDelay = VIDEO_LOAD_RETRY_DELAYS_MS[retryIndex]; |
|
|
|
if (retryDelay !== undefined && videoBlobUrl) { |
|
|
|
window.setTimeout(() => { |
|
|
|
setVideoRetryNonce((current) => current === retryIndex ? current + 1 : current); |
|
|
|
}, retryDelay); |
|
|
|
} |
|
|
|
}} |
|
|
|
onDoubleClick={(e) => { |
|
|
|
e.preventDefault(); |
|
|
|
e.stopPropagation(); |
|
|
|
|