@shotstack/shotstack-canvas 2.0.3 → 2.0.5
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 +59 -43
- package/dist/entry.node.d.cts +2 -1
- package/dist/entry.node.d.ts +2 -1
- package/dist/entry.node.js +58 -43
- package/dist/entry.web.d.ts +2 -1
- package/dist/entry.web.js +906 -1829
- package/package.json +65 -65
package/dist/entry.node.cjs
CHANGED
|
@@ -362,6 +362,7 @@ __export(entry_node_exports, {
|
|
|
362
362
|
RichCaptionRenderer: () => RichCaptionRenderer,
|
|
363
363
|
WordTimingStore: () => WordTimingStore,
|
|
364
364
|
arcToCubicBeziers: () => arcToCubicBeziers,
|
|
365
|
+
breakIntoLines: () => breakIntoLines,
|
|
365
366
|
calculateAnimationStatesForGroup: () => calculateAnimationStatesForGroup,
|
|
366
367
|
commandsToPathString: () => commandsToPathString,
|
|
367
368
|
computeSimplePathBounds: () => computeSimplePathBounds,
|
|
@@ -417,7 +418,7 @@ var CANVAS_CONFIG = {
|
|
|
417
418
|
width: 800,
|
|
418
419
|
height: 400,
|
|
419
420
|
pixelRatio: 2,
|
|
420
|
-
fontFamily: "
|
|
421
|
+
fontFamily: "Open Sans",
|
|
421
422
|
fontSize: 48,
|
|
422
423
|
color: "#ffffff",
|
|
423
424
|
textAlign: "center"
|
|
@@ -572,7 +573,7 @@ var wordTimingSchema = import_zod2.wordTimingSchema.extend({
|
|
|
572
573
|
confidence: import_zod.z.number().min(0).max(1).optional()
|
|
573
574
|
});
|
|
574
575
|
var richCaptionFontSchema = import_zod.z.object({
|
|
575
|
-
family: import_zod.z.string().default(
|
|
576
|
+
family: import_zod.z.string().default(CANVAS_CONFIG.DEFAULTS.fontFamily),
|
|
576
577
|
size: import_zod.z.number().int().min(1).max(500).default(24),
|
|
577
578
|
weight: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).default("400"),
|
|
578
579
|
color: import_zod.z.string().regex(HEX6).default("#ffffff"),
|
|
@@ -581,7 +582,7 @@ var richCaptionFontSchema = import_zod.z.object({
|
|
|
581
582
|
});
|
|
582
583
|
var richCaptionActiveSchema = import_zod2.richCaptionActiveSchema.extend({
|
|
583
584
|
font: import_zod.z.object({
|
|
584
|
-
color: import_zod.z.string().regex(HEX6).default("#
|
|
585
|
+
color: import_zod.z.string().regex(HEX6).default("#ffffff"),
|
|
585
586
|
background: import_zod.z.string().regex(HEX6).optional(),
|
|
586
587
|
opacity: import_zod.z.number().min(0).max(1).default(1)
|
|
587
588
|
}).optional(),
|
|
@@ -4328,7 +4329,7 @@ function groupWordsByPause(store, pauseThreshold = 500) {
|
|
|
4328
4329
|
}
|
|
4329
4330
|
return groups;
|
|
4330
4331
|
}
|
|
4331
|
-
function breakIntoLines(wordWidths, maxWidth,
|
|
4332
|
+
function breakIntoLines(wordWidths, maxWidth, spaceWidth) {
|
|
4332
4333
|
const lines = [];
|
|
4333
4334
|
let currentLine = [];
|
|
4334
4335
|
let currentWidth = 0;
|
|
@@ -4341,15 +4342,12 @@ function breakIntoLines(wordWidths, maxWidth, maxLines, spaceWidth) {
|
|
|
4341
4342
|
} else {
|
|
4342
4343
|
if (currentLine.length > 0) {
|
|
4343
4344
|
lines.push(currentLine);
|
|
4344
|
-
if (lines.length >= maxLines) {
|
|
4345
|
-
return lines;
|
|
4346
|
-
}
|
|
4347
4345
|
}
|
|
4348
4346
|
currentLine = [i];
|
|
4349
4347
|
currentWidth = wordWidth;
|
|
4350
4348
|
}
|
|
4351
4349
|
}
|
|
4352
|
-
if (currentLine.length > 0
|
|
4350
|
+
if (currentLine.length > 0) {
|
|
4353
4351
|
lines.push(currentLine);
|
|
4354
4352
|
}
|
|
4355
4353
|
return lines;
|
|
@@ -4382,6 +4380,13 @@ function transformText(text, transform) {
|
|
|
4382
4380
|
return text;
|
|
4383
4381
|
}
|
|
4384
4382
|
}
|
|
4383
|
+
function splitIntoChunks(arr, chunkSize) {
|
|
4384
|
+
const chunks = [];
|
|
4385
|
+
for (let i = 0; i < arr.length; i += chunkSize) {
|
|
4386
|
+
chunks.push(arr.slice(i, i + chunkSize));
|
|
4387
|
+
}
|
|
4388
|
+
return chunks;
|
|
4389
|
+
}
|
|
4385
4390
|
var CaptionLayoutEngine = class {
|
|
4386
4391
|
fontRegistry;
|
|
4387
4392
|
cache;
|
|
@@ -4468,31 +4473,34 @@ var CaptionLayoutEngine = class {
|
|
|
4468
4473
|
const spaceWord = await this.measureWord(" ", measurementConfig);
|
|
4469
4474
|
spaceWidth = spaceWord.width + config.wordSpacing;
|
|
4470
4475
|
}
|
|
4471
|
-
const groups = wordGroups.
|
|
4476
|
+
const groups = wordGroups.flatMap((indices) => {
|
|
4472
4477
|
const groupWidths = indices.map((i) => store.widths[i]);
|
|
4473
|
-
const
|
|
4478
|
+
const allLines = breakIntoLines(
|
|
4474
4479
|
groupWidths,
|
|
4475
4480
|
pixelMaxWidth,
|
|
4476
|
-
config.maxLines,
|
|
4477
4481
|
spaceWidth
|
|
4478
4482
|
);
|
|
4479
|
-
const
|
|
4480
|
-
|
|
4481
|
-
const
|
|
4483
|
+
const lineChunks = splitIntoChunks(allLines, config.maxLines);
|
|
4484
|
+
return lineChunks.map((chunkLines) => {
|
|
4485
|
+
const lines = chunkLines.map((lineWordIndices, lineIndex) => {
|
|
4486
|
+
const actualIndices = lineWordIndices.map((i) => indices[i]);
|
|
4487
|
+
const lineWidth = actualIndices.reduce((sum, idx) => sum + store.widths[idx], 0) + (actualIndices.length - 1) * spaceWidth;
|
|
4488
|
+
return {
|
|
4489
|
+
wordIndices: actualIndices,
|
|
4490
|
+
x: 0,
|
|
4491
|
+
y: lineIndex * config.fontSize * config.lineHeight,
|
|
4492
|
+
width: lineWidth,
|
|
4493
|
+
height: config.fontSize
|
|
4494
|
+
};
|
|
4495
|
+
});
|
|
4496
|
+
const allWordIndices = lines.flatMap((l) => l.wordIndices);
|
|
4482
4497
|
return {
|
|
4483
|
-
wordIndices:
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
height: config.fontSize
|
|
4498
|
+
wordIndices: allWordIndices,
|
|
4499
|
+
startTime: store.startTimes[allWordIndices[0]],
|
|
4500
|
+
endTime: store.endTimes[allWordIndices[allWordIndices.length - 1]],
|
|
4501
|
+
lines
|
|
4488
4502
|
};
|
|
4489
4503
|
});
|
|
4490
|
-
return {
|
|
4491
|
-
wordIndices: lines.flatMap((l) => l.wordIndices),
|
|
4492
|
-
startTime: store.startTimes[indices[0]],
|
|
4493
|
-
endTime: store.endTimes[indices[indices.length - 1]],
|
|
4494
|
-
lines
|
|
4495
|
-
};
|
|
4496
4504
|
});
|
|
4497
4505
|
const calculateGroupY = (group) => {
|
|
4498
4506
|
const totalHeight = group.lines.length * config.fontSize * config.lineHeight;
|
|
@@ -4867,11 +4875,11 @@ function extractFontConfig(asset) {
|
|
|
4867
4875
|
const font = asset.font;
|
|
4868
4876
|
const active = asset.active?.font;
|
|
4869
4877
|
return {
|
|
4870
|
-
family: font?.family ??
|
|
4878
|
+
family: font?.family ?? CANVAS_CONFIG.DEFAULTS.fontFamily,
|
|
4871
4879
|
size: font?.size ?? 24,
|
|
4872
4880
|
weight: String(font?.weight ?? "400"),
|
|
4873
4881
|
baseColor: font?.color ?? "#ffffff",
|
|
4874
|
-
activeColor: active?.color ?? "#
|
|
4882
|
+
activeColor: active?.color ?? "#ffffff",
|
|
4875
4883
|
baseOpacity: font?.opacity ?? 1,
|
|
4876
4884
|
activeOpacity: active?.opacity ?? 1,
|
|
4877
4885
|
letterSpacing: asset.style?.letterSpacing ?? 0
|
|
@@ -5773,15 +5781,14 @@ async function createNodeRawEncoder(config, options) {
|
|
|
5773
5781
|
}
|
|
5774
5782
|
|
|
5775
5783
|
// src/core/rich-caption-renderer.ts
|
|
5776
|
-
var
|
|
5777
|
-
|
|
5778
|
-
"300":
|
|
5779
|
-
"400":
|
|
5780
|
-
"500":
|
|
5781
|
-
"600":
|
|
5782
|
-
"700":
|
|
5783
|
-
"800":
|
|
5784
|
-
"900": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtammT.ttf"
|
|
5784
|
+
var OPEN_SANS_FONT_URL = "https://fonts.gstatic.com/s/opensans/v44/mem8YaGs126MiZpBA-U1UpcaXcl0Aw.ttf";
|
|
5785
|
+
var OPEN_SANS_FONT_URLS = {
|
|
5786
|
+
"300": OPEN_SANS_FONT_URL,
|
|
5787
|
+
"400": OPEN_SANS_FONT_URL,
|
|
5788
|
+
"500": OPEN_SANS_FONT_URL,
|
|
5789
|
+
"600": OPEN_SANS_FONT_URL,
|
|
5790
|
+
"700": OPEN_SANS_FONT_URL,
|
|
5791
|
+
"800": OPEN_SANS_FONT_URL
|
|
5785
5792
|
};
|
|
5786
5793
|
var RichCaptionRenderer = class {
|
|
5787
5794
|
width;
|
|
@@ -5811,12 +5818,12 @@ var RichCaptionRenderer = class {
|
|
|
5811
5818
|
async initialize() {
|
|
5812
5819
|
this.fontRegistry = await FontRegistry.getSharedInstance(this.wasmBaseURL);
|
|
5813
5820
|
this.layoutEngine = new CaptionLayoutEngine(this.fontRegistry);
|
|
5814
|
-
const weightsToLoad = Object.keys(
|
|
5821
|
+
const weightsToLoad = Object.keys(OPEN_SANS_FONT_URLS);
|
|
5815
5822
|
const loadPromises = weightsToLoad.map(async (weight) => {
|
|
5816
|
-
const existingFace = await this.fontRegistry.getFace({ family: "
|
|
5823
|
+
const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
|
|
5817
5824
|
if (!existingFace) {
|
|
5818
|
-
const bytes = await loadFileOrHttpToArrayBuffer(
|
|
5819
|
-
await this.fontRegistry.registerFromBytes(bytes, { family: "
|
|
5825
|
+
const bytes = await loadFileOrHttpToArrayBuffer(OPEN_SANS_FONT_URLS[weight]);
|
|
5826
|
+
await this.fontRegistry.registerFromBytes(bytes, { family: "Open Sans", weight });
|
|
5820
5827
|
}
|
|
5821
5828
|
});
|
|
5822
5829
|
await Promise.all(loadPromises);
|
|
@@ -5860,7 +5867,7 @@ var RichCaptionRenderer = class {
|
|
|
5860
5867
|
maxLines: asset.maxLines ?? 2,
|
|
5861
5868
|
position: asset.position ?? "bottom",
|
|
5862
5869
|
fontSize: font?.size ?? 24,
|
|
5863
|
-
fontFamily: font?.family ?? "
|
|
5870
|
+
fontFamily: font?.family ?? "Open Sans",
|
|
5864
5871
|
fontWeight: String(font?.weight ?? "400"),
|
|
5865
5872
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
5866
5873
|
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
@@ -5953,7 +5960,15 @@ var RichCaptionRenderer = class {
|
|
|
5953
5960
|
const elapsed = performance.now() - totalStart;
|
|
5954
5961
|
const fps = framesProcessed / (elapsed / 1e3);
|
|
5955
5962
|
const eta = (schedule.totalFrames - framesProcessed) / fps * 1e3;
|
|
5956
|
-
this.logProgress(
|
|
5963
|
+
this.logProgress(
|
|
5964
|
+
pct,
|
|
5965
|
+
framesProcessed,
|
|
5966
|
+
schedule.totalFrames,
|
|
5967
|
+
i + 1,
|
|
5968
|
+
schedule.uniqueFrameCount,
|
|
5969
|
+
fps,
|
|
5970
|
+
eta
|
|
5971
|
+
);
|
|
5957
5972
|
}
|
|
5958
5973
|
if (i % 500 === 0 && i > 0) {
|
|
5959
5974
|
this.checkMemoryUsage();
|
|
@@ -6333,7 +6348,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6333
6348
|
}
|
|
6334
6349
|
}
|
|
6335
6350
|
const main = asset.font ?? {
|
|
6336
|
-
family: "
|
|
6351
|
+
family: "Open Sans",
|
|
6337
6352
|
weight: "400",
|
|
6338
6353
|
size: 48,
|
|
6339
6354
|
color: "#000000",
|
|
@@ -6562,6 +6577,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6562
6577
|
RichCaptionRenderer,
|
|
6563
6578
|
WordTimingStore,
|
|
6564
6579
|
arcToCubicBeziers,
|
|
6580
|
+
breakIntoLines,
|
|
6565
6581
|
calculateAnimationStatesForGroup,
|
|
6566
6582
|
commandsToPathString,
|
|
6567
6583
|
computeSimplePathBounds,
|
package/dist/entry.node.d.cts
CHANGED
|
@@ -670,6 +670,7 @@ declare class WordTimingStore {
|
|
|
670
670
|
}
|
|
671
671
|
declare function findWordAtTime(store: WordTimingStore, timeMs: number): number;
|
|
672
672
|
declare function groupWordsByPause(store: WordTimingStore, pauseThreshold?: number): number[][];
|
|
673
|
+
declare function breakIntoLines(wordWidths: number[], maxWidth: number, spaceWidth: number): number[][];
|
|
673
674
|
declare class CaptionLayoutEngine {
|
|
674
675
|
private fontRegistry;
|
|
675
676
|
private cache;
|
|
@@ -1314,4 +1315,4 @@ declare function createTextEngine(opts?: {
|
|
|
1314
1315
|
destroy(): void;
|
|
1315
1316
|
}>;
|
|
1316
1317
|
|
|
1317
|
-
export { type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectPlatform, detectSubtitleFormat, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|
|
1318
|
+
export { type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, breakIntoLines, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectPlatform, detectSubtitleFormat, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|
package/dist/entry.node.d.ts
CHANGED
|
@@ -670,6 +670,7 @@ declare class WordTimingStore {
|
|
|
670
670
|
}
|
|
671
671
|
declare function findWordAtTime(store: WordTimingStore, timeMs: number): number;
|
|
672
672
|
declare function groupWordsByPause(store: WordTimingStore, pauseThreshold?: number): number[][];
|
|
673
|
+
declare function breakIntoLines(wordWidths: number[], maxWidth: number, spaceWidth: number): number[][];
|
|
673
674
|
declare class CaptionLayoutEngine {
|
|
674
675
|
private fontRegistry;
|
|
675
676
|
private cache;
|
|
@@ -1314,4 +1315,4 @@ declare function createTextEngine(opts?: {
|
|
|
1314
1315
|
destroy(): void;
|
|
1315
1316
|
}>;
|
|
1316
1317
|
|
|
1317
|
-
export { type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectPlatform, detectSubtitleFormat, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|
|
1318
|
+
export { type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, breakIntoLines, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectPlatform, detectSubtitleFormat, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|
package/dist/entry.node.js
CHANGED
|
@@ -29,7 +29,7 @@ var CANVAS_CONFIG = {
|
|
|
29
29
|
width: 800,
|
|
30
30
|
height: 400,
|
|
31
31
|
pixelRatio: 2,
|
|
32
|
-
fontFamily: "
|
|
32
|
+
fontFamily: "Open Sans",
|
|
33
33
|
fontSize: 48,
|
|
34
34
|
color: "#ffffff",
|
|
35
35
|
textAlign: "center"
|
|
@@ -184,7 +184,7 @@ var wordTimingSchema = baseWordTimingSchema.extend({
|
|
|
184
184
|
confidence: z.number().min(0).max(1).optional()
|
|
185
185
|
});
|
|
186
186
|
var richCaptionFontSchema = z.object({
|
|
187
|
-
family: z.string().default(
|
|
187
|
+
family: z.string().default(CANVAS_CONFIG.DEFAULTS.fontFamily),
|
|
188
188
|
size: z.number().int().min(1).max(500).default(24),
|
|
189
189
|
weight: z.union([z.string(), z.number()]).default("400"),
|
|
190
190
|
color: z.string().regex(HEX6).default("#ffffff"),
|
|
@@ -193,7 +193,7 @@ var richCaptionFontSchema = z.object({
|
|
|
193
193
|
});
|
|
194
194
|
var richCaptionActiveSchema = baseCaptionActiveSchema.extend({
|
|
195
195
|
font: z.object({
|
|
196
|
-
color: z.string().regex(HEX6).default("#
|
|
196
|
+
color: z.string().regex(HEX6).default("#ffffff"),
|
|
197
197
|
background: z.string().regex(HEX6).optional(),
|
|
198
198
|
opacity: z.number().min(0).max(1).default(1)
|
|
199
199
|
}).optional(),
|
|
@@ -3939,7 +3939,7 @@ function groupWordsByPause(store, pauseThreshold = 500) {
|
|
|
3939
3939
|
}
|
|
3940
3940
|
return groups;
|
|
3941
3941
|
}
|
|
3942
|
-
function breakIntoLines(wordWidths, maxWidth,
|
|
3942
|
+
function breakIntoLines(wordWidths, maxWidth, spaceWidth) {
|
|
3943
3943
|
const lines = [];
|
|
3944
3944
|
let currentLine = [];
|
|
3945
3945
|
let currentWidth = 0;
|
|
@@ -3952,15 +3952,12 @@ function breakIntoLines(wordWidths, maxWidth, maxLines, spaceWidth) {
|
|
|
3952
3952
|
} else {
|
|
3953
3953
|
if (currentLine.length > 0) {
|
|
3954
3954
|
lines.push(currentLine);
|
|
3955
|
-
if (lines.length >= maxLines) {
|
|
3956
|
-
return lines;
|
|
3957
|
-
}
|
|
3958
3955
|
}
|
|
3959
3956
|
currentLine = [i];
|
|
3960
3957
|
currentWidth = wordWidth;
|
|
3961
3958
|
}
|
|
3962
3959
|
}
|
|
3963
|
-
if (currentLine.length > 0
|
|
3960
|
+
if (currentLine.length > 0) {
|
|
3964
3961
|
lines.push(currentLine);
|
|
3965
3962
|
}
|
|
3966
3963
|
return lines;
|
|
@@ -3993,6 +3990,13 @@ function transformText(text, transform) {
|
|
|
3993
3990
|
return text;
|
|
3994
3991
|
}
|
|
3995
3992
|
}
|
|
3993
|
+
function splitIntoChunks(arr, chunkSize) {
|
|
3994
|
+
const chunks = [];
|
|
3995
|
+
for (let i = 0; i < arr.length; i += chunkSize) {
|
|
3996
|
+
chunks.push(arr.slice(i, i + chunkSize));
|
|
3997
|
+
}
|
|
3998
|
+
return chunks;
|
|
3999
|
+
}
|
|
3996
4000
|
var CaptionLayoutEngine = class {
|
|
3997
4001
|
fontRegistry;
|
|
3998
4002
|
cache;
|
|
@@ -4079,31 +4083,34 @@ var CaptionLayoutEngine = class {
|
|
|
4079
4083
|
const spaceWord = await this.measureWord(" ", measurementConfig);
|
|
4080
4084
|
spaceWidth = spaceWord.width + config.wordSpacing;
|
|
4081
4085
|
}
|
|
4082
|
-
const groups = wordGroups.
|
|
4086
|
+
const groups = wordGroups.flatMap((indices) => {
|
|
4083
4087
|
const groupWidths = indices.map((i) => store.widths[i]);
|
|
4084
|
-
const
|
|
4088
|
+
const allLines = breakIntoLines(
|
|
4085
4089
|
groupWidths,
|
|
4086
4090
|
pixelMaxWidth,
|
|
4087
|
-
config.maxLines,
|
|
4088
4091
|
spaceWidth
|
|
4089
4092
|
);
|
|
4090
|
-
const
|
|
4091
|
-
|
|
4092
|
-
const
|
|
4093
|
+
const lineChunks = splitIntoChunks(allLines, config.maxLines);
|
|
4094
|
+
return lineChunks.map((chunkLines) => {
|
|
4095
|
+
const lines = chunkLines.map((lineWordIndices, lineIndex) => {
|
|
4096
|
+
const actualIndices = lineWordIndices.map((i) => indices[i]);
|
|
4097
|
+
const lineWidth = actualIndices.reduce((sum, idx) => sum + store.widths[idx], 0) + (actualIndices.length - 1) * spaceWidth;
|
|
4098
|
+
return {
|
|
4099
|
+
wordIndices: actualIndices,
|
|
4100
|
+
x: 0,
|
|
4101
|
+
y: lineIndex * config.fontSize * config.lineHeight,
|
|
4102
|
+
width: lineWidth,
|
|
4103
|
+
height: config.fontSize
|
|
4104
|
+
};
|
|
4105
|
+
});
|
|
4106
|
+
const allWordIndices = lines.flatMap((l) => l.wordIndices);
|
|
4093
4107
|
return {
|
|
4094
|
-
wordIndices:
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
height: config.fontSize
|
|
4108
|
+
wordIndices: allWordIndices,
|
|
4109
|
+
startTime: store.startTimes[allWordIndices[0]],
|
|
4110
|
+
endTime: store.endTimes[allWordIndices[allWordIndices.length - 1]],
|
|
4111
|
+
lines
|
|
4099
4112
|
};
|
|
4100
4113
|
});
|
|
4101
|
-
return {
|
|
4102
|
-
wordIndices: lines.flatMap((l) => l.wordIndices),
|
|
4103
|
-
startTime: store.startTimes[indices[0]],
|
|
4104
|
-
endTime: store.endTimes[indices[indices.length - 1]],
|
|
4105
|
-
lines
|
|
4106
|
-
};
|
|
4107
4114
|
});
|
|
4108
4115
|
const calculateGroupY = (group) => {
|
|
4109
4116
|
const totalHeight = group.lines.length * config.fontSize * config.lineHeight;
|
|
@@ -4478,11 +4485,11 @@ function extractFontConfig(asset) {
|
|
|
4478
4485
|
const font = asset.font;
|
|
4479
4486
|
const active = asset.active?.font;
|
|
4480
4487
|
return {
|
|
4481
|
-
family: font?.family ??
|
|
4488
|
+
family: font?.family ?? CANVAS_CONFIG.DEFAULTS.fontFamily,
|
|
4482
4489
|
size: font?.size ?? 24,
|
|
4483
4490
|
weight: String(font?.weight ?? "400"),
|
|
4484
4491
|
baseColor: font?.color ?? "#ffffff",
|
|
4485
|
-
activeColor: active?.color ?? "#
|
|
4492
|
+
activeColor: active?.color ?? "#ffffff",
|
|
4486
4493
|
baseOpacity: font?.opacity ?? 1,
|
|
4487
4494
|
activeOpacity: active?.opacity ?? 1,
|
|
4488
4495
|
letterSpacing: asset.style?.letterSpacing ?? 0
|
|
@@ -5384,15 +5391,14 @@ async function createNodeRawEncoder(config, options) {
|
|
|
5384
5391
|
}
|
|
5385
5392
|
|
|
5386
5393
|
// src/core/rich-caption-renderer.ts
|
|
5387
|
-
var
|
|
5388
|
-
|
|
5389
|
-
"300":
|
|
5390
|
-
"400":
|
|
5391
|
-
"500":
|
|
5392
|
-
"600":
|
|
5393
|
-
"700":
|
|
5394
|
-
"800":
|
|
5395
|
-
"900": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtammT.ttf"
|
|
5394
|
+
var OPEN_SANS_FONT_URL = "https://fonts.gstatic.com/s/opensans/v44/mem8YaGs126MiZpBA-U1UpcaXcl0Aw.ttf";
|
|
5395
|
+
var OPEN_SANS_FONT_URLS = {
|
|
5396
|
+
"300": OPEN_SANS_FONT_URL,
|
|
5397
|
+
"400": OPEN_SANS_FONT_URL,
|
|
5398
|
+
"500": OPEN_SANS_FONT_URL,
|
|
5399
|
+
"600": OPEN_SANS_FONT_URL,
|
|
5400
|
+
"700": OPEN_SANS_FONT_URL,
|
|
5401
|
+
"800": OPEN_SANS_FONT_URL
|
|
5396
5402
|
};
|
|
5397
5403
|
var RichCaptionRenderer = class {
|
|
5398
5404
|
width;
|
|
@@ -5422,12 +5428,12 @@ var RichCaptionRenderer = class {
|
|
|
5422
5428
|
async initialize() {
|
|
5423
5429
|
this.fontRegistry = await FontRegistry.getSharedInstance(this.wasmBaseURL);
|
|
5424
5430
|
this.layoutEngine = new CaptionLayoutEngine(this.fontRegistry);
|
|
5425
|
-
const weightsToLoad = Object.keys(
|
|
5431
|
+
const weightsToLoad = Object.keys(OPEN_SANS_FONT_URLS);
|
|
5426
5432
|
const loadPromises = weightsToLoad.map(async (weight) => {
|
|
5427
|
-
const existingFace = await this.fontRegistry.getFace({ family: "
|
|
5433
|
+
const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
|
|
5428
5434
|
if (!existingFace) {
|
|
5429
|
-
const bytes = await loadFileOrHttpToArrayBuffer(
|
|
5430
|
-
await this.fontRegistry.registerFromBytes(bytes, { family: "
|
|
5435
|
+
const bytes = await loadFileOrHttpToArrayBuffer(OPEN_SANS_FONT_URLS[weight]);
|
|
5436
|
+
await this.fontRegistry.registerFromBytes(bytes, { family: "Open Sans", weight });
|
|
5431
5437
|
}
|
|
5432
5438
|
});
|
|
5433
5439
|
await Promise.all(loadPromises);
|
|
@@ -5471,7 +5477,7 @@ var RichCaptionRenderer = class {
|
|
|
5471
5477
|
maxLines: asset.maxLines ?? 2,
|
|
5472
5478
|
position: asset.position ?? "bottom",
|
|
5473
5479
|
fontSize: font?.size ?? 24,
|
|
5474
|
-
fontFamily: font?.family ?? "
|
|
5480
|
+
fontFamily: font?.family ?? "Open Sans",
|
|
5475
5481
|
fontWeight: String(font?.weight ?? "400"),
|
|
5476
5482
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
5477
5483
|
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
@@ -5564,7 +5570,15 @@ var RichCaptionRenderer = class {
|
|
|
5564
5570
|
const elapsed = performance.now() - totalStart;
|
|
5565
5571
|
const fps = framesProcessed / (elapsed / 1e3);
|
|
5566
5572
|
const eta = (schedule.totalFrames - framesProcessed) / fps * 1e3;
|
|
5567
|
-
this.logProgress(
|
|
5573
|
+
this.logProgress(
|
|
5574
|
+
pct,
|
|
5575
|
+
framesProcessed,
|
|
5576
|
+
schedule.totalFrames,
|
|
5577
|
+
i + 1,
|
|
5578
|
+
schedule.uniqueFrameCount,
|
|
5579
|
+
fps,
|
|
5580
|
+
eta
|
|
5581
|
+
);
|
|
5568
5582
|
}
|
|
5569
5583
|
if (i % 500 === 0 && i > 0) {
|
|
5570
5584
|
this.checkMemoryUsage();
|
|
@@ -5944,7 +5958,7 @@ async function createTextEngine(opts = {}) {
|
|
|
5944
5958
|
}
|
|
5945
5959
|
}
|
|
5946
5960
|
const main = asset.font ?? {
|
|
5947
|
-
family: "
|
|
5961
|
+
family: "Open Sans",
|
|
5948
5962
|
weight: "400",
|
|
5949
5963
|
size: 48,
|
|
5950
5964
|
color: "#000000",
|
|
@@ -6172,6 +6186,7 @@ export {
|
|
|
6172
6186
|
RichCaptionRenderer,
|
|
6173
6187
|
WordTimingStore,
|
|
6174
6188
|
arcToCubicBeziers,
|
|
6189
|
+
breakIntoLines,
|
|
6175
6190
|
calculateAnimationStatesForGroup,
|
|
6176
6191
|
commandsToPathString,
|
|
6177
6192
|
computeSimplePathBounds,
|
package/dist/entry.web.d.ts
CHANGED
|
@@ -670,6 +670,7 @@ declare class WordTimingStore {
|
|
|
670
670
|
}
|
|
671
671
|
declare function findWordAtTime(store: WordTimingStore, timeMs: number): number;
|
|
672
672
|
declare function groupWordsByPause(store: WordTimingStore, pauseThreshold?: number): number[][];
|
|
673
|
+
declare function breakIntoLines(wordWidths: number[], maxWidth: number, spaceWidth: number): number[][];
|
|
673
674
|
declare class CaptionLayoutEngine {
|
|
674
675
|
private fontRegistry;
|
|
675
676
|
private cache;
|
|
@@ -1259,4 +1260,4 @@ declare function createTextEngine(opts?: {
|
|
|
1259
1260
|
destroy(): void;
|
|
1260
1261
|
}>;
|
|
1261
1262
|
|
|
1262
|
-
export { type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, MediaRecorderFallback, type MoveToCommand, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, WebCodecsEncoder, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createMediaRecorderFallback, createTextEngine, createVideoEncoder, createWebCodecsEncoder, createWebPainter, detectPlatform, detectSubtitleFormat, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, initResvg, isDrawCaptionWordOp, isMediaRecorderSupported, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|
|
1263
|
+
export { type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, MediaRecorderFallback, type MoveToCommand, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, WebCodecsEncoder, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, breakIntoLines, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createMediaRecorderFallback, createTextEngine, createVideoEncoder, createWebCodecsEncoder, createWebPainter, detectPlatform, detectSubtitleFormat, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, initResvg, isDrawCaptionWordOp, isMediaRecorderSupported, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|