refactor: reuse director serialization helpers

This commit is contained in:
OpenClaw Agent
2026-07-09 15:23:17 +00:00
parent 7e569d5deb
commit 7099b3c6f1

View File

@@ -12,6 +12,49 @@ const MIN_SEGMENT_LENGTH = 6;
const MAX_THUMBNAIL_DIM = 512; // Increased to maintain quality for taller images
const HIDDEN_WIDGET_NAMES = ["timeline_data", "local_prompts", "segment_lengths", "guide_strength", "audio_data", "use_custom_audio", "inpaint_audio", "use_custom_motion", "override_audio"];
const DEFAULT_WIDGET_VALUES = {
inpaint_audio: true,
override_audio: false,
use_custom_audio: false,
use_custom_motion: true,
frame_rate: 24,
display_mode: "seconds",
custom_width: 0,
custom_height: 0,
resize_method: "maintain aspect ratio",
divisible_by: 32,
img_compression: 18,
guide_strength: "",
local_prompts: "",
segment_lengths: "",
timeline_data: "{}",
epsilon: 0.001,
start_second: 0.0,
end_second: 5.0,
duration_seconds: 5.0,
start_frame: 0,
end_frame: 120,
duration_frames: 120,
};
function stripImageSegmentTransient(s) {
const { imgObj, videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
}
function stripMotionSegmentTransient(s) {
const { videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
}
function stripAudioSegmentTransient(s) {
const { _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _decoding, _blobUrl, _audioBuffer, ...rest } = s;
return rest;
}
function dedupeById(items = []) {
return items.filter((seg, index, self) => index === self.findIndex((s) => s.id === seg.id));
}
function hideWidget(w) {
if (!w) return;
@@ -751,22 +794,13 @@ function parseInitial(jsonStr) {
}
}
if (Array.isArray(p.segments)) {
parsed.segments = p.segments.map(s => {
const { imgObj, videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
});
parsed.segments = p.segments.map(stripImageSegmentTransient);
}
if (Array.isArray(p.motionSegments)) {
parsed.motionSegments = p.motionSegments.map(s => {
const { videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
});
parsed.motionSegments = p.motionSegments.map(stripMotionSegmentTransient);
}
if (Array.isArray(p.audioSegments)) {
parsed.audioSegments = p.audioSegments.map(s => {
const { _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _decoding, ...rest } = s;
return rest;
});
parsed.audioSegments = p.audioSegments.map(stripAudioSegmentTransient);
}
}
} catch (e) { }
@@ -9348,12 +9382,12 @@ class TimelineEditor {
commitChanges(skipRender = false) {
if (this._suppressCommit) return;
// Deduplicate segments by ID to clean up any duplicates created by the previous onseeked bug
this.timeline.segments = this.timeline.segments.filter((seg, index, self) => index === self.findIndex((s) => s.id === seg.id));
this.timeline.segments = dedupeById(this.timeline.segments);
if (this.timeline.audioSegments) {
this.timeline.audioSegments = this.timeline.audioSegments.filter((seg, index, self) => index === self.findIndex((s) => s.id === seg.id));
this.timeline.audioSegments = dedupeById(this.timeline.audioSegments);
}
if (this.timeline.motionSegments) {
this.timeline.motionSegments = this.timeline.motionSegments.filter((seg, index, self) => index === self.findIndex((s) => s.id === seg.id));
this.timeline.motionSegments = dedupeById(this.timeline.motionSegments);
}
let sortedSegments = [...this.timeline.segments].sort((a, b) => a.start - b.start);
@@ -9477,18 +9511,9 @@ class TimelineEditor {
images: (c.images || []).map(img => img.b64 ? { b64: img.b64, name: img.name } : { name: img.name }),
description: c.description || ""
})),
segments: sortedSegments.map(s => {
const { imgObj, videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
}),
motionSegments: (this.timeline.motionSegments || []).map(s => {
const { imgObj, videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
}),
audioSegments: (this.timeline.audioSegments || []).map(s => {
const { _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _decoding, _blobUrl, _audioBuffer, ...rest } = s;
return rest;
})
segments: sortedSegments.map(stripImageSegmentTransient),
motionSegments: (this.timeline.motionSegments || []).map(stripMotionSegmentTransient),
audioSegments: (this.timeline.audioSegments || []).map(stripAudioSegmentTransient)
};
const jsonStr = JSON.stringify(toSave);
@@ -10889,18 +10914,9 @@ class TimelineEditor {
} : null,
normalStartFrame: this.timeline.normalStartFrame,
normalDurationFrames: this.timeline.normalDurationFrames,
segments: (this.timeline.segments || []).map(s => {
const { imgObj, videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
}),
motionSegments: (this.timeline.motionSegments || []).map(s => {
const { imgObj, videoEl, _isSeeking, thumbnails, _extractingThumbs, _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _blobUrl, ...rest } = s;
return rest;
}),
audioSegments: (this.timeline.audioSegments || []).map(s => {
const { _sSecs, _lSecs, _tSecs, _dSecs, _uploading, _decoding, _blobUrl, _audioBuffer, ...rest } = s;
return rest;
})
segments: (this.timeline.segments || []).map(stripImageSegmentTransient),
motionSegments: (this.timeline.motionSegments || []).map(stripMotionSegmentTransient),
audioSegments: (this.timeline.audioSegments || []).map(stripAudioSegmentTransient)
}
}, null, 2);
}
@@ -12260,31 +12276,6 @@ app.registerExtension({
"resize_method", "divisible_by", "img_compression", "override_audio", "timeline_ui"
];
const ALL_WIDGET_DEFAULTS = {
inpaint_audio: true,
override_audio: false,
use_custom_audio: false,
use_custom_motion: true,
frame_rate: 24,
display_mode: "seconds",
custom_width: 0,
custom_height: 0,
resize_method: "maintain aspect ratio",
divisible_by: 32,
img_compression: 18,
guide_strength: "",
local_prompts: "",
segment_lengths: "",
timeline_data: "{}",
epsilon: 0.001,
start_second: 0.0,
end_second: 5.0,
duration_seconds: 5.0,
start_frame: 0,
end_frame: 120,
duration_frames: 120,
};
let names = SCHEMA_23;
const len = info.widgets_values.length;
if (len <= 19) {
@@ -12304,8 +12295,8 @@ app.registerExtension({
const schemaIdx = names.indexOf(w.name);
if (schemaIdx !== -1 && schemaIdx < len) {
setWidgetValue(w, info.widgets_values[schemaIdx]);
} else if (ALL_WIDGET_DEFAULTS.hasOwnProperty(w.name)) {
setWidgetValue(w, ALL_WIDGET_DEFAULTS[w.name]);
} else if (DEFAULT_WIDGET_VALUES.hasOwnProperty(w.name)) {
setWidgetValue(w, DEFAULT_WIDGET_VALUES[w.name]);
}
}
}