refactor: simplify director video sync paths
This commit is contained in:
@@ -2122,6 +2122,41 @@ class TimelineEditor {
|
||||
};
|
||||
}
|
||||
|
||||
_syncActiveVideoSegments(segments, currentFrame, frameRate, activeType, dragSelectionType = null) {
|
||||
const activeList = (this._isDragging && this._previewSegments && dragSelectionType === this.selectionType)
|
||||
? this._previewSegments
|
||||
: segments;
|
||||
const activeSeg = activeList.find(s => s.type === activeType && currentFrame >= s.start && currentFrame < s.start + s.length);
|
||||
const activeVideoEl = activeSeg ? activeSeg.videoEl : null;
|
||||
|
||||
for (const seg of activeList) {
|
||||
if (seg.type !== activeType || !seg.videoEl) continue;
|
||||
if (seg === activeSeg) {
|
||||
const expectedSec = (seg.trimStart + (currentFrame - seg.start)) / frameRate;
|
||||
if (seg.videoEl.paused && !seg.videoEl.seeking) {
|
||||
seg.videoEl.currentTime = expectedSec;
|
||||
seg.videoEl.play().catch(e => console.warn("Video play prevented", e));
|
||||
} else if (!seg.videoEl.paused && Math.abs(seg.videoEl.currentTime - expectedSec) > 0.5) {
|
||||
seg.videoEl.currentTime = expectedSec;
|
||||
}
|
||||
} else if (seg.videoEl !== activeVideoEl && !seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_pauseAndSeekSegments(segments, currentFrame, frameRate, activeType) {
|
||||
for (const seg of segments) {
|
||||
if (seg.type !== activeType || !seg.videoEl) continue;
|
||||
if (!seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
if (currentFrame >= seg.start && currentFrame < seg.start + seg.length) {
|
||||
seg.videoEl.currentTime = (seg.trimStart + (currentFrame - seg.start)) / frameRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _preloadAudioSegment(seg) {
|
||||
if (seg._audioBuffer || seg._decoding) return;
|
||||
if (!seg.audioFile && !seg._blobUrl) return;
|
||||
@@ -11582,11 +11617,11 @@ class TimelineEditor {
|
||||
}
|
||||
|
||||
// Sync video playback
|
||||
if (this.retakeMode) {
|
||||
if (this.timeline.retakeVideo) {
|
||||
const retakeVid = this.timeline.retakeVideo;
|
||||
this._ensureVideoEl(retakeVid);
|
||||
if (retakeVid.videoEl) {
|
||||
if (this.retakeMode) {
|
||||
if (this.timeline.retakeVideo) {
|
||||
const retakeVid = this.timeline.retakeVideo;
|
||||
this._ensureVideoEl(retakeVid);
|
||||
if (retakeVid.videoEl) {
|
||||
const expectedSec = this.currentFrame / frameRate;
|
||||
if (retakeVid.videoEl.paused && !retakeVid.videoEl.seeking) {
|
||||
retakeVid.videoEl.currentTime = expectedSec;
|
||||
@@ -11600,66 +11635,18 @@ class TimelineEditor {
|
||||
// Pause all other video elements
|
||||
const allSegments = [...(this.timeline.segments || []), ...(this.timeline.motionSegments || [])];
|
||||
for (const seg of allSegments) {
|
||||
if (seg.videoEl && !seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const activeSegments = (this._isDragging && this._previewSegments && this.selectionType !== "audio") ? this._previewSegments : this.timeline.segments;
|
||||
const activeSeg = activeSegments.find(s => s.type === "video" && this.currentFrame >= s.start && this.currentFrame < s.start + s.length);
|
||||
const activeVideoEl = activeSeg ? activeSeg.videoEl : null;
|
||||
|
||||
for (const seg of activeSegments) {
|
||||
if (seg.type === "video" && seg.videoEl) {
|
||||
if (seg === activeSeg) {
|
||||
const expectedSec = (seg.trimStart + (this.currentFrame - seg.start)) / frameRate;
|
||||
if (seg.videoEl.paused && !seg.videoEl.seeking) {
|
||||
// Not playing and no seek in flight — start a fresh seek+play
|
||||
seg.videoEl.currentTime = expectedSec;
|
||||
seg.videoEl.play().catch(e => console.warn("Video play prevented", e));
|
||||
} else if (!seg.videoEl.paused && Math.abs(seg.videoEl.currentTime - expectedSec) > 0.5) {
|
||||
// Already playing but drifted — resync
|
||||
seg.videoEl.currentTime = expectedSec;
|
||||
}
|
||||
// If paused && seeking: a seek+play is already in flight, let it finish
|
||||
} else {
|
||||
// Only pause if this segment's video element is NOT shared with the currently active segment
|
||||
if (seg.videoEl !== activeVideoEl && !seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sync motion playback
|
||||
if (!this.retakeMode) {
|
||||
const activeMotionSegments = (this._isDragging && this._previewSegments && this.selectionType === "motion") ? this._previewSegments : this.timeline.motionSegments;
|
||||
const activeMotionSeg = activeMotionSegments.find(s => s.type === "motion_video" && this.currentFrame >= s.start && this.currentFrame < s.start + s.length);
|
||||
const activeMotionVideoEl = activeMotionSeg ? activeMotionSeg.videoEl : null;
|
||||
|
||||
for (const seg of activeMotionSegments) {
|
||||
if (seg.type === "motion_video" && seg.videoEl) {
|
||||
if (seg === activeMotionSeg) {
|
||||
const expectedSec = (seg.trimStart + (this.currentFrame - seg.start)) / frameRate;
|
||||
if (seg.videoEl.paused && !seg.videoEl.seeking) {
|
||||
// Not playing and no seek in flight — start a fresh seek+play
|
||||
seg.videoEl.currentTime = expectedSec;
|
||||
seg.videoEl.play().catch(e => console.warn("Video play prevented", e));
|
||||
} else if (!seg.videoEl.paused && Math.abs(seg.videoEl.currentTime - expectedSec) > 0.5) {
|
||||
// Already playing but drifted — resync
|
||||
seg.videoEl.currentTime = expectedSec;
|
||||
}
|
||||
// If paused && seeking: a seek+play is already in flight, let it finish
|
||||
} else {
|
||||
// Only pause if this segment's video element is NOT shared with the currently active motion segment
|
||||
if (seg.videoEl !== activeMotionVideoEl && !seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seg.videoEl && !seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this._syncActiveVideoSegments(this.timeline.segments, this.currentFrame, frameRate, "video", "image");
|
||||
}
|
||||
|
||||
// Sync motion playback
|
||||
if (!this.retakeMode) {
|
||||
this._syncActiveVideoSegments(this.timeline.motionSegments, this.currentFrame, frameRate, "motion_video", "motion");
|
||||
}
|
||||
|
||||
this.render();
|
||||
this._playLoopId = requestAnimationFrame(loop);
|
||||
@@ -11676,40 +11663,20 @@ class TimelineEditor {
|
||||
try { this.audioContext.suspend(); } catch (e) { }
|
||||
}
|
||||
|
||||
if (this.retakeMode && this.timeline.retakeVideo) {
|
||||
const retakeVid = this.timeline.retakeVideo;
|
||||
if (retakeVid.videoEl) {
|
||||
if (!retakeVid.videoEl.paused) {
|
||||
if (this.retakeMode && this.timeline.retakeVideo) {
|
||||
const retakeVid = this.timeline.retakeVideo;
|
||||
if (retakeVid.videoEl) {
|
||||
if (!retakeVid.videoEl.paused) {
|
||||
retakeVid.videoEl.pause();
|
||||
}
|
||||
retakeVid.videoEl.muted = true; // Mute again on pause/stop to prevent transient audio bursts
|
||||
retakeVid.videoEl.currentTime = this.currentFrame / this.getFrameRate();
|
||||
}
|
||||
} else {
|
||||
// Sync video segments on pause
|
||||
for (const seg of this.timeline.segments) {
|
||||
if (seg.type === "video" && seg.videoEl) {
|
||||
if (!seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
if (this.currentFrame >= seg.start && this.currentFrame < seg.start + seg.length) {
|
||||
seg.videoEl.currentTime = (seg.trimStart + (this.currentFrame - seg.start)) / this.getFrameRate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sync motion segments on pause
|
||||
for (const seg of this.timeline.motionSegments) {
|
||||
if (seg.type === "motion_video" && seg.videoEl) {
|
||||
if (!seg.videoEl.paused) {
|
||||
seg.videoEl.pause();
|
||||
}
|
||||
if (this.currentFrame >= seg.start && this.currentFrame < seg.start + seg.length) {
|
||||
seg.videoEl.currentTime = (seg.trimStart + (this.currentFrame - seg.start)) / this.getFrameRate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
retakeVid.videoEl.currentTime = this.currentFrame / this.getFrameRate();
|
||||
}
|
||||
} else {
|
||||
const frameRate = this.getFrameRate();
|
||||
this._pauseAndSeekSegments(this.timeline.segments, this.currentFrame, frameRate, "video");
|
||||
this._pauseAndSeekSegments(this.timeline.motionSegments, this.currentFrame, frameRate, "motion_video");
|
||||
}
|
||||
|
||||
for (let node of this.activeAudioNodes) {
|
||||
try { node.stop(); } catch (e) { }
|
||||
|
||||
Reference in New Issue
Block a user