feat: publish av-tools 0.2.0

This commit is contained in:
2026-07-27 01:04:21 +02:00
parent fcc537b024
commit 0a4548851c
68 changed files with 4130 additions and 605 deletions

View File

@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
import {
buildConvertPlan,
buildFastConcatPlan,
buildNormalizedConcatPlan,
buildPreviewProxyPlan,
buildRemuxPlan,
buildSplitPlan,
@@ -276,6 +277,64 @@ describe('concat and transform validation', () => {
expect(plan.expectedDurationSeconds).toBe(5);
});
it('builds bounded chained audio/video crossfades for normalized concat', () => {
const preset = findBuiltInPreset('mp4-h264-balanced');
const sources = [
{ ...SOURCES[0]!, durationSeconds: 4 },
{ ...SOURCES[1]!, durationSeconds: 5 },
{
...SOURCES[1]!,
id: 'three',
sourceIndex: 2,
fileName: 'three.mp4',
durationSeconds: 3,
},
];
const plan = buildNormalizedConcatPlan({
jobId: 'crossfade',
sources,
targetExtension: 'mp4',
targetMuxer: 'mp4',
preset: preset!,
width: 640,
height: 360,
frameRate: 25,
sampleRate: 48_000,
channelLayout: 'stereo',
missingAudioPolicy: 'reject',
subtitlePolicy: 'reject',
crossfadeSeconds: 0.5,
});
const graph = plan.args[plan.args.indexOf('-filter_complex') + 1] ?? '';
expect(graph).toContain(
'[v0][v1]xfade=transition=fade:duration=0.5:offset=3.5[vxf1]'
);
expect(graph).toContain(
'[vxf1][v2]xfade=transition=fade:duration=0.5:offset=8[vout]'
);
expect(graph).toContain('[a0][a1]acrossfade=d=0.5:c1=tri:c2=tri[axf1]');
expect(graph).not.toContain('concat=n=3');
expect(plan.expectedDurationSeconds).toBe(11);
expect(plan.requiredCapabilities.filters).toEqual(
expect.arrayContaining(['xfade', 'acrossfade'])
);
expect(() =>
buildNormalizedConcatPlan({
jobId: 'too-long-crossfade',
sources: SOURCES,
targetExtension: 'mp4',
targetMuxer: 'mp4',
preset: preset!,
width: 640,
height: 360,
frameRate: 25,
missingAudioPolicy: 'reject',
subtitlePolicy: 'reject',
crossfadeSeconds: 2.5,
})
).toThrow(/Clip 1 needs at least/iu);
});
it('corrects crop to even bounds and calculates aspect-preserving resize', () => {
expect(
validateCrop({