chore(merge): resolve merge conflict in streamingDecoder.ts

Address merge conflict markers added during resolution of Windows export fixes, ensuring clean integration of decode termination logic updates.
This commit is contained in:
Azeru
2026-04-11 18:43:02 +01:00
4 changed files with 44 additions and 43 deletions
+9 -10
View File
@@ -639,16 +639,15 @@ export function registerIpcHandlers(
}
});
/**
* Handles saving an exported video file.
* Shows a save dialog, normalizes the file path for the current OS,
* ensures the directory exists, and writes the video data.
* @param _ - Unused event parameter.
* @param videoData - The exported video as an ArrayBuffer.
* @param fileName - Suggested filename for the save dialog.
* @returns Object with success status, optional file path, and error details.
*/
/**
* Handles saving an exported video file.
* Shows a save dialog, normalizes the file path for the current OS,
* ensures the directory exists, and writes the video data.
* @param _ - Unused event parameter.
* @param videoData - The exported video as an ArrayBuffer.
* @param fileName - Suggested filename for the save dialog.
* @returns Object with success status, optional file path, and error details.
*/
ipcMain.handle("save-exported-video", async (_, videoData: ArrayBuffer, fileName: string) => {
try {
@@ -320,7 +320,6 @@ export default function VideoEditor() {
aspectRatio,
webcamLayoutPreset,
webcamMaskShape,
webcamSizePreset,
webcamPosition,
exportQuality,
exportFormat,
@@ -1313,7 +1313,6 @@ export default function TimelineEditor({
selectedBlurId,
selectedSpeedId,
annotationRegions,
blurRegions,
currentTime,
onSelectAnnotation,
keyShortcuts,
+35 -31
View File
@@ -217,15 +217,15 @@ export class StreamingVideoDecoder {
return this.metadata;
}
/**
* Decodes all video frames from the loaded source and invokes a callback for each.
* Handles trimming and speed adjustments, and resamples to the target frame rate.
* On Windows, early decode termination is tolerated to work around driver quirks.
* @param targetFrameRate - Desired output frame rate.
* @param trimRegions - Array of time regions to keep (others discarded).
* @param speedRegions - Array of speed adjustments for specific time ranges.
* @param onFrame - Async callback receiving each decoded VideoFrame.
*/
/**
* Decodes all video frames from the loaded source and invokes a callback for each.
* Handles trimming and speed adjustments, and resamples to the target frame rate.
* On Windows, early decode termination is tolerated to work around driver quirks.
* @param targetFrameRate - Desired output frame rate.
* @param trimRegions - Array of time regions to keep (others discarded).
* @param speedRegions - Array of speed adjustments for specific time ranges.
* @param onFrame - Async callback receiving each decoded VideoFrame.
*/
async decodeAll(
targetFrameRate: number,
trimRegions: TrimRegion[] | undefined,
@@ -501,31 +501,35 @@ export class StreamingVideoDecoder {
}
this.decoder = null;
const isWindows = typeof navigator !== "undefined" && /Windows/.test(navigator.userAgent);
const isWindows = typeof navigator !== "undefined" && /Windows/.test(navigator.userAgent);
if (shouldFailDecodeEndedEarly({
cancelled: this.cancelled,
lastDecodedFrameSec,
requiredEndSec,
streamDurationSec: this.metadata.streamDuration,
})) {
const decodedAtLabel = lastDecodedFrameSec === null ? "no decoded frame" : `${lastDecodedFrameSec.toFixed(3)}s`;
const decodeGapSec = lastDecodedFrameSec === null ? Infinity : requiredEndSec - lastDecodedFrameSec;
if (
shouldFailDecodeEndedEarly({
cancelled: this.cancelled,
lastDecodedFrameSec,
requiredEndSec,
streamDurationSec: this.metadata.streamDuration,
})
) {
const decodedAtLabel =
lastDecodedFrameSec === null ? "no decoded frame" : `${lastDecodedFrameSec.toFixed(3)}s`;
const decodeGapSec =
lastDecodedFrameSec === null ? Infinity : requiredEndSec - lastDecodedFrameSec;
// On Windows, tolerate a small decode gap: up to 10% of required duration, capped at 3 seconds.
const maxToleratedGap = Math.min(3.0, requiredEndSec * 0.1);
// On Windows, tolerate a small decode gap: up to 10% of required duration, capped at 3 seconds.
const maxToleratedGap = Math.min(3.0, requiredEndSec * 0.1);
if (isWindows && lastDecodedFrameSec !== null && decodeGapSec <= maxToleratedGap) {
console.warn(
`[StreamingVideoDecoder] Decode ended early on Windows with a gap of ${decodeGapSec.toFixed(2)}s ` +
`(max tolerated: ${maxToleratedGap.toFixed(2)}s) proceeding anyway.`,
);
} else {
throw new Error(
`Video decode ended early at ${decodedAtLabel} (needed ${requiredEndSec.toFixed(3)}s).`,
);
}
}
if (isWindows && lastDecodedFrameSec !== null && decodeGapSec <= maxToleratedGap) {
console.warn(
`[StreamingVideoDecoder] Decode ended early on Windows with a gap of ${decodeGapSec.toFixed(2)}s ` +
`(max tolerated: ${maxToleratedGap.toFixed(2)}s) proceeding anyway.`,
);
} else {
throw new Error(
`Video decode ended early at ${decodedAtLabel} (needed ${requiredEndSec.toFixed(3)}s).`,
);
}
}
}
private computeSegments(