mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-27 08:15:42 +00:00
fix(export): validate edited-track fast-path inputs
This commit is contained in:
@@ -100,6 +100,23 @@ describe("editedTrackStrategy", () => {
|
||||
).toBe("offline-render-fallback");
|
||||
});
|
||||
|
||||
it("falls back when source duration or speed-region bounds are invalid", () => {
|
||||
const invalidBounds: SpeedRegion[] = [
|
||||
{ id: "speed-1", startMs: Number.NaN, endMs: 10_000, speed: 1.5 },
|
||||
];
|
||||
|
||||
expect(
|
||||
classifyEditedTrackStrategy({
|
||||
primaryAudioSourcePath: "recording.mp4",
|
||||
sourceDurationMs: Number.POSITIVE_INFINITY,
|
||||
trimRegions: EMPTY_TRIMS,
|
||||
speedRegions: invalidBounds,
|
||||
audioRegions: [],
|
||||
sourceAudioFallbackPaths: [],
|
||||
}),
|
||||
).toBe("offline-render-fallback");
|
||||
});
|
||||
|
||||
it("builds source segments that preserve trims and speed boundaries", () => {
|
||||
const trimRegions: TrimRegion[] = [{ id: "trim-1", startMs: 10_000, endMs: 12_000 }];
|
||||
const speedRegions: SpeedRegion[] = [
|
||||
@@ -118,4 +135,12 @@ describe("editedTrackStrategy", () => {
|
||||
{ startMs: 18_000, endMs: 20_000, speed: 1 },
|
||||
]);
|
||||
});
|
||||
|
||||
it("returns no source segments when speed-region bounds are invalid", () => {
|
||||
expect(
|
||||
buildEditedTrackSourceSegments(SOURCE_DURATION_MS, EMPTY_TRIMS, [
|
||||
{ id: "speed-1", startMs: 15_000, endMs: 10_000, speed: 1.5 },
|
||||
]),
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,8 +26,29 @@ function isSafeFiltergraphSpeed(speed: number): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function hasSafeFiltergraphSpeedRegions(speedRegions: SpeedRegion[]): boolean {
|
||||
return speedRegions.every((region) => isSafeFiltergraphSpeed(region.speed));
|
||||
function hasFiniteTimelineRange(startMs: number, endMs: number, sourceDurationMs: number): boolean {
|
||||
return (
|
||||
Number.isFinite(startMs) &&
|
||||
Number.isFinite(endMs) &&
|
||||
startMs >= 0 &&
|
||||
endMs > startMs &&
|
||||
endMs <= sourceDurationMs
|
||||
);
|
||||
}
|
||||
|
||||
function hasSafeFiltergraphSpeedRegions(
|
||||
speedRegions: SpeedRegion[],
|
||||
sourceDurationMs: number,
|
||||
): boolean {
|
||||
if (!Number.isFinite(sourceDurationMs) || sourceDurationMs <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return speedRegions.every(
|
||||
(region) =>
|
||||
hasFiniteTimelineRange(region.startMs, region.endMs, sourceDurationMs) &&
|
||||
isSafeFiltergraphSpeed(region.speed),
|
||||
);
|
||||
}
|
||||
|
||||
function buildKeptRanges(
|
||||
@@ -64,6 +85,20 @@ export function buildEditedTrackSourceSegments(
|
||||
trimRegions: TrimRegion[],
|
||||
speedRegions: SpeedRegion[],
|
||||
): EditedTrackSourceSegment[] {
|
||||
if (!Number.isFinite(sourceDurationMs) || sourceDurationMs <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (
|
||||
speedRegions.some(
|
||||
(region) =>
|
||||
!hasFiniteTimelineRange(region.startMs, region.endMs, sourceDurationMs) ||
|
||||
!isSafeFiltergraphSpeed(region.speed),
|
||||
)
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const segments: EditedTrackSourceSegment[] = [];
|
||||
const keptRanges = buildKeptRanges(sourceDurationMs, trimRegions);
|
||||
|
||||
@@ -119,7 +154,7 @@ export function classifyEditedTrackStrategy(input: EditedTrackStrategyInput): Ed
|
||||
return "offline-render-fallback";
|
||||
}
|
||||
|
||||
if (!hasSafeFiltergraphSpeedRegions(input.speedRegions)) {
|
||||
if (!hasSafeFiltergraphSpeedRegions(input.speedRegions, input.sourceDurationMs)) {
|
||||
return "offline-render-fallback";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user