Initial OSS scaffold from Songs2VID (pre-strip)
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import assert from "node:assert/strict";
|
||||
import {
|
||||
BLUR_AMOUNT_MAX,
|
||||
INVALID_LAYOUT_TEMPLATE_MESSAGE,
|
||||
blurToBoxblur,
|
||||
boxblurFilterSegment,
|
||||
buildArtTrackFilterComplex,
|
||||
clampBlurAmount,
|
||||
clampTextPadding,
|
||||
clampTitleArtistGap,
|
||||
computeLayoutGeometry,
|
||||
normalizeLayoutSettings,
|
||||
requiresArtTrackLayoutEntitlement,
|
||||
} from "../lib/layout";
|
||||
import { sanitizeDrawtext } from "../lib/watermark";
|
||||
|
||||
function testEnumsAndClamp() {
|
||||
assert.equal(clampBlurAmount(150), BLUR_AMOUNT_MAX);
|
||||
assert.equal(clampBlurAmount(-1), 0);
|
||||
assert.equal(clampTextPadding(999), 120);
|
||||
assert.equal(clampTextPadding(1), 16);
|
||||
assert.equal(clampTitleArtistGap(100), 64);
|
||||
assert.equal(clampTitleArtistGap(-5), 0);
|
||||
|
||||
assert.equal(blurToBoxblur(0), null);
|
||||
const mid = blurToBoxblur(50);
|
||||
assert.ok(mid && mid.radius >= 1 && mid.power >= 1);
|
||||
assert.ok(boxblurFilterSegment(60).includes("boxblur="));
|
||||
assert.equal(boxblurFilterSegment(0), "");
|
||||
}
|
||||
|
||||
function testNormalize() {
|
||||
const classic = normalizeLayoutSettings(null);
|
||||
assert.equal(classic.template, null);
|
||||
assert.equal(classic.titleArtistGap, 10);
|
||||
assert.equal(classic.textOffsetX, 0);
|
||||
|
||||
assert.equal(
|
||||
normalizeLayoutSettings({
|
||||
layout_template: "CENTERED_COMPACT",
|
||||
blur_amount: 80,
|
||||
title_artist_gap: 24,
|
||||
text_offset_y: -20,
|
||||
}).titleArtistGap,
|
||||
24,
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => normalizeLayoutSettings({ template: "NOT_A_TEMPLATE" }),
|
||||
(err: Error) => err.message === INVALID_LAYOUT_TEMPLATE_MESSAGE,
|
||||
);
|
||||
assert.throws(
|
||||
() => normalizeLayoutSettings({ template: "COVER_LEFT_TEXT_RIGHT", x: 10 }),
|
||||
(err: Error) => err.message === INVALID_LAYOUT_TEMPLATE_MESSAGE,
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
requiresArtTrackLayoutEntitlement(normalizeLayoutSettings({ template: null })),
|
||||
false,
|
||||
);
|
||||
assert.equal(
|
||||
requiresArtTrackLayoutEntitlement(
|
||||
normalizeLayoutSettings({ template: "COVER_TOP_TEXT_BOTTOM" }),
|
||||
),
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
function testGeometryAndFilter() {
|
||||
const geo = computeLayoutGeometry("COVER_TOP_TEXT_BOTTOM", 1920, 1080, 48, 16, 10, -5);
|
||||
assert.ok(geo.coverMaxW > 1600, "top layout cover should be near full width");
|
||||
assert.ok(geo.artistY !== geo.titleY);
|
||||
|
||||
const withGap = computeLayoutGeometry("COVER_LEFT_TEXT_RIGHT", 1280, 720, 40, 40, 0, 0);
|
||||
const tight = computeLayoutGeometry("COVER_LEFT_TEXT_RIGHT", 1280, 720, 40, 0, 0, 0);
|
||||
assert.ok(Number(withGap.artistY) - Number(withGap.titleY) > Number(tight.artistY) - Number(tight.titleY));
|
||||
|
||||
const fc = buildArtTrackFilterComplex({
|
||||
width: 1280,
|
||||
height: 720,
|
||||
layout: {
|
||||
template: "CENTERED_COMPACT",
|
||||
blurAmount: 40,
|
||||
blurOpacity: 70,
|
||||
textPadding: 40,
|
||||
titleArtistGap: 18,
|
||||
textOffsetX: 5,
|
||||
textOffsetY: -8,
|
||||
},
|
||||
titleEscaped: sanitizeDrawtext("Hello:World"),
|
||||
artistEscaped: sanitizeDrawtext("Artist"),
|
||||
});
|
||||
assert.ok(fc.includes("split=2"));
|
||||
assert.ok(fc.includes("blend=") || fc.includes("[blurred]"));
|
||||
assert.ok(fc.includes("overlay="));
|
||||
assert.ok(fc.includes("drawtext="));
|
||||
assert.ok(fc.endsWith("[laid]"));
|
||||
}
|
||||
|
||||
testEnumsAndClamp();
|
||||
testNormalize();
|
||||
testGeometryAndFilter();
|
||||
console.log("layout.test.ts: ok");
|
||||
Reference in New Issue
Block a user