@bendyline/squisq-video 2.3.9 → 2.3.11
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 +17 -1
- package/dist/index.js +22 -2
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Doc, Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, ViewportPreset } from '@bendyline/squisq/schemas';
|
|
1
|
+
import { MediaScheduleOptions, Doc, Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, ViewportPreset } from '@bendyline/squisq/schemas';
|
|
2
2
|
export { fetchFile } from '@ffmpeg/util';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -191,6 +191,16 @@ interface AudioTimelineClip {
|
|
|
191
191
|
* authored audio/narration source, whose decode failure remains an error.
|
|
192
192
|
*/
|
|
193
193
|
sourceKind?: 'video';
|
|
194
|
+
/** Clip gain in dB (media-edit recipe). Omitted means unity. */
|
|
195
|
+
gainDb?: number;
|
|
196
|
+
/**
|
|
197
|
+
* Linear fade-in over the first seconds of this clip. Also set to a few
|
|
198
|
+
* milliseconds on the inner edges of a cut clip's segments, so a cut never
|
|
199
|
+
* clicks.
|
|
200
|
+
*/
|
|
201
|
+
fadeInSec?: number;
|
|
202
|
+
/** Linear fade-out over the last seconds of this clip (see {@link fadeInSec}). */
|
|
203
|
+
fadeOutSec?: number;
|
|
194
204
|
}
|
|
195
205
|
interface ComputeAudioTimelineOptions {
|
|
196
206
|
/**
|
|
@@ -199,6 +209,12 @@ interface ComputeAudioTimelineOptions {
|
|
|
199
209
|
* explicitly retain the legacy audio-only behavior.
|
|
200
210
|
*/
|
|
201
211
|
includeVideoAudio?: boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Processed-audio lookup forwarded to `resolveMediaSchedule`. With a render
|
|
214
|
+
* available, an edited clip's audio comes from its render (and a video's own
|
|
215
|
+
* audio track is left out). Omitted → original audio everywhere.
|
|
216
|
+
*/
|
|
217
|
+
processedAudio?: MediaScheduleOptions['processedAudio'];
|
|
202
218
|
}
|
|
203
219
|
/**
|
|
204
220
|
* Flatten a doc's narration + timed-media audio into absolute-timed clips.
|
package/dist/index.js
CHANGED
|
@@ -66,6 +66,20 @@ function resolveFfmpegWasmLoad(config, context, defaults) {
|
|
|
66
66
|
// src/audioTimeline.ts
|
|
67
67
|
import { resolveMediaSchedule } from "@bendyline/squisq/schemas";
|
|
68
68
|
import { flattenRenderableBlocks, materializeBlockLayers } from "@bendyline/squisq/doc";
|
|
69
|
+
var CUT_EDGE_FADE_SEC = 0.01;
|
|
70
|
+
function clipDynamics(clip) {
|
|
71
|
+
const out = {};
|
|
72
|
+
if (clip.gain != null && clip.gain !== 0) out.gainDb = clip.gain;
|
|
73
|
+
let fadeIn = clip.fadeIn ?? 0;
|
|
74
|
+
let fadeOut = clip.fadeOut ?? 0;
|
|
75
|
+
if (clip.segment) {
|
|
76
|
+
if (clip.segment.index > 0) fadeIn = Math.max(fadeIn, CUT_EDGE_FADE_SEC);
|
|
77
|
+
if (clip.segment.index < clip.segment.count - 1) fadeOut = Math.max(fadeOut, CUT_EDGE_FADE_SEC);
|
|
78
|
+
}
|
|
79
|
+
if (fadeIn > 0) out.fadeInSec = fadeIn;
|
|
80
|
+
if (fadeOut > 0) out.fadeOutSec = fadeOut;
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
69
83
|
function computeAudioTimeline(doc, coverPreRoll = 0, options = {}) {
|
|
70
84
|
const preRoll = safeSeconds(coverPreRoll);
|
|
71
85
|
const includeVideoAudio = options.includeVideoAudio ?? true;
|
|
@@ -78,8 +92,13 @@ function computeAudioTimeline(doc, coverPreRoll = 0, options = {}) {
|
|
|
78
92
|
}
|
|
79
93
|
cursor += durationSec;
|
|
80
94
|
}
|
|
81
|
-
|
|
95
|
+
const schedule = resolveMediaSchedule(
|
|
96
|
+
doc,
|
|
97
|
+
options.processedAudio ? { processedAudio: options.processedAudio } : void 0
|
|
98
|
+
);
|
|
99
|
+
for (const clip of schedule) {
|
|
82
100
|
if (clip.kind !== "audio" && !includeVideoAudio) continue;
|
|
101
|
+
if (clip.kind === "video" && clip.audioMuted) continue;
|
|
83
102
|
if (!Number.isFinite(clip.absoluteStart) || !Number.isFinite(clip.absoluteEnd)) continue;
|
|
84
103
|
const durationSec = Math.max(0, clip.absoluteEnd - clip.absoluteStart);
|
|
85
104
|
if (durationSec <= 0 || !clip.src) continue;
|
|
@@ -88,7 +107,8 @@ function computeAudioTimeline(doc, coverPreRoll = 0, options = {}) {
|
|
|
88
107
|
startSec: safeSeconds(clip.absoluteStart) + preRoll,
|
|
89
108
|
sourceInSec: safeSeconds(clip.sourceIn),
|
|
90
109
|
durationSec,
|
|
91
|
-
...clip.kind === "video" ? { sourceKind: "video" } : {}
|
|
110
|
+
...clip.kind === "video" ? { sourceKind: "video" } : {},
|
|
111
|
+
...clipDynamics(clip)
|
|
92
112
|
});
|
|
93
113
|
}
|
|
94
114
|
if (includeVideoAudio) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/squisq-video",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.11",
|
|
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.8",
|
|
52
52
|
"@ffmpeg/ffmpeg": "0.12.15",
|
|
53
53
|
"@ffmpeg/util": "0.12.2"
|
|
54
54
|
},
|