@bendyline/squisq-video 2.3.12 → 2.3.14
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/index.d.ts +21 -2
- package/dist/index.js +28 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MediaScheduleOptions, Doc, Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, ViewportPreset } from '@bendyline/squisq/schemas';
|
|
1
|
+
import { MediaScheduleOptions, Doc, Theme, MotionSpec, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, ViewportPreset } from '@bendyline/squisq/schemas';
|
|
2
2
|
export { fetchFile } from '@ffmpeg/util';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -263,6 +263,8 @@ interface RenderHtmlOptions {
|
|
|
263
263
|
captionStyle?: 'standard' | 'social';
|
|
264
264
|
/** Theme override for the capture player. Omitted values resolve from the Doc. */
|
|
265
265
|
theme?: Theme;
|
|
266
|
+
/** Motion profile override. Omitted values resolve from the Doc, then the theme. */
|
|
267
|
+
motion?: MotionSpec | null;
|
|
266
268
|
/** Player-level video placement override. Omitted values resolve from Doc frontmatter. */
|
|
267
269
|
videoPresentation?: VideoPresentation;
|
|
268
270
|
/** Picture-in-picture size override. Omitted values resolve from Doc frontmatter. */
|
|
@@ -510,4 +512,21 @@ declare function ffmpegGifOutputArgs(options: GifOutputOptions): string[];
|
|
|
510
512
|
*/
|
|
511
513
|
declare function framesToMp4Wasm(frames: Uint8Array[], audio: Uint8Array | null, options?: VideoExportOptions): Promise<EncoderResult>;
|
|
512
514
|
|
|
513
|
-
|
|
515
|
+
/**
|
|
516
|
+
* Frame clock — the one place that turns a frame index into a timeline time.
|
|
517
|
+
*
|
|
518
|
+
* Every offline capture path (CLI pipe/memory transports, browser export)
|
|
519
|
+
* must agree on which instant a frame shows, otherwise a resumed or
|
|
520
|
+
* deduplicated render drifts from a fresh one. `i / fps` in floating point is
|
|
521
|
+
* not exactly reproducible across code paths, so the time is rounded to a
|
|
522
|
+
* microsecond: `frameTimeSeconds(370, 30)` equals `frameTimeSeconds(37, 3)`.
|
|
523
|
+
*
|
|
524
|
+
* Contract: a frame's pixels are a function of its time only. Consumers seek
|
|
525
|
+
* the player to this time and pause every animation before capturing.
|
|
526
|
+
*/
|
|
527
|
+
/** Timeline second shown by frame `index` at `fps`, rounded to a microsecond. */
|
|
528
|
+
declare function frameTimeSeconds(index: number, fps: number): number;
|
|
529
|
+
/** Number of frames needed to cover `durationSeconds` at `fps` (partial frames round up). */
|
|
530
|
+
declare function frameCountFor(durationSeconds: number, fps: number): number;
|
|
531
|
+
|
|
532
|
+
export { type AudioTimelineClip, type ComputeAudioTimelineOptions, DASHBOARD_RESOLUTIONS, DEFAULT_DASHBOARD_RESOLUTION, type DashboardResolutionId, type DashboardResolutionPreset, type EncoderResult, FFMPEG_WASM_SETUP_HINT, type FfmpegWasmLoadConfig, type GifDither, type GifFilterOptions, type GifOutputOptions, MAX_DASHBOARD_IMAGE_DIMENSION, MAX_DASHBOARD_IMAGE_PIXELS, MIN_DASHBOARD_IMAGE_DIMENSION, ORIENTATION_DIMENSIONS, QUALITY_PRESETS, type QualityPreset, type RenderHtmlOptions, type ResolveDashboardDimensionsInput, type ResolvedDashboardDimensions, type VideoExportOptions, type VideoOrientation, type VideoQuality, audioBitrateArg, bitrateForQuality, computeAudioTimeline, dashboardFamilyForDimensions, ffmpegAudioMuxArgs, ffmpegGifFilterGraph, ffmpegGifOutputArgs, ffmpegGifPaletteApplicationArgs, ffmpegGifPaletteApplicationGraph, ffmpegGifPaletteGenerationFilter, ffmpegVideoQualityArgs, frameCountFor, frameTimeSeconds, framesToMp4Wasm, generateRenderHtml, resolveDashboardDimensions, resolveDimensions, resolveFfmpegWasmLoad, validateDashboardImageDimensions, validateVideoExportOptions };
|
package/dist/index.js
CHANGED
|
@@ -196,6 +196,7 @@ function generateRenderHtml(doc, options) {
|
|
|
196
196
|
height = 1080,
|
|
197
197
|
captionStyle,
|
|
198
198
|
theme,
|
|
199
|
+
motion,
|
|
199
200
|
videoPresentation,
|
|
200
201
|
pipSize,
|
|
201
202
|
pipShape,
|
|
@@ -222,9 +223,14 @@ function generateRenderHtml(doc, options) {
|
|
|
222
223
|
const imageMapJson = escapeForScript(JSON.stringify(imageMap));
|
|
223
224
|
const audioMapJson = hasAudio ? escapeForScript(JSON.stringify(audioMap)) : "null";
|
|
224
225
|
const playerOptionLines = [
|
|
226
|
+
// Always pin the composed viewport to the export size. The page also
|
|
227
|
+
// pins #squisq-root to it, but an explicit viewport is what stops
|
|
228
|
+
// portrait/custom renders from falling back to the landscape preset.
|
|
229
|
+
` viewport: ${JSON.stringify({ width, height })}`,
|
|
225
230
|
` animationsEnabled: ${JSON.stringify(animationsEnabled)}`,
|
|
226
231
|
captionStyle ? ` captionStyle: ${JSON.stringify(captionStyle)}` : null,
|
|
227
232
|
theme ? ` theme: ${escapeForScript(JSON.stringify(theme))}` : null,
|
|
233
|
+
motion != null ? ` motion: ${escapeForScript(JSON.stringify(motion))}` : null,
|
|
228
234
|
videoPresentation ? ` videoPresentation: ${JSON.stringify(videoPresentation)}` : null,
|
|
229
235
|
pipSize ? ` pipSize: ${JSON.stringify(pipSize)}` : null,
|
|
230
236
|
pipShape ? ` pipShape: ${JSON.stringify(pipShape)}` : null,
|
|
@@ -512,6 +518,26 @@ async function framesToMp4Wasm(frames, audio, options = {}) {
|
|
|
512
518
|
ffmpeg.terminate();
|
|
513
519
|
}
|
|
514
520
|
}
|
|
521
|
+
|
|
522
|
+
// src/frameClock.ts
|
|
523
|
+
function frameTimeSeconds(index, fps) {
|
|
524
|
+
if (!Number.isSafeInteger(index) || index < 0) {
|
|
525
|
+
throw new RangeError("Frame index must be a non-negative integer.");
|
|
526
|
+
}
|
|
527
|
+
if (!Number.isFinite(fps) || fps <= 0) {
|
|
528
|
+
throw new RangeError("Frames per second must be a positive number.");
|
|
529
|
+
}
|
|
530
|
+
return Math.round(index * 1e6 / fps) / 1e6;
|
|
531
|
+
}
|
|
532
|
+
function frameCountFor(durationSeconds, fps) {
|
|
533
|
+
if (!Number.isFinite(durationSeconds) || durationSeconds < 0) {
|
|
534
|
+
throw new RangeError("Duration must be a non-negative number of seconds.");
|
|
535
|
+
}
|
|
536
|
+
if (!Number.isFinite(fps) || fps <= 0) {
|
|
537
|
+
throw new RangeError("Frames per second must be a positive number.");
|
|
538
|
+
}
|
|
539
|
+
return Math.max(0, Math.ceil(durationSeconds * fps - 1e-9)) + 0;
|
|
540
|
+
}
|
|
515
541
|
export {
|
|
516
542
|
DASHBOARD_RESOLUTIONS,
|
|
517
543
|
DEFAULT_DASHBOARD_RESOLUTION,
|
|
@@ -533,6 +559,8 @@ export {
|
|
|
533
559
|
ffmpegGifPaletteApplicationGraph,
|
|
534
560
|
ffmpegGifPaletteGenerationFilter,
|
|
535
561
|
ffmpegVideoQualityArgs,
|
|
562
|
+
frameCountFor,
|
|
563
|
+
frameTimeSeconds,
|
|
536
564
|
framesToMp4Wasm,
|
|
537
565
|
generateRenderHtml,
|
|
538
566
|
resolveDashboardDimensions,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/squisq-video",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.14",
|
|
4
4
|
"description": "Cross-runtime video and animated-GIF helpers with browser-based ffmpeg.wasm encoding for Squisq documents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bendyline",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"typecheck": "tsc --noEmit"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@bendyline/squisq": "2.11.
|
|
51
|
+
"@bendyline/squisq": "2.11.10",
|
|
52
52
|
"@ffmpeg/ffmpeg": "0.12.15",
|
|
53
53
|
"@ffmpeg/util": "0.12.2"
|
|
54
54
|
},
|