@bendyline/squisq-video-react 2.2.5 → 2.2.7
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/{chunk-ZQJBUX75.js → chunk-2XACUF6E.js} +15 -1
- package/dist/{chunk-NZYFSB2T.js → chunk-NX34XGLL.js} +4 -1
- package/dist/{chunk-U2TST3MN.js → chunk-SO656KT7.js} +25 -15
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +3 -3
- package/dist/encoder/index.js +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/{useVideoExport-Okwrf8gg.d.ts → useVideoExport-DKpdXZ0o.d.ts} +2 -2
- package/package.json +4 -4
|
@@ -172,15 +172,27 @@ async function renderAudioTimeline(clips, buffers, totalDurationSec, sampleRate
|
|
|
172
172
|
const length = Math.max(1, Math.ceil(totalDurationSec * sampleRate));
|
|
173
173
|
const ctx = new Ctor(channels, length, sampleRate);
|
|
174
174
|
const decoded = /* @__PURE__ */ new Map();
|
|
175
|
+
const decodeFailures = [];
|
|
175
176
|
for (const [src, data] of buffers) {
|
|
176
177
|
try {
|
|
177
178
|
decoded.set(src, await ctx.decodeAudioData(data.slice(0)));
|
|
178
179
|
} catch {
|
|
180
|
+
decodeFailures.push(src);
|
|
179
181
|
}
|
|
180
182
|
}
|
|
183
|
+
const requiredFailures = decodeFailures.filter(
|
|
184
|
+
(src) => clips.some((clip) => clip.src === src && clip.sourceKind !== "video")
|
|
185
|
+
);
|
|
186
|
+
if (requiredFailures.length > 0) {
|
|
187
|
+
throw new Error(`No decodable audio track was found in: ${requiredFailures.join(", ")}`);
|
|
188
|
+
}
|
|
189
|
+
let scheduledNodes = 0;
|
|
181
190
|
for (const clip of clips) {
|
|
182
191
|
const buffer = decoded.get(clip.src);
|
|
183
|
-
if (!buffer)
|
|
192
|
+
if (!buffer) {
|
|
193
|
+
if (clip.sourceKind === "video") continue;
|
|
194
|
+
throw new Error(`Audio source was not decoded: ${clip.src}`);
|
|
195
|
+
}
|
|
184
196
|
const node = ctx.createBufferSource();
|
|
185
197
|
node.buffer = buffer;
|
|
186
198
|
node.connect(ctx.destination);
|
|
@@ -188,7 +200,9 @@ async function renderAudioTimeline(clips, buffers, totalDurationSec, sampleRate
|
|
|
188
200
|
const offset = Math.max(0, clip.sourceInSec);
|
|
189
201
|
const duration = Math.max(0, clip.durationSec);
|
|
190
202
|
node.start(when, offset, duration);
|
|
203
|
+
scheduledNodes++;
|
|
191
204
|
}
|
|
205
|
+
if (scheduledNodes === 0) return null;
|
|
192
206
|
return ctx.startRendering();
|
|
193
207
|
}
|
|
194
208
|
async function encodeAacTrack(audioBuffer, sink, bitrate) {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
supportsWebCodecs,
|
|
11
11
|
supportsWebCodecsAac,
|
|
12
12
|
supportsWebCodecsH264
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-2XACUF6E.js";
|
|
14
14
|
|
|
15
15
|
// src/hooks/useFrameCapture.ts
|
|
16
16
|
import { createElement } from "react";
|
|
@@ -1168,6 +1168,9 @@ function useVideoExport(options = {}) {
|
|
|
1168
1168
|
totalAudioDur,
|
|
1169
1169
|
EXPORT_AUDIO_SAMPLE_RATE
|
|
1170
1170
|
);
|
|
1171
|
+
if (!renderedAudio) {
|
|
1172
|
+
audioReasonLocal = "No included video source contained a decodable audio track.";
|
|
1173
|
+
}
|
|
1171
1174
|
}
|
|
1172
1175
|
} catch (audioErr) {
|
|
1173
1176
|
renderedAudio = null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useVideoExport
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NX34XGLL.js";
|
|
4
4
|
|
|
5
5
|
// src/VideoExportModal.tsx
|
|
6
6
|
import { useState, useCallback, useId, useRef } from "react";
|
|
@@ -179,9 +179,7 @@ function VideoExportModal({
|
|
|
179
179
|
const [animationsEnabled, setAnimationsEnabled] = useState(
|
|
180
180
|
defaultConfig?.animationsEnabled ?? initialOutputFormat === "mp4"
|
|
181
181
|
);
|
|
182
|
-
const [
|
|
183
|
-
defaultConfig?.audioPolicy ?? "require"
|
|
184
|
-
);
|
|
182
|
+
const [includeAudio, setIncludeAudio] = useState(defaultConfig?.audioPolicy !== "omit");
|
|
185
183
|
const palette = {
|
|
186
184
|
...VIDEO_EXPORT_PALETTES[colorScheme],
|
|
187
185
|
...uiPalette
|
|
@@ -268,7 +266,7 @@ function VideoExportModal({
|
|
|
268
266
|
fps,
|
|
269
267
|
orientation,
|
|
270
268
|
captionMode,
|
|
271
|
-
audioPolicy,
|
|
269
|
+
audioPolicy: includeAudio ? "require" : "omit",
|
|
272
270
|
images,
|
|
273
271
|
audio,
|
|
274
272
|
mediaProvider,
|
|
@@ -284,7 +282,7 @@ function VideoExportModal({
|
|
|
284
282
|
fps,
|
|
285
283
|
orientation,
|
|
286
284
|
captionMode,
|
|
287
|
-
|
|
285
|
+
includeAudio,
|
|
288
286
|
images,
|
|
289
287
|
audio,
|
|
290
288
|
mediaProvider,
|
|
@@ -443,16 +441,28 @@ function VideoExportModal({
|
|
|
443
441
|
outputFormat === "mp4" && /* @__PURE__ */ jsxs("div", { children: [
|
|
444
442
|
/* @__PURE__ */ jsx("label", { style: themedLabelStyle, children: "Audio" }),
|
|
445
443
|
/* @__PURE__ */ jsxs(
|
|
446
|
-
"
|
|
444
|
+
"label",
|
|
447
445
|
{
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
446
|
+
style: {
|
|
447
|
+
display: "flex",
|
|
448
|
+
alignItems: "center",
|
|
449
|
+
gap: 8,
|
|
450
|
+
marginBottom: 12,
|
|
451
|
+
fontSize: 14,
|
|
452
|
+
color: palette.text,
|
|
453
|
+
cursor: "pointer"
|
|
454
|
+
},
|
|
452
455
|
children: [
|
|
453
|
-
/* @__PURE__ */ jsx(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
+
/* @__PURE__ */ jsx(
|
|
457
|
+
"input",
|
|
458
|
+
{
|
|
459
|
+
type: "checkbox",
|
|
460
|
+
"aria-label": "Include audio",
|
|
461
|
+
checked: includeAudio,
|
|
462
|
+
onChange: (e) => setIncludeAudio(e.target.checked)
|
|
463
|
+
}
|
|
464
|
+
),
|
|
465
|
+
"Include audio"
|
|
456
466
|
]
|
|
457
467
|
}
|
|
458
468
|
)
|
|
@@ -575,7 +585,7 @@ function VideoExportModal({
|
|
|
575
585
|
(fileSize / (1024 * 1024)).toFixed(1),
|
|
576
586
|
" MB"
|
|
577
587
|
] }),
|
|
578
|
-
completedOutputFormat === "gif" ? /* @__PURE__ */ jsx("p", { style: { fontSize: 12, color: palette.muted, margin: "0 0 4px 0" }, children: "Animated GIF does not include audio." }) : audioIncluded ? /* @__PURE__ */ jsx("p", { style: { fontSize: 12, color: palette.success, margin: "0 0 4px 0" }, children: "Audio included \u2713" }) : /* @__PURE__ */ jsxs("p", { style: { fontSize: 12, color: palette.muted, margin: "0 0 4px 0" }, children: [
|
|
588
|
+
completedOutputFormat === "gif" ? /* @__PURE__ */ jsx("p", { style: { fontSize: 12, color: palette.muted, margin: "0 0 4px 0" }, children: "Animated GIF does not include audio." }) : !includeAudio ? /* @__PURE__ */ jsx("p", { style: { fontSize: 12, color: palette.muted, margin: "0 0 4px 0" }, children: "Audio excluded" }) : audioIncluded ? /* @__PURE__ */ jsx("p", { style: { fontSize: 12, color: palette.success, margin: "0 0 4px 0" }, children: "Audio included \u2713" }) : /* @__PURE__ */ jsxs("p", { style: { fontSize: 12, color: palette.muted, margin: "0 0 4px 0" }, children: [
|
|
579
589
|
"Video only",
|
|
580
590
|
audioSkippedReason ? ` \u2014 ${audioSkippedReason}` : ""
|
|
581
591
|
] }),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { Doc, MediaProvider } from '@bendyline/squisq/schemas';
|
|
3
|
-
import { a as VideoExportConfig } from '../useVideoExport-
|
|
3
|
+
import { a as VideoExportConfig } from '../useVideoExport-DKpdXZ0o.js';
|
|
4
4
|
import '@bendyline/squisq/markdown';
|
|
5
5
|
import '@bendyline/squisq-video';
|
|
6
6
|
import '@bendyline/squisq-react';
|
package/dist/components/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VideoExportButton,
|
|
3
3
|
VideoExportModal
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-SO656KT7.js";
|
|
5
|
+
import "../chunk-NX34XGLL.js";
|
|
6
|
+
import "../chunk-2XACUF6E.js";
|
|
7
7
|
import "../chunk-MEPETH5V.js";
|
|
8
8
|
export {
|
|
9
9
|
VideoExportButton,
|
package/dist/encoder/index.js
CHANGED
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { D as DEFAULT_VIDEO_COVER_PRE_ROLL_SECONDS, R as ResolvedVideoExportCover, U as UseVideoExportOptions, V as VideoAudioPolicy, a as VideoExportConfig, b as VideoExportFramePreview, c as VideoExportResult, d as VideoExportState, e as VideoOutputFormat, r as resolveVideoExportCover, u as useVideoExport } from '../useVideoExport-
|
|
1
|
+
export { D as DEFAULT_VIDEO_COVER_PRE_ROLL_SECONDS, R as ResolvedVideoExportCover, U as UseVideoExportOptions, V as VideoAudioPolicy, a as VideoExportConfig, b as VideoExportFramePreview, c as VideoExportResult, d as VideoExportState, e as VideoOutputFormat, r as resolveVideoExportCover, u as useVideoExport } from '../useVideoExport-DKpdXZ0o.js';
|
|
2
2
|
import { Doc } from '@bendyline/squisq/schemas';
|
|
3
3
|
import { RenderHtmlOptions } from '@bendyline/squisq-video';
|
|
4
4
|
import { CaptionMode } from '@bendyline/squisq-react';
|
package/dist/hooks/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
resolveVideoExportCover,
|
|
4
4
|
useFrameCapture,
|
|
5
5
|
useVideoExport
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-NX34XGLL.js";
|
|
7
|
+
import "../chunk-2XACUF6E.js";
|
|
8
8
|
import "../chunk-MEPETH5V.js";
|
|
9
9
|
export {
|
|
10
10
|
DEFAULT_VIDEO_COVER_PRE_ROLL_SECONDS,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { VideoExportButton, VideoExportButtonProps, VideoExportModal, VideoExportModalProps, VideoExportPalette } from './components/index.js';
|
|
2
|
-
export { D as DEFAULT_VIDEO_COVER_PRE_ROLL_SECONDS, R as ResolvedVideoExportCover, U as UseVideoExportOptions, V as VideoAudioPolicy, a as VideoExportConfig, b as VideoExportFramePreview, c as VideoExportResult, d as VideoExportState, e as VideoOutputFormat, r as resolveVideoExportCover, u as useVideoExport } from './useVideoExport-
|
|
2
|
+
export { D as DEFAULT_VIDEO_COVER_PRE_ROLL_SECONDS, R as ResolvedVideoExportCover, U as UseVideoExportOptions, V as VideoAudioPolicy, a as VideoExportConfig, b as VideoExportFramePreview, c as VideoExportResult, d as VideoExportState, e as VideoOutputFormat, r as resolveVideoExportCover, u as useVideoExport } from './useVideoExport-DKpdXZ0o.js';
|
|
3
3
|
export { FrameCaptureHandle, FrameCaptureOptions, FrameCaptureRenderOptions, useFrameCapture } from './hooks/index.js';
|
|
4
4
|
export { E as EncoderConfig, a as EncoderFrameSource, M as MainThreadEncoder, c as createEncoder, s as supportsWebCodecs, b as supportsWebCodecsH264 } from './mainThreadEncoder-BgcFyYvO.js';
|
|
5
5
|
export { FfmpegWasmLoadConfig } from '@bendyline/squisq-video';
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VideoExportButton,
|
|
3
3
|
VideoExportModal
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SO656KT7.js";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_VIDEO_COVER_PRE_ROLL_SECONDS,
|
|
7
7
|
resolveVideoExportCover,
|
|
8
8
|
useFrameCapture,
|
|
9
9
|
useVideoExport
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-NX34XGLL.js";
|
|
11
11
|
import {
|
|
12
12
|
createEncoder,
|
|
13
13
|
supportsWebCodecs,
|
|
14
14
|
supportsWebCodecsAac,
|
|
15
15
|
supportsWebCodecsH264
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2XACUF6E.js";
|
|
17
17
|
import "./chunk-MEPETH5V.js";
|
|
18
18
|
export {
|
|
19
19
|
DEFAULT_VIDEO_COVER_PRE_ROLL_SECONDS,
|
|
@@ -119,8 +119,8 @@ interface VideoExportResult {
|
|
|
119
119
|
/**
|
|
120
120
|
* Why audio is absent, when `audioIncluded` is false. `null` means the doc
|
|
121
121
|
* simply had no audio (not a failure); a non-null string explains a genuine
|
|
122
|
-
* capability shortfall or runtime failure.
|
|
123
|
-
* export
|
|
122
|
+
* capability shortfall or runtime failure. The default `require` policy
|
|
123
|
+
* fails the export instead of returning a misleading video-only success.
|
|
124
124
|
*/
|
|
125
125
|
audioSkippedReason: string | null;
|
|
126
126
|
/** Error message (populated when state === 'error') */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/squisq-video-react",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.7",
|
|
4
4
|
"description": "React components for browser-based MP4 and animated-GIF export of Squisq documents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bendyline",
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@bendyline/squisq": "2.4.
|
|
69
|
-
"@bendyline/squisq-video": "2.2.
|
|
70
|
-
"@bendyline/squisq-react": "2.4.
|
|
68
|
+
"@bendyline/squisq": "2.4.3",
|
|
69
|
+
"@bendyline/squisq-video": "2.2.7",
|
|
70
|
+
"@bendyline/squisq-react": "2.4.3",
|
|
71
71
|
"@ffmpeg/core": "0.12.9",
|
|
72
72
|
"@ffmpeg/ffmpeg": "0.12.15",
|
|
73
73
|
"@ffmpeg/util": "0.12.2",
|