@shotstack/shotstack-canvas 1.1.7 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entry.node.cjs +76 -34
- package/dist/entry.node.cjs.map +1 -1
- package/dist/entry.node.d.cts +1 -0
- package/dist/entry.node.d.ts +1 -0
- package/dist/entry.node.js +76 -34
- package/dist/entry.node.js.map +1 -1
- package/package.json +1 -1
package/dist/entry.node.d.cts
CHANGED
|
@@ -204,6 +204,7 @@ interface VideoGenerationOptions {
|
|
|
204
204
|
duration: number;
|
|
205
205
|
outputPath: string;
|
|
206
206
|
pixelRatio?: number;
|
|
207
|
+
hasAlpha?: boolean;
|
|
207
208
|
crf?: number;
|
|
208
209
|
preset?: "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "medium" | "slow" | "slower" | "veryslow";
|
|
209
210
|
tune?: "film" | "animation" | "grain" | "stillimage" | "psnr" | "ssim" | "fastdecode" | "zerolatency";
|
package/dist/entry.node.d.ts
CHANGED
|
@@ -204,6 +204,7 @@ interface VideoGenerationOptions {
|
|
|
204
204
|
duration: number;
|
|
205
205
|
outputPath: string;
|
|
206
206
|
pixelRatio?: number;
|
|
207
|
+
hasAlpha?: boolean;
|
|
207
208
|
crf?: number;
|
|
208
209
|
preset?: "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "medium" | "slow" | "slower" | "veryslow";
|
|
209
210
|
tune?: "film" | "animation" | "grain" | "stillimage" | "psnr" | "ssim" | "fastdecode" | "zerolatency";
|
package/dist/entry.node.js
CHANGED
|
@@ -1230,6 +1230,7 @@ async function createNodePainter(opts) {
|
|
|
1230
1230
|
const hasBackground = !!(op.bg && op.bg.color);
|
|
1231
1231
|
needsAlphaExtraction = !hasBackground;
|
|
1232
1232
|
if (op.bg && op.bg.color) {
|
|
1233
|
+
ctx.clearRect(0, 0, op.width, op.height);
|
|
1233
1234
|
const { color, opacity, radius } = op.bg;
|
|
1234
1235
|
const c = parseHex6(color, opacity);
|
|
1235
1236
|
ctx.fillStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;
|
|
@@ -1243,10 +1244,15 @@ async function createNodePainter(opts) {
|
|
|
1243
1244
|
ctx.fillRect(0, 0, op.width, op.height);
|
|
1244
1245
|
}
|
|
1245
1246
|
} else {
|
|
1247
|
+
ctx.clearRect(0, 0, op.width, op.height);
|
|
1248
|
+
ctx.save();
|
|
1246
1249
|
ctx.fillStyle = "rgb(255, 255, 255)";
|
|
1247
1250
|
ctx.fillRect(0, 0, op.width, op.height);
|
|
1251
|
+
ctx.restore();
|
|
1252
|
+
offscreenCtx.save();
|
|
1248
1253
|
offscreenCtx.fillStyle = "rgb(0, 0, 0)";
|
|
1249
1254
|
offscreenCtx.fillRect(0, 0, op.width, op.height);
|
|
1255
|
+
offscreenCtx.restore();
|
|
1250
1256
|
}
|
|
1251
1257
|
continue;
|
|
1252
1258
|
}
|
|
@@ -1632,44 +1638,72 @@ var VideoGenerator = class {
|
|
|
1632
1638
|
tune = "animation",
|
|
1633
1639
|
profile = "high",
|
|
1634
1640
|
level = "4.2",
|
|
1635
|
-
pixFmt = "yuv420p"
|
|
1641
|
+
pixFmt = "yuv420p",
|
|
1642
|
+
hasAlpha = false
|
|
1636
1643
|
} = options;
|
|
1637
1644
|
const totalFrames = Math.max(2, Math.round(duration * fps) + 1);
|
|
1645
|
+
const finalOutputPath = hasAlpha ? outputPath.replace(/\.mp4$/, ".mov") : outputPath;
|
|
1638
1646
|
console.log(
|
|
1639
|
-
`\u{1F3AC} Generating video: ${width}x${height} @ ${fps}fps, ${duration}s (${totalFrames} frames)
|
|
1640
|
-
CRF=${crf}, preset=${preset}, tune=${tune}, profile=${profile}, level=${level}, pix_fmt=${pixFmt}`
|
|
1647
|
+
`\u{1F3AC} Generating video: ${width}x${height} @ ${fps}fps, ${duration}s (${totalFrames} frames)` + (hasAlpha ? " (MOV with alpha)" : "")
|
|
1641
1648
|
);
|
|
1642
1649
|
return new Promise(async (resolve, reject) => {
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1650
|
+
let args;
|
|
1651
|
+
if (hasAlpha) {
|
|
1652
|
+
args = [
|
|
1653
|
+
"-y",
|
|
1654
|
+
"-f",
|
|
1655
|
+
"image2pipe",
|
|
1656
|
+
"-vcodec",
|
|
1657
|
+
"png",
|
|
1658
|
+
"-framerate",
|
|
1659
|
+
String(fps),
|
|
1660
|
+
"-i",
|
|
1661
|
+
"-",
|
|
1662
|
+
"-c:v",
|
|
1663
|
+
"prores_ks",
|
|
1664
|
+
"-profile:v",
|
|
1665
|
+
"4444",
|
|
1666
|
+
"-pix_fmt",
|
|
1667
|
+
"yuva444p10le",
|
|
1668
|
+
"-vendor",
|
|
1669
|
+
"apl0",
|
|
1670
|
+
"-r",
|
|
1671
|
+
String(fps),
|
|
1672
|
+
finalOutputPath
|
|
1673
|
+
];
|
|
1674
|
+
console.log(` Output: ${finalOutputPath} (ProRes 4444 with alpha)`);
|
|
1675
|
+
} else {
|
|
1676
|
+
args = [
|
|
1677
|
+
"-y",
|
|
1678
|
+
"-f",
|
|
1679
|
+
"image2pipe",
|
|
1680
|
+
"-vcodec",
|
|
1681
|
+
"png",
|
|
1682
|
+
"-framerate",
|
|
1683
|
+
String(fps),
|
|
1684
|
+
"-i",
|
|
1685
|
+
"-",
|
|
1686
|
+
"-c:v",
|
|
1687
|
+
"libx264",
|
|
1688
|
+
"-preset",
|
|
1689
|
+
preset,
|
|
1690
|
+
"-crf",
|
|
1691
|
+
String(crf),
|
|
1692
|
+
"-tune",
|
|
1693
|
+
tune,
|
|
1694
|
+
"-profile:v",
|
|
1695
|
+
profile,
|
|
1696
|
+
"-level",
|
|
1697
|
+
level,
|
|
1698
|
+
"-pix_fmt",
|
|
1699
|
+
pixFmt,
|
|
1700
|
+
"-r",
|
|
1701
|
+
String(fps),
|
|
1702
|
+
"-movflags",
|
|
1703
|
+
"+faststart",
|
|
1704
|
+
outputPath
|
|
1705
|
+
];
|
|
1706
|
+
}
|
|
1673
1707
|
const ffmpeg = spawn(this.ffmpegPath, args, { stdio: ["pipe", "inherit", "pipe"] });
|
|
1674
1708
|
let ffmpegError = "";
|
|
1675
1709
|
ffmpeg.stderr.on("data", (data) => {
|
|
@@ -1918,13 +1952,21 @@ async function createTextEngine(opts = {}) {
|
|
|
1918
1952
|
},
|
|
1919
1953
|
async generateVideo(asset, options) {
|
|
1920
1954
|
try {
|
|
1955
|
+
const hasBackground = !!asset.background?.color;
|
|
1956
|
+
const hasAnimation = !!asset.animation?.preset;
|
|
1957
|
+
const needsAlpha = !hasBackground && hasAnimation;
|
|
1958
|
+
console.log(
|
|
1959
|
+
`\u{1F3A8} Video settings: Animation=${hasAnimation}, Background=${hasBackground}, Alpha=${needsAlpha}`
|
|
1960
|
+
);
|
|
1921
1961
|
const finalOptions = {
|
|
1922
1962
|
width: asset.width ?? width,
|
|
1923
1963
|
height: asset.height ?? height,
|
|
1924
1964
|
fps,
|
|
1925
1965
|
duration: asset.animation?.duration ?? 3,
|
|
1926
1966
|
outputPath: options.outputPath ?? "output.mp4",
|
|
1927
|
-
pixelRatio: asset.pixelRatio ?? pixelRatio
|
|
1967
|
+
pixelRatio: asset.pixelRatio ?? pixelRatio,
|
|
1968
|
+
hasAlpha: needsAlpha,
|
|
1969
|
+
...options
|
|
1928
1970
|
};
|
|
1929
1971
|
const frameGenerator = async (time) => {
|
|
1930
1972
|
return this.renderFrame(asset, time);
|