@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.
@@ -1268,6 +1268,7 @@ async function createNodePainter(opts) {
1268
1268
  const hasBackground = !!(op.bg && op.bg.color);
1269
1269
  needsAlphaExtraction = !hasBackground;
1270
1270
  if (op.bg && op.bg.color) {
1271
+ ctx.clearRect(0, 0, op.width, op.height);
1271
1272
  const { color, opacity, radius } = op.bg;
1272
1273
  const c = parseHex6(color, opacity);
1273
1274
  ctx.fillStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;
@@ -1281,10 +1282,15 @@ async function createNodePainter(opts) {
1281
1282
  ctx.fillRect(0, 0, op.width, op.height);
1282
1283
  }
1283
1284
  } else {
1285
+ ctx.clearRect(0, 0, op.width, op.height);
1286
+ ctx.save();
1284
1287
  ctx.fillStyle = "rgb(255, 255, 255)";
1285
1288
  ctx.fillRect(0, 0, op.width, op.height);
1289
+ ctx.restore();
1290
+ offscreenCtx.save();
1286
1291
  offscreenCtx.fillStyle = "rgb(0, 0, 0)";
1287
1292
  offscreenCtx.fillRect(0, 0, op.width, op.height);
1293
+ offscreenCtx.restore();
1288
1294
  }
1289
1295
  continue;
1290
1296
  }
@@ -1670,44 +1676,72 @@ var VideoGenerator = class {
1670
1676
  tune = "animation",
1671
1677
  profile = "high",
1672
1678
  level = "4.2",
1673
- pixFmt = "yuv420p"
1679
+ pixFmt = "yuv420p",
1680
+ hasAlpha = false
1674
1681
  } = options;
1675
1682
  const totalFrames = Math.max(2, Math.round(duration * fps) + 1);
1683
+ const finalOutputPath = hasAlpha ? outputPath.replace(/\.mp4$/, ".mov") : outputPath;
1676
1684
  console.log(
1677
- `\u{1F3AC} Generating video: ${width}x${height} @ ${fps}fps, ${duration}s (${totalFrames} frames)
1678
- CRF=${crf}, preset=${preset}, tune=${tune}, profile=${profile}, level=${level}, pix_fmt=${pixFmt}`
1685
+ `\u{1F3AC} Generating video: ${width}x${height} @ ${fps}fps, ${duration}s (${totalFrames} frames)` + (hasAlpha ? " (MOV with alpha)" : "")
1679
1686
  );
1680
1687
  return new Promise(async (resolve, reject) => {
1681
- const args = [
1682
- "-y",
1683
- "-f",
1684
- "image2pipe",
1685
- "-vcodec",
1686
- "png",
1687
- "-framerate",
1688
- String(fps),
1689
- "-i",
1690
- "-",
1691
- "-c:v",
1692
- "libx264",
1693
- "-preset",
1694
- preset,
1695
- "-crf",
1696
- String(crf),
1697
- "-tune",
1698
- tune,
1699
- "-profile:v",
1700
- profile,
1701
- "-level",
1702
- level,
1703
- "-pix_fmt",
1704
- pixFmt,
1705
- "-r",
1706
- String(fps),
1707
- "-movflags",
1708
- "+faststart",
1709
- outputPath
1710
- ];
1688
+ let args;
1689
+ if (hasAlpha) {
1690
+ args = [
1691
+ "-y",
1692
+ "-f",
1693
+ "image2pipe",
1694
+ "-vcodec",
1695
+ "png",
1696
+ "-framerate",
1697
+ String(fps),
1698
+ "-i",
1699
+ "-",
1700
+ "-c:v",
1701
+ "prores_ks",
1702
+ "-profile:v",
1703
+ "4444",
1704
+ "-pix_fmt",
1705
+ "yuva444p10le",
1706
+ "-vendor",
1707
+ "apl0",
1708
+ "-r",
1709
+ String(fps),
1710
+ finalOutputPath
1711
+ ];
1712
+ console.log(` Output: ${finalOutputPath} (ProRes 4444 with alpha)`);
1713
+ } else {
1714
+ args = [
1715
+ "-y",
1716
+ "-f",
1717
+ "image2pipe",
1718
+ "-vcodec",
1719
+ "png",
1720
+ "-framerate",
1721
+ String(fps),
1722
+ "-i",
1723
+ "-",
1724
+ "-c:v",
1725
+ "libx264",
1726
+ "-preset",
1727
+ preset,
1728
+ "-crf",
1729
+ String(crf),
1730
+ "-tune",
1731
+ tune,
1732
+ "-profile:v",
1733
+ profile,
1734
+ "-level",
1735
+ level,
1736
+ "-pix_fmt",
1737
+ pixFmt,
1738
+ "-r",
1739
+ String(fps),
1740
+ "-movflags",
1741
+ "+faststart",
1742
+ outputPath
1743
+ ];
1744
+ }
1711
1745
  const ffmpeg = (0, import_child_process.spawn)(this.ffmpegPath, args, { stdio: ["pipe", "inherit", "pipe"] });
1712
1746
  let ffmpegError = "";
1713
1747
  ffmpeg.stderr.on("data", (data) => {
@@ -1956,13 +1990,21 @@ async function createTextEngine(opts = {}) {
1956
1990
  },
1957
1991
  async generateVideo(asset, options) {
1958
1992
  try {
1993
+ const hasBackground = !!asset.background?.color;
1994
+ const hasAnimation = !!asset.animation?.preset;
1995
+ const needsAlpha = !hasBackground && hasAnimation;
1996
+ console.log(
1997
+ `\u{1F3A8} Video settings: Animation=${hasAnimation}, Background=${hasBackground}, Alpha=${needsAlpha}`
1998
+ );
1959
1999
  const finalOptions = {
1960
2000
  width: asset.width ?? width,
1961
2001
  height: asset.height ?? height,
1962
2002
  fps,
1963
2003
  duration: asset.animation?.duration ?? 3,
1964
2004
  outputPath: options.outputPath ?? "output.mp4",
1965
- pixelRatio: asset.pixelRatio ?? pixelRatio
2005
+ pixelRatio: asset.pixelRatio ?? pixelRatio,
2006
+ hasAlpha: needsAlpha,
2007
+ ...options
1966
2008
  };
1967
2009
  const frameGenerator = async (time) => {
1968
2010
  return this.renderFrame(asset, time);