mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-25 15:25:44 +00:00
Merge pull request #310 from meiiie/fix/native-audio-lead
fix(recording): keep longer audio tracks anchored
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { appendSyncedAudioFilter, getAudioSyncAdjustment } from "./filters";
|
||||
|
||||
describe("getAudioSyncAdjustment", () => {
|
||||
it("does not speed up longer audio tracks that would advance speech", () => {
|
||||
expect(getAudioSyncAdjustment(120, 122.5)).toEqual({
|
||||
mode: "none",
|
||||
delayMs: 0,
|
||||
tempoRatio: 1,
|
||||
durationDeltaMs: -2500,
|
||||
});
|
||||
});
|
||||
|
||||
it("still stretches slightly shorter audio tracks to match the video", () => {
|
||||
expect(getAudioSyncAdjustment(120, 117)).toEqual({
|
||||
mode: "tempo",
|
||||
delayMs: 0,
|
||||
tempoRatio: 0.975,
|
||||
durationDeltaMs: 3000,
|
||||
});
|
||||
});
|
||||
|
||||
it("still delays much shorter audio tracks instead of extreme tempo correction", () => {
|
||||
expect(getAudioSyncAdjustment(120, 110)).toEqual({
|
||||
mode: "delay",
|
||||
delayMs: 10000,
|
||||
tempoRatio: 1,
|
||||
durationDeltaMs: 10000,
|
||||
});
|
||||
});
|
||||
|
||||
it("does not inject atempo when longer audio stays on the anchored path", () => {
|
||||
const filterParts: string[] = [];
|
||||
appendSyncedAudioFilter(filterParts, "[1:a]", "aout", getAudioSyncAdjustment(120, 122.5));
|
||||
|
||||
expect(filterParts).toEqual([
|
||||
"[1:a]aresample=async=1:first_pts=0,asetpts=PTS-STARTPTS[aout]",
|
||||
]);
|
||||
});
|
||||
|
||||
it("still injects atempo for slightly shorter audio tracks", () => {
|
||||
const filterParts: string[] = [];
|
||||
appendSyncedAudioFilter(filterParts, "[1:a]", "aout", getAudioSyncAdjustment(120, 117));
|
||||
|
||||
expect(filterParts).toEqual([
|
||||
"[1:a]atempo=0.975000,aresample=async=1:first_pts=0,asetpts=PTS-STARTPTS[aout]",
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -44,10 +44,17 @@ export function getAudioSyncAdjustment(
|
||||
return { mode: "none", delayMs: 0, tempoRatio: 1, durationDeltaMs };
|
||||
}
|
||||
|
||||
// When the recorded audio runs longer than the video, globally speeding it
|
||||
// up can pull speech ahead of the picture. Keep the track anchored at the
|
||||
// start instead and let the downstream mux path trim any trailing overrun.
|
||||
if (durationDeltaMs < 0) {
|
||||
return { mode: "none", delayMs: 0, tempoRatio: 1, durationDeltaMs };
|
||||
}
|
||||
|
||||
const tempoRatio = Math.max(0.5, Math.min(2, audioDuration / videoDuration));
|
||||
const relativeDelta = absDeltaMs / Math.max(videoDuration * 1000, 1);
|
||||
|
||||
if (relativeDelta <= 0.03 || absDeltaMs <= 1500 || durationDeltaMs < 0) {
|
||||
if (relativeDelta <= 0.03 || absDeltaMs <= 1500) {
|
||||
return { mode: "tempo", delayMs: 0, tempoRatio, durationDeltaMs };
|
||||
}
|
||||
|
||||
@@ -78,9 +85,7 @@ export function formatFfmpegSeconds(milliseconds: number): string {
|
||||
return (milliseconds / 1000).toFixed(3);
|
||||
}
|
||||
|
||||
export function normalizePauseSegments(
|
||||
pauseSegments: PauseSegment[] | undefined,
|
||||
): PauseSegment[] {
|
||||
export function normalizePauseSegments(pauseSegments: PauseSegment[] | undefined): PauseSegment[] {
|
||||
if (!Array.isArray(pauseSegments) || pauseSegments.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user