From 268e54321063ac360da19c9f041619bb075acb8e Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Thu, 9 Jul 2026 15:09:50 +0000 Subject: [PATCH] refactor: reuse director file-key segment lookup --- js/ltx_director.js | 87 ++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/js/ltx_director.js b/js/ltx_director.js index 41d7b72..6ad1a06 100644 --- a/js/ltx_director.js +++ b/js/ltx_director.js @@ -1568,12 +1568,10 @@ class TimelineEditor { canvas.width = w; canvas.height = h; const ctx = canvas.getContext('2d'); - for (let i = 0; i < numFrames; i++) { - // Check if the file/segment is still active in the current timeline - const exists = this.timeline.segments.find(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) || - this.timeline.motionSegments.find(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) || - (this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey)); - if (!exists) break; + for (let i = 0; i < numFrames; i++) { + // Check if the file/segment is still active in the current timeline + const exists = this._getSegmentsByFileKey(fileKey).length > 0; + if (!exists) break; const time = (i / numFrames) * duration; bgVid.currentTime = time; @@ -1590,19 +1588,13 @@ class TimelineEditor { img.src = canvas.toDataURL('image/jpeg', 0.5); await new Promise(r => { img.onload = r; }); - thumbs.push({ time, img }); - - // Propagate the partial progress live to all active segments sharing this file - const matchingSegs = [ - ...this.timeline.segments.filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey), - ...(this.timeline.motionSegments || []).filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) - ]; - if (this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey)) { - matchingSegs.push(this.timeline.retakeVideo); - } - for (const ms of matchingSegs) { - ms.thumbnails = thumbs; - } + thumbs.push({ time, img }); + + // Propagate the partial progress live to all active segments sharing this file + const matchingSegs = this._getSegmentsByFileKey(fileKey); + for (const ms of matchingSegs) { + ms.thumbnails = thumbs; + } this.render(); } @@ -1623,20 +1615,14 @@ class TimelineEditor { this._thumbnailPromises.set(fileKey, extractPromise); - try { - const thumbs = await extractPromise; - this._thumbnailCache.set(fileKey, thumbs); - - const matchingSegs = [ - ...this.timeline.segments.filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey), - ...(this.timeline.motionSegments || []).filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) - ]; - if (this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey)) { - matchingSegs.push(this.timeline.retakeVideo); - } - for (const ms of matchingSegs) { - ms.thumbnails = thumbs; - ms._extractingThumbs = false; + try { + const thumbs = await extractPromise; + this._thumbnailCache.set(fileKey, thumbs); + + const matchingSegs = this._getSegmentsByFileKey(fileKey); + for (const ms of matchingSegs) { + ms.thumbnails = thumbs; + ms._extractingThumbs = false; // If fileKey is a blob URL, and the segment now has a server file path, cache under that path too if (fileKey.startsWith("blob:")) { @@ -1645,19 +1631,13 @@ class TimelineEditor { this._thumbnailCache.set(serverKey, thumbs); } } - } - } catch (err) { - console.error("Extraction error:", err); - const matchingSegs = [ - ...this.timeline.segments.filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey), - ...(this.timeline.motionSegments || []).filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) - ]; - if (this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey)) { - matchingSegs.push(this.timeline.retakeVideo); - } - for (const ms of matchingSegs) { - ms._extractingThumbs = false; - } + } + } catch (err) { + console.error("Extraction error:", err); + const matchingSegs = this._getSegmentsByFileKey(fileKey); + for (const ms of matchingSegs) { + ms._extractingThumbs = false; + } } finally { this._thumbnailPromises.delete(fileKey); this.render(); @@ -1960,6 +1940,21 @@ class TimelineEditor { return api.apiURL(`/view?filename=${encodeURIComponent(filename)}&type=input&subfolder=${encodeURIComponent(subfolder)}`); } + _segmentMatchesFileKey(seg, fileKey) { + return !!seg && (seg.imageFile === fileKey || seg.videoFile === fileKey || seg._blobUrl === fileKey); + } + + _getSegmentsByFileKey(fileKey) { + const matches = [ + ...(this.timeline.segments || []).filter(s => this._segmentMatchesFileKey(s, fileKey)), + ...(this.timeline.motionSegments || []).filter(s => this._segmentMatchesFileKey(s, fileKey)), + ]; + if (this._segmentMatchesFileKey(this.timeline.retakeVideo, fileKey)) { + matches.push(this.timeline.retakeVideo); + } + return matches; + } + async _decodeBase64Audio(audioB64) { const binaryString = window.atob(audioB64); const len = binaryString.length;