@bendyline/squisq-video-react 1.1.1 → 1.2.0
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 +171 -19
- package/dist/index.js +921 -21
- package/dist/index.js.map +1 -1
- package/dist/workers/encode.worker.d.ts +2 -13
- package/dist/workers/encode.worker.js +258 -304
- package/dist/workers/encode.worker.js.map +1 -1
- package/package.json +4 -4
- package/src/__tests__/encodeParams.test.ts +33 -0
- package/src/workers/encode.worker.ts +1 -13
- package/src/workers/encodeParams.ts +24 -0
- package/dist/VideoExportButton.d.ts +0 -28
- package/dist/VideoExportButton.d.ts.map +0 -1
- package/dist/VideoExportButton.js +0 -18
- package/dist/VideoExportButton.js.map +0 -1
- package/dist/VideoExportModal.d.ts +0 -26
- package/dist/VideoExportModal.d.ts.map +0 -1
- package/dist/VideoExportModal.js +0 -164
- package/dist/VideoExportModal.js.map +0 -1
- package/dist/hooks/useFrameCapture.d.ts +0 -27
- package/dist/hooks/useFrameCapture.d.ts.map +0 -1
- package/dist/hooks/useFrameCapture.js +0 -211
- package/dist/hooks/useFrameCapture.js.map +0 -1
- package/dist/hooks/useVideoExport.d.ts +0 -75
- package/dist/hooks/useVideoExport.d.ts.map +0 -1
- package/dist/hooks/useVideoExport.js +0 -266
- package/dist/hooks/useVideoExport.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mainThreadEncoder.d.ts +0 -44
- package/dist/mainThreadEncoder.d.ts.map +0 -1
- package/dist/mainThreadEncoder.js +0 -123
- package/dist/mainThreadEncoder.js.map +0 -1
- package/dist/mp4Mux.d.ts +0 -22
- package/dist/mp4Mux.d.ts.map +0 -1
- package/dist/mp4Mux.js +0 -32
- package/dist/mp4Mux.js.map +0 -1
- package/dist/workerEncoder.d.ts +0 -17
- package/dist/workerEncoder.d.ts.map +0 -1
- package/dist/workerEncoder.js +0 -103
- package/dist/workerEncoder.js.map +0 -1
- package/dist/workers/encode.worker.d.ts.map +0 -1
- package/dist/workers/workerTypes.d.ts +0 -63
- package/dist/workers/workerTypes.d.ts.map +0 -1
- package/dist/workers/workerTypes.js +0 -8
- package/dist/workers/workerTypes.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encode.worker.js","sourceRoot":"","sources":["../../src/workers/encode.worker.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/workers/encodeParams.ts","../../src/workers/encode.worker.ts"],"sourcesContent":["/**\n * Pure encoding-parameter helpers used by the encode worker.\n *\n * Kept separate from `encode.worker.ts` so they can be unit-tested directly —\n * importing the worker module wires up `self.onmessage` and pulls in the\n * WebCodecs / ffmpeg.wasm backends, none of which exist in a plain test runner.\n */\n\n/**\n * Target H.264 bitrate (bits/sec) for a given quality at a given resolution.\n * Baseline is ~4 bits per pixel; `draft` halves it and `high` doubles it.\n */\nexport function bitrateForQuality(quality: string, width: number, height: number): number {\n const pixels = width * height;\n const baseBitrate = pixels * 4; // ~4 bits per pixel baseline\n switch (quality) {\n case 'draft':\n return Math.round(baseBitrate * 0.5);\n case 'high':\n return Math.round(baseBitrate * 2);\n default: // normal\n return baseBitrate;\n }\n}\n","/**\n * Video Encoding Web Worker\n *\n * Encodes video frames to MP4 using one of two backends:\n * - **WebCodecs** (preferred): Streaming H.264 encoding via VideoEncoder + mp4-muxer.\n * Each frame is encoded as it arrives — minimal memory footprint.\n * - **ffmpeg.wasm** (fallback): Batch encoding in ~10-second segments.\n * Used when WebCodecs is unavailable (older browsers).\n *\n * Frames arrive as ImageBitmap (zero-copy transfer from main thread).\n */\n\nimport type {\n MainToWorkerMessage,\n WorkerToMainMessage,\n InitMessage,\n FrameMessage,\n} from './workerTypes.js';\nimport { createMp4Muxer, type Mp4MuxerHandle } from '../mp4Mux.js';\nimport { bitrateForQuality } from './encodeParams.js';\n\n// ── State ──────────────────────────────────────────────────────────\n\nlet backend: 'webcodecs' | 'ffmpeg-wasm' | null = null;\nlet cancelled = false;\n\n// WebCodecs state\nlet videoEncoder: VideoEncoder | null = null;\nlet muxer: Mp4MuxerHandle | null = null;\n\n// ffmpeg.wasm state\nlet ffmpegInstance: unknown = null;\nlet ffmpegFrames: Array<{ data: Uint8Array; index: number }> = [];\nlet ffmpegConfig: InitMessage | null = null;\n\n// Frame tracking\nlet totalFramesReceived = 0;\nlet _totalFramesEncoded = 0;\n\n// ── Helpers ────────────────────────────────────────────────────────\n\nfunction post(msg: WorkerToMainMessage, transfer?: Transferable[]) {\n self.postMessage(msg, { transfer: transfer ?? [] });\n}\n\nfunction postProgress(percent: number, phase: string) {\n post({ type: 'progress', percent, phase });\n}\n\nfunction postError(message: string) {\n post({ type: 'error', message });\n}\n\n// ── Feature Detection ──────────────────────────────────────────────\n\nfunction hasWebCodecs(): boolean {\n return typeof VideoEncoder !== 'undefined' && typeof VideoFrame !== 'undefined';\n}\n\nfunction hasSharedArrayBuffer(): boolean {\n return typeof SharedArrayBuffer !== 'undefined';\n}\n\n/**\n * Check whether the browser's WebCodecs implementation actually supports\n * the H.264 Baseline profile we use. Linux Chromium ships without the\n * proprietary H.264 encoder, so `VideoEncoder` exists but `configure()`\n * for `avc1.*` fails asynchronously.\n */\nasync function supportsWebCodecsH264(config: InitMessage): Promise<boolean> {\n if (!hasWebCodecs()) return false;\n try {\n const support = await VideoEncoder.isConfigSupported({\n codec: 'avc1.42001f',\n width: config.width,\n height: config.height,\n bitrate: bitrateForQuality(config.quality, config.width, config.height),\n framerate: config.fps,\n });\n return support.supported === true;\n } catch {\n return false;\n }\n}\n\n// ── WebCodecs Backend ──────────────────────────────────────────────\n\nfunction initWebCodecs(config: InitMessage) {\n muxer = createMp4Muxer({\n width: config.width,\n height: config.height,\n fps: config.fps,\n });\n\n videoEncoder = new VideoEncoder({\n output(chunk, meta) {\n if (cancelled) return;\n muxer!.addVideoChunk(chunk, meta ?? undefined);\n _totalFramesEncoded++;\n },\n error(err) {\n postError(`WebCodecs encoder error: ${err.message}`);\n },\n });\n\n // Use H.264 Baseline for maximum compatibility\n videoEncoder.configure({\n codec: 'avc1.42001f',\n width: config.width,\n height: config.height,\n bitrate: bitrateForQuality(config.quality, config.width, config.height),\n framerate: config.fps,\n });\n}\n\nasync function encodeFrameWebCodecs(msg: FrameMessage) {\n if (!videoEncoder || cancelled) {\n msg.bitmap.close();\n return;\n }\n\n const frame = new VideoFrame(msg.bitmap, { timestamp: msg.timestamp });\n const keyFrame = msg.frameIndex % 30 === 0; // Key frame every 30 frames\n videoEncoder.encode(frame, { keyFrame });\n frame.close();\n msg.bitmap.close();\n totalFramesReceived++;\n\n postProgress(\n Math.round((totalFramesReceived / (totalFramesReceived + 1)) * 50),\n `Encoding frame ${totalFramesReceived}`,\n );\n}\n\nasync function finalizeWebCodecs() {\n if (!videoEncoder || !muxer || cancelled) return;\n\n postProgress(50, 'Flushing encoder…');\n await videoEncoder.flush();\n videoEncoder.close();\n videoEncoder = null;\n\n postProgress(90, 'Finalizing MP4…');\n const buffer = muxer.finalize();\n muxer = null;\n\n post({ type: 'complete', data: buffer, size: buffer.byteLength }, [buffer]);\n}\n\n// ── ffmpeg.wasm Backend ────────────────────────────────────────────\n\nasync function initFfmpegWasm(config: InitMessage) {\n ffmpegConfig = config;\n ffmpegFrames = [];\n totalFramesReceived = 0;\n\n // Lazy-load ffmpeg.wasm\n try {\n const { FFmpeg } = await import('@ffmpeg/ffmpeg');\n const ffmpeg = new FFmpeg();\n await ffmpeg.load();\n ffmpegInstance = ffmpeg;\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n postError(\n `Failed to load ffmpeg.wasm: ${message}. ` +\n 'Ensure @ffmpeg/ffmpeg and @ffmpeg/util are installed and ' +\n 'Cross-Origin-Isolation headers (COOP/COEP) are set.',\n );\n }\n}\n\nasync function encodeFrameFfmpeg(msg: FrameMessage) {\n if (cancelled) {\n msg.bitmap.close();\n return;\n }\n\n // Convert ImageBitmap to PNG bytes via OffscreenCanvas\n const canvas = new OffscreenCanvas(msg.bitmap.width, msg.bitmap.height);\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n msg.bitmap.close();\n postError('Failed to create OffscreenCanvas 2D context');\n return;\n }\n ctx.drawImage(msg.bitmap, 0, 0);\n msg.bitmap.close();\n\n const blob = await canvas.convertToBlob({ type: 'image/png' });\n const arrayBuffer = await blob.arrayBuffer();\n ffmpegFrames.push({ data: new Uint8Array(arrayBuffer), index: msg.frameIndex });\n totalFramesReceived++;\n\n postProgress(\n Math.round((totalFramesReceived / (totalFramesReceived + 1)) * 40),\n `Collecting frame ${totalFramesReceived}`,\n );\n\n // Batch encode every ~10 seconds worth of frames\n const batchSize = (ffmpegConfig?.fps ?? 30) * 10;\n if (ffmpegFrames.length >= batchSize) {\n await encodeFfmpegBatch();\n }\n}\n\n/** Segments already encoded as MP4 data. */\nconst ffmpegSegments: Uint8Array[] = [];\n\nasync function encodeFfmpegBatch() {\n if (!ffmpegInstance || ffmpegFrames.length === 0 || cancelled) return;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ffmpeg = ffmpegInstance as any;\n const config = ffmpegConfig!;\n const batchIndex = ffmpegSegments.length;\n\n postProgress(40 + batchIndex * 5, `Encoding batch ${batchIndex + 1}…`);\n\n // Write frames to virtual filesystem\n for (const frame of ffmpegFrames) {\n const paddedIndex = String(frame.index).padStart(6, '0');\n await ffmpeg.writeFile(`frame_${paddedIndex}.png`, frame.data);\n }\n\n const firstIndex = ffmpegFrames[0].index;\n const segmentName = `segment_${batchIndex}.mp4`;\n\n // Encode batch to MP4 segment\n await ffmpeg.exec([\n '-framerate',\n String(config.fps),\n '-start_number',\n String(firstIndex),\n '-i',\n `frame_%06d.png`,\n '-frames:v',\n String(ffmpegFrames.length),\n '-c:v',\n 'libx264',\n '-pix_fmt',\n 'yuv420p',\n '-preset',\n config.quality === 'draft' ? 'ultrafast' : config.quality === 'high' ? 'slow' : 'medium',\n '-crf',\n config.quality === 'draft' ? '28' : config.quality === 'high' ? '18' : '23',\n segmentName,\n ]);\n\n // Read segment and clean up frames\n const segmentData = await ffmpeg.readFile(segmentName);\n ffmpegSegments.push(segmentData);\n\n // Clean up frame files\n for (const frame of ffmpegFrames) {\n const paddedIndex = String(frame.index).padStart(6, '0');\n await ffmpeg.deleteFile(`frame_${paddedIndex}.png`);\n }\n await ffmpeg.deleteFile(segmentName);\n\n // Free batch memory\n ffmpegFrames = [];\n}\n\nasync function finalizeFfmpeg() {\n if (!ffmpegInstance || cancelled) return;\n\n // Encode any remaining frames\n await encodeFfmpegBatch();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ffmpeg = ffmpegInstance as any;\n\n postProgress(85, 'Concatenating segments…');\n\n let finalData: Uint8Array;\n\n if (ffmpegSegments.length === 1) {\n // Single segment — no concat needed\n finalData = ffmpegSegments[0];\n } else if (ffmpegSegments.length > 1) {\n // Write segments and concat list\n const concatList: string[] = [];\n for (let i = 0; i < ffmpegSegments.length; i++) {\n const name = `seg_${i}.mp4`;\n await ffmpeg.writeFile(name, ffmpegSegments[i]);\n concatList.push(`file '${name}'`);\n }\n await ffmpeg.writeFile('concat.txt', new TextEncoder().encode(concatList.join('\\n')));\n\n await ffmpeg.exec([\n '-f',\n 'concat',\n '-safe',\n '0',\n '-i',\n 'concat.txt',\n '-c',\n 'copy',\n 'output.mp4',\n ]);\n\n finalData = await ffmpeg.readFile('output.mp4');\n\n // Clean up\n for (let i = 0; i < ffmpegSegments.length; i++) {\n await ffmpeg.deleteFile(`seg_${i}.mp4`);\n }\n await ffmpeg.deleteFile('concat.txt');\n await ffmpeg.deleteFile('output.mp4');\n } else {\n postError('No frames were encoded');\n return;\n }\n\n postProgress(95, 'Preparing download…');\n\n // Convert Uint8Array to a transferable ArrayBuffer\n const sliced = new Uint8Array(finalData).buffer as ArrayBuffer;\n post({ type: 'complete', data: sliced, size: sliced.byteLength }, [sliced]);\n\n // Clean up\n ffmpegInstance = null;\n ffmpegSegments.length = 0;\n}\n\n// ── Message Handler ────────────────────────────────────────────────\n\nself.onmessage = async (event: MessageEvent<MainToWorkerMessage>) => {\n const msg = event.data;\n\n try {\n switch (msg.type) {\n case 'init': {\n cancelled = false;\n totalFramesReceived = 0;\n _totalFramesEncoded = 0;\n\n if (await supportsWebCodecsH264(msg)) {\n backend = 'webcodecs';\n initWebCodecs(msg);\n } else if (hasSharedArrayBuffer()) {\n backend = 'ffmpeg-wasm';\n await initFfmpegWasm(msg);\n } else {\n postError(\n 'No video encoding support available. ' +\n 'WebCodecs H.264 is unavailable (typical on Linux Chromium without proprietary codecs) ' +\n 'and ffmpeg.wasm requires SharedArrayBuffer (Cross-Origin-Isolation headers).',\n );\n return;\n }\n\n post({ type: 'capabilities', backend });\n postProgress(0, 'Encoder ready');\n break;\n }\n\n case 'frame': {\n if (backend === 'webcodecs') {\n await encodeFrameWebCodecs(msg);\n } else if (backend === 'ffmpeg-wasm') {\n await encodeFrameFfmpeg(msg);\n }\n break;\n }\n\n case 'finalize': {\n if (backend === 'webcodecs') {\n await finalizeWebCodecs();\n } else if (backend === 'ffmpeg-wasm') {\n await finalizeFfmpeg();\n }\n break;\n }\n\n case 'cancel': {\n cancelled = true;\n if (videoEncoder && videoEncoder.state !== 'closed') {\n videoEncoder.close();\n videoEncoder = null;\n }\n muxer = null;\n ffmpegInstance = null;\n ffmpegFrames = [];\n ffmpegSegments.length = 0;\n break;\n }\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n postError(message);\n }\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/squisq-video-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "React components for browser-based video export of Squisq documents via WebCodecs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bendyline",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@bendyline/squisq": "1.
|
|
49
|
-
"@bendyline/squisq-video": "1.
|
|
50
|
-
"@bendyline/squisq-react": "1.
|
|
48
|
+
"@bendyline/squisq": "1.5.0",
|
|
49
|
+
"@bendyline/squisq-video": "1.2.0",
|
|
50
|
+
"@bendyline/squisq-react": "1.4.0",
|
|
51
51
|
"@ffmpeg/ffmpeg": "0.12.15",
|
|
52
52
|
"@ffmpeg/util": "0.12.2",
|
|
53
53
|
"html2canvas": "1.4.1",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { bitrateForQuality } from '../workers/encodeParams.js';
|
|
3
|
+
|
|
4
|
+
const W = 1920;
|
|
5
|
+
const H = 1080;
|
|
6
|
+
const base = W * H * 4;
|
|
7
|
+
|
|
8
|
+
describe('bitrateForQuality', () => {
|
|
9
|
+
it('returns the ~4 bits-per-pixel baseline for normal quality', () => {
|
|
10
|
+
expect(bitrateForQuality('normal', W, H)).toBe(base);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('falls back to the normal baseline for unknown quality values', () => {
|
|
14
|
+
expect(bitrateForQuality('whatever', W, H)).toBe(base);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('halves the baseline for draft and doubles it for high', () => {
|
|
18
|
+
expect(bitrateForQuality('draft', W, H)).toBe(Math.round(base * 0.5));
|
|
19
|
+
expect(bitrateForQuality('high', W, H)).toBe(Math.round(base * 2));
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('orders bitrate draft < normal < high', () => {
|
|
23
|
+
const draft = bitrateForQuality('draft', W, H);
|
|
24
|
+
const normal = bitrateForQuality('normal', W, H);
|
|
25
|
+
const high = bitrateForQuality('high', W, H);
|
|
26
|
+
expect(draft).toBeLessThan(normal);
|
|
27
|
+
expect(normal).toBeLessThan(high);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('scales with resolution', () => {
|
|
31
|
+
expect(bitrateForQuality('normal', 640, 480)).toBeLessThan(bitrateForQuality('normal', W, H));
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
FrameMessage,
|
|
18
18
|
} from './workerTypes.js';
|
|
19
19
|
import { createMp4Muxer, type Mp4MuxerHandle } from '../mp4Mux.js';
|
|
20
|
+
import { bitrateForQuality } from './encodeParams.js';
|
|
20
21
|
|
|
21
22
|
// ── State ──────────────────────────────────────────────────────────
|
|
22
23
|
|
|
@@ -112,19 +113,6 @@ function initWebCodecs(config: InitMessage) {
|
|
|
112
113
|
});
|
|
113
114
|
}
|
|
114
115
|
|
|
115
|
-
function bitrateForQuality(quality: string, width: number, height: number): number {
|
|
116
|
-
const pixels = width * height;
|
|
117
|
-
const baseBitrate = pixels * 4; // ~4 bits per pixel baseline
|
|
118
|
-
switch (quality) {
|
|
119
|
-
case 'draft':
|
|
120
|
-
return Math.round(baseBitrate * 0.5);
|
|
121
|
-
case 'high':
|
|
122
|
-
return Math.round(baseBitrate * 2);
|
|
123
|
-
default: // normal
|
|
124
|
-
return baseBitrate;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
116
|
async function encodeFrameWebCodecs(msg: FrameMessage) {
|
|
129
117
|
if (!videoEncoder || cancelled) {
|
|
130
118
|
msg.bitmap.close();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure encoding-parameter helpers used by the encode worker.
|
|
3
|
+
*
|
|
4
|
+
* Kept separate from `encode.worker.ts` so they can be unit-tested directly —
|
|
5
|
+
* importing the worker module wires up `self.onmessage` and pulls in the
|
|
6
|
+
* WebCodecs / ffmpeg.wasm backends, none of which exist in a plain test runner.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Target H.264 bitrate (bits/sec) for a given quality at a given resolution.
|
|
11
|
+
* Baseline is ~4 bits per pixel; `draft` halves it and `high` doubles it.
|
|
12
|
+
*/
|
|
13
|
+
export function bitrateForQuality(quality: string, width: number, height: number): number {
|
|
14
|
+
const pixels = width * height;
|
|
15
|
+
const baseBitrate = pixels * 4; // ~4 bits per pixel baseline
|
|
16
|
+
switch (quality) {
|
|
17
|
+
case 'draft':
|
|
18
|
+
return Math.round(baseBitrate * 0.5);
|
|
19
|
+
case 'high':
|
|
20
|
+
return Math.round(baseBitrate * 2);
|
|
21
|
+
default: // normal
|
|
22
|
+
return baseBitrate;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VideoExportButton — Simple button that opens the VideoExportModal in a portal.
|
|
3
|
-
*
|
|
4
|
-
* Convenience wrapper for consumers who want a drop-in button.
|
|
5
|
-
* The modal renders via `createPortal` into `document.body`.
|
|
6
|
-
*/
|
|
7
|
-
import type { Doc } from '@bendyline/squisq/schemas';
|
|
8
|
-
import type { MediaProvider } from '@bendyline/squisq/schemas';
|
|
9
|
-
export interface VideoExportButtonProps {
|
|
10
|
-
/** The document to export */
|
|
11
|
-
doc: Doc;
|
|
12
|
-
/** Player IIFE bundle source */
|
|
13
|
-
playerScript: string;
|
|
14
|
-
/** Optional media provider for resolving images/audio */
|
|
15
|
-
mediaProvider?: MediaProvider;
|
|
16
|
-
/** Pre-collected images map */
|
|
17
|
-
images?: Map<string, ArrayBuffer>;
|
|
18
|
-
/** Pre-collected audio map */
|
|
19
|
-
audio?: Map<string, ArrayBuffer>;
|
|
20
|
-
/** Button label (default: "Export Video") */
|
|
21
|
-
label?: string;
|
|
22
|
-
/** Additional inline styles for the button */
|
|
23
|
-
style?: React.CSSProperties;
|
|
24
|
-
/** Whether the button is disabled */
|
|
25
|
-
disabled?: boolean;
|
|
26
|
-
}
|
|
27
|
-
export declare function VideoExportButton({ doc, playerScript, mediaProvider, images, audio, label, style, disabled, }: VideoExportButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
-
//# sourceMappingURL=VideoExportButton.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VideoExportButton.d.ts","sourceRoot":"","sources":["../src/VideoExportButton.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG/D,MAAM,WAAW,sBAAsB;IACrC,6BAA6B;IAC7B,GAAG,EAAE,GAAG,CAAC;IACT,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACjC,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,GAAG,EACH,YAAY,EACZ,aAAa,EACb,MAAM,EACN,KAAK,EACL,KAAsB,EACtB,KAAK,EACL,QAAQ,GACT,EAAE,sBAAsB,2CA0BxB"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* VideoExportButton — Simple button that opens the VideoExportModal in a portal.
|
|
4
|
-
*
|
|
5
|
-
* Convenience wrapper for consumers who want a drop-in button.
|
|
6
|
-
* The modal renders via `createPortal` into `document.body`.
|
|
7
|
-
*/
|
|
8
|
-
import { useState, useCallback } from 'react';
|
|
9
|
-
import { createPortal } from 'react-dom';
|
|
10
|
-
import { VideoExportModal } from './VideoExportModal.js';
|
|
11
|
-
export function VideoExportButton({ doc, playerScript, mediaProvider, images, audio, label = 'Export Video', style, disabled, }) {
|
|
12
|
-
const [showModal, setShowModal] = useState(false);
|
|
13
|
-
const handleOpen = useCallback(() => setShowModal(true), []);
|
|
14
|
-
const handleClose = useCallback(() => setShowModal(false), []);
|
|
15
|
-
return (_jsxs(_Fragment, { children: [_jsx("button", { onClick: handleOpen, disabled: disabled, style: style, children: label }), showModal &&
|
|
16
|
-
createPortal(_jsx(VideoExportModal, { doc: doc, playerScript: playerScript, mediaProvider: mediaProvider, images: images, audio: audio, onClose: handleClose }), document.body)] }));
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=VideoExportButton.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VideoExportButton.js","sourceRoot":"","sources":["../src/VideoExportButton.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAqBzD,MAAM,UAAU,iBAAiB,CAAC,EAChC,GAAG,EACH,YAAY,EACZ,aAAa,EACb,MAAM,EACN,KAAK,EACL,KAAK,GAAG,cAAc,EACtB,KAAK,EACL,QAAQ,GACe;IACvB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAE/D,OAAO,CACL,8BACE,iBAAQ,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,YAC1D,KAAK,GACC,EAER,SAAS;gBACR,YAAY,CACV,KAAC,gBAAgB,IACf,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,GACpB,EACF,QAAQ,CAAC,IAAI,CACd,IACF,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VideoExportModal — Modal dialog for configuring and monitoring video export.
|
|
3
|
-
*
|
|
4
|
-
* States:
|
|
5
|
-
* configure → exporting (capturing + encoding) → complete | error
|
|
6
|
-
*
|
|
7
|
-
* Inline styles match the site's cream/gold palette (from FileToolbar).
|
|
8
|
-
*/
|
|
9
|
-
import type { Doc } from '@bendyline/squisq/schemas';
|
|
10
|
-
import type { MediaProvider } from '@bendyline/squisq/schemas';
|
|
11
|
-
export interface VideoExportModalProps {
|
|
12
|
-
/** The document to export */
|
|
13
|
-
doc: Doc;
|
|
14
|
-
/** Player IIFE bundle source */
|
|
15
|
-
playerScript: string;
|
|
16
|
-
/** Optional media provider for resolving images/audio */
|
|
17
|
-
mediaProvider?: MediaProvider;
|
|
18
|
-
/** Pre-collected images map (alternative to mediaProvider) */
|
|
19
|
-
images?: Map<string, ArrayBuffer>;
|
|
20
|
-
/** Pre-collected audio map */
|
|
21
|
-
audio?: Map<string, ArrayBuffer>;
|
|
22
|
-
/** Called when the modal should close */
|
|
23
|
-
onClose: () => void;
|
|
24
|
-
}
|
|
25
|
-
export declare function VideoExportModal({ doc, playerScript, mediaProvider, images, audio, onClose, }: VideoExportModalProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
-
//# sourceMappingURL=VideoExportModal.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VideoExportModal.d.ts","sourceRoot":"","sources":["../src/VideoExportModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAO/D,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,GAAG,EAAE,GAAG,CAAC;IACT,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACjC,yCAAyC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAwGD,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,YAAY,EACZ,aAAa,EACb,MAAM,EACN,KAAK,EACL,OAAO,GACR,EAAE,qBAAqB,2CA+NvB"}
|
package/dist/VideoExportModal.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* VideoExportModal — Modal dialog for configuring and monitoring video export.
|
|
4
|
-
*
|
|
5
|
-
* States:
|
|
6
|
-
* configure → exporting (capturing + encoding) → complete | error
|
|
7
|
-
*
|
|
8
|
-
* Inline styles match the site's cream/gold palette (from FileToolbar).
|
|
9
|
-
*/
|
|
10
|
-
import { useState, useCallback } from 'react';
|
|
11
|
-
import { useVideoExport } from './hooks/useVideoExport.js';
|
|
12
|
-
// ── Helpers ────────────────────────────────────────────────────
|
|
13
|
-
function formatDuration(seconds) {
|
|
14
|
-
if (seconds < 60)
|
|
15
|
-
return `${seconds}s`;
|
|
16
|
-
const m = Math.floor(seconds / 60);
|
|
17
|
-
const s = seconds % 60;
|
|
18
|
-
return `${m}m ${s}s`;
|
|
19
|
-
}
|
|
20
|
-
// ── Styles ─────────────────────────────────────────────────────────
|
|
21
|
-
const overlayStyle = {
|
|
22
|
-
position: 'fixed',
|
|
23
|
-
inset: 0,
|
|
24
|
-
background: 'rgba(0, 0, 0, 0.5)',
|
|
25
|
-
display: 'flex',
|
|
26
|
-
alignItems: 'center',
|
|
27
|
-
justifyContent: 'center',
|
|
28
|
-
zIndex: 10000,
|
|
29
|
-
};
|
|
30
|
-
const modalStyle = {
|
|
31
|
-
background: '#FFFDF7',
|
|
32
|
-
border: '1px solid #c9b98a',
|
|
33
|
-
borderRadius: 0,
|
|
34
|
-
padding: '24px 28px',
|
|
35
|
-
minWidth: 380,
|
|
36
|
-
maxWidth: 480,
|
|
37
|
-
boxShadow: '0 8px 32px rgba(0,0,0,0.18)',
|
|
38
|
-
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
39
|
-
color: '#4a3c1f',
|
|
40
|
-
};
|
|
41
|
-
const titleStyle = {
|
|
42
|
-
margin: '0 0 16px 0',
|
|
43
|
-
fontSize: 18,
|
|
44
|
-
fontWeight: 600,
|
|
45
|
-
color: '#2d2310',
|
|
46
|
-
};
|
|
47
|
-
const labelStyle = {
|
|
48
|
-
display: 'block',
|
|
49
|
-
fontSize: 13,
|
|
50
|
-
fontWeight: 500,
|
|
51
|
-
marginBottom: 4,
|
|
52
|
-
color: '#5a4a2a',
|
|
53
|
-
};
|
|
54
|
-
const selectStyle = {
|
|
55
|
-
width: '100%',
|
|
56
|
-
padding: '6px 8px',
|
|
57
|
-
fontSize: 13,
|
|
58
|
-
fontFamily: 'inherit',
|
|
59
|
-
border: '1px solid #c9b98a',
|
|
60
|
-
borderRadius: 0,
|
|
61
|
-
background: '#fff',
|
|
62
|
-
color: '#4a3c1f',
|
|
63
|
-
marginBottom: 12,
|
|
64
|
-
};
|
|
65
|
-
const btnPrimary = {
|
|
66
|
-
padding: '8px 20px',
|
|
67
|
-
fontSize: 14,
|
|
68
|
-
fontFamily: 'inherit',
|
|
69
|
-
fontWeight: 500,
|
|
70
|
-
cursor: 'pointer',
|
|
71
|
-
background: '#8B6914',
|
|
72
|
-
color: '#fff',
|
|
73
|
-
border: '1px solid #7a5c10',
|
|
74
|
-
borderRadius: 0,
|
|
75
|
-
};
|
|
76
|
-
const btnSecondary = {
|
|
77
|
-
padding: '8px 20px',
|
|
78
|
-
fontSize: 14,
|
|
79
|
-
fontFamily: 'inherit',
|
|
80
|
-
fontWeight: 500,
|
|
81
|
-
cursor: 'pointer',
|
|
82
|
-
background: '#E8DFC6',
|
|
83
|
-
color: '#4a3c1f',
|
|
84
|
-
border: '1px solid #c9b98a',
|
|
85
|
-
borderRadius: 0,
|
|
86
|
-
};
|
|
87
|
-
const progressBarOuterStyle = {
|
|
88
|
-
width: '100%',
|
|
89
|
-
height: 8,
|
|
90
|
-
background: '#E8DFC6',
|
|
91
|
-
borderRadius: 0,
|
|
92
|
-
overflow: 'hidden',
|
|
93
|
-
marginBottom: 8,
|
|
94
|
-
};
|
|
95
|
-
const footerStyle = {
|
|
96
|
-
display: 'flex',
|
|
97
|
-
justifyContent: 'flex-end',
|
|
98
|
-
gap: 8,
|
|
99
|
-
marginTop: 20,
|
|
100
|
-
};
|
|
101
|
-
// ── Component ──────────────────────────────────────────────────────
|
|
102
|
-
export function VideoExportModal({ doc, playerScript, mediaProvider, images, audio, onClose, }) {
|
|
103
|
-
const [quality, setQuality] = useState('normal');
|
|
104
|
-
const [fps, setFps] = useState(24);
|
|
105
|
-
const [orientation, setOrientation] = useState('landscape');
|
|
106
|
-
const [captionMode, setCaptionMode] = useState('off');
|
|
107
|
-
const exportHook = useVideoExport();
|
|
108
|
-
const { state, progress, backend, downloadUrl, fileSize, error, elapsed, estimatedRemaining, startExport, cancel: cancelExport, reset: resetExport, } = exportHook;
|
|
109
|
-
const handleExport = useCallback(async () => {
|
|
110
|
-
const config = {
|
|
111
|
-
quality,
|
|
112
|
-
fps,
|
|
113
|
-
orientation,
|
|
114
|
-
captionMode,
|
|
115
|
-
images,
|
|
116
|
-
audio,
|
|
117
|
-
mediaProvider,
|
|
118
|
-
playerScript,
|
|
119
|
-
};
|
|
120
|
-
await startExport(doc, config);
|
|
121
|
-
}, [
|
|
122
|
-
doc,
|
|
123
|
-
quality,
|
|
124
|
-
fps,
|
|
125
|
-
orientation,
|
|
126
|
-
captionMode,
|
|
127
|
-
images,
|
|
128
|
-
audio,
|
|
129
|
-
mediaProvider,
|
|
130
|
-
playerScript,
|
|
131
|
-
startExport,
|
|
132
|
-
]);
|
|
133
|
-
const handleDownload = useCallback(() => {
|
|
134
|
-
if (!downloadUrl)
|
|
135
|
-
return;
|
|
136
|
-
const a = document.createElement('a');
|
|
137
|
-
a.href = downloadUrl;
|
|
138
|
-
const ts = new Date().toISOString().slice(0, 10);
|
|
139
|
-
a.download = `document-${ts}.mp4`;
|
|
140
|
-
document.body.appendChild(a);
|
|
141
|
-
a.click();
|
|
142
|
-
document.body.removeChild(a);
|
|
143
|
-
}, [downloadUrl]);
|
|
144
|
-
const handleClose = useCallback(() => {
|
|
145
|
-
if (state === 'capturing' || state === 'encoding' || state === 'preparing') {
|
|
146
|
-
cancelExport();
|
|
147
|
-
}
|
|
148
|
-
resetExport();
|
|
149
|
-
onClose();
|
|
150
|
-
}, [state, cancelExport, resetExport, onClose]);
|
|
151
|
-
const isExporting = state === 'preparing' || state === 'capturing' || state === 'encoding';
|
|
152
|
-
return (_jsx("div", { style: overlayStyle, onClick: handleClose, children: _jsxs("div", { style: modalStyle, onClick: (e) => e.stopPropagation(), children: [_jsx("h2", { style: titleStyle, children: "Export Video" }), state === 'idle' && (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("label", { style: labelStyle, children: "Quality" }), _jsxs("select", { style: selectStyle, value: quality, onChange: (e) => setQuality(e.target.value), children: [_jsx("option", { value: "draft", children: "Draft \u2014 fast, lower quality" }), _jsx("option", { value: "normal", children: "Normal \u2014 balanced" }), _jsx("option", { value: "high", children: "High \u2014 best quality, slower" })] })] }), _jsxs("div", { children: [_jsx("label", { style: labelStyle, children: "Frame Rate" }), _jsxs("select", { style: selectStyle, value: fps, onChange: (e) => setFps(Number(e.target.value)), children: [_jsx("option", { value: 15, children: "15 fps \u2014 fast export" }), _jsx("option", { value: 24, children: "24 fps \u2014 cinematic" }), _jsx("option", { value: 30, children: "30 fps \u2014 smooth" })] })] }), _jsxs("div", { children: [_jsx("label", { style: labelStyle, children: "Orientation" }), _jsxs("select", { style: selectStyle, value: orientation, onChange: (e) => setOrientation(e.target.value), children: [_jsx("option", { value: "landscape", children: "Landscape (1920 \u00D7 1080)" }), _jsx("option", { value: "portrait", children: "Portrait (1080 \u00D7 1920)" })] })] }), _jsxs("div", { children: [_jsx("label", { style: labelStyle, children: "Captions" }), _jsxs("select", { style: selectStyle, value: captionMode, onChange: (e) => setCaptionMode(e.target.value), children: [_jsx("option", { value: "off", children: "None" }), _jsx("option", { value: "standard", children: "Standard (top bar)" }), _jsx("option", { value: "social", children: "Social media (large words)" })] })] }), _jsxs("div", { style: footerStyle, children: [_jsx("button", { style: btnSecondary, onClick: handleClose, children: "Cancel" }), _jsx("button", { style: btnPrimary, onClick: handleExport, children: "Export Video" })] })] })), isExporting && (_jsxs(_Fragment, { children: [backend && (_jsx("p", { style: { fontSize: 12, color: '#8a7a5a', margin: '0 0 8px 0' }, children: "Encoder: WebCodecs (H.264)" })), _jsx("div", { style: progressBarOuterStyle, children: _jsx("div", { style: {
|
|
153
|
-
width: `${progress}%`,
|
|
154
|
-
height: '100%',
|
|
155
|
-
background: '#8B6914',
|
|
156
|
-
transition: 'width 0.3s ease',
|
|
157
|
-
} }) }), _jsxs("p", { style: { fontSize: 13, margin: '0 0 4px 0' }, children: [progress, "% complete"] }), _jsxs("p", { style: { fontSize: 12, color: '#8a7a5a', margin: 0 }, children: [formatDuration(elapsed), " elapsed", estimatedRemaining > 0 && ` · ~${formatDuration(estimatedRemaining)} remaining`] }), _jsx("div", { style: footerStyle, children: _jsx("button", { style: btnSecondary, onClick: cancelExport, children: "Cancel" }) })] })), state === 'complete' && (_jsxs(_Fragment, { children: [_jsx("p", { style: { fontSize: 14, margin: '0 0 8px 0', color: '#2d6a10' }, children: "Export complete!" }), _jsxs("p", { style: { fontSize: 13, color: '#5a4a2a', margin: '0 0 4px 0' }, children: ["File size: ", (fileSize / (1024 * 1024)).toFixed(1), " MB"] }), backend && (_jsx("p", { style: { fontSize: 12, color: '#8a7a5a', margin: '0 0 12px 0' }, children: "Encoded with WebCodecs (H.264)" })), _jsxs("div", { style: footerStyle, children: [_jsx("button", { style: btnSecondary, onClick: handleClose, children: "Close" }), _jsx("button", { style: btnPrimary, onClick: handleDownload, children: "Download MP4" })] })] })), state === 'error' && (_jsxs(_Fragment, { children: [_jsx("p", { style: { fontSize: 14, margin: '0 0 8px 0', color: '#a03020' }, children: "Export failed" }), _jsx("p", { style: {
|
|
158
|
-
fontSize: 13,
|
|
159
|
-
color: '#5a4a2a',
|
|
160
|
-
margin: '0 0 12px 0',
|
|
161
|
-
wordBreak: 'break-word',
|
|
162
|
-
}, children: error }), _jsxs("div", { style: footerStyle, children: [_jsx("button", { style: btnSecondary, onClick: handleClose, children: "Close" }), _jsx("button", { style: btnPrimary, onClick: handleExport, children: "Retry" })] })] }))] }) }));
|
|
163
|
-
}
|
|
164
|
-
//# sourceMappingURL=VideoExportModal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VideoExportModal.js","sourceRoot":"","sources":["../src/VideoExportModal.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAK9C,OAAO,EAAE,cAAc,EAA0B,MAAM,2BAA2B,CAAC;AAmBnF,kEAAkE;AAElE,SAAS,cAAc,CAAC,OAAe;IACrC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACvC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,OAAO,GAAG,EAAE,CAAC;IACvB,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;AACvB,CAAC;AAED,sEAAsE;AAEtE,MAAM,YAAY,GAAwB;IACxC,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,CAAC;IACR,UAAU,EAAE,oBAAoB;IAChC,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,QAAQ;IACxB,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,MAAM,UAAU,GAAwB;IACtC,UAAU,EAAE,SAAS;IACrB,MAAM,EAAE,mBAAmB;IAC3B,YAAY,EAAE,CAAC;IACf,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,GAAG;IACb,QAAQ,EAAE,GAAG;IACb,SAAS,EAAE,6BAA6B;IACxC,UAAU,EAAE,sCAAsC;IAClD,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,UAAU,GAAwB;IACtC,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,GAAG;IACf,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,UAAU,GAAwB;IACtC,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,GAAG;IACf,YAAY,EAAE,CAAC;IACf,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,WAAW,GAAwB;IACvC,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,SAAS;IACrB,MAAM,EAAE,mBAAmB;IAC3B,YAAY,EAAE,CAAC;IACf,UAAU,EAAE,MAAM;IAClB,KAAK,EAAE,SAAS;IAChB,YAAY,EAAE,EAAE;CACjB,CAAC;AAEF,MAAM,UAAU,GAAwB;IACtC,OAAO,EAAE,UAAU;IACnB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,SAAS;IACrB,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,mBAAmB;IAC3B,YAAY,EAAE,CAAC;CAChB,CAAC;AAEF,MAAM,YAAY,GAAwB;IACxC,OAAO,EAAE,UAAU;IACnB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,SAAS;IACrB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,mBAAmB;IAC3B,YAAY,EAAE,CAAC;CAChB,CAAC;AAEF,MAAM,qBAAqB,GAAwB;IACjD,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,CAAC;IACf,QAAQ,EAAE,QAAQ;IAClB,YAAY,EAAE,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,GAAwB;IACvC,OAAO,EAAE,MAAM;IACf,cAAc,EAAE,UAAU;IAC1B,GAAG,EAAE,CAAC;IACN,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,sEAAsE;AAEtE,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,YAAY,EACZ,aAAa,EACb,MAAM,EACN,KAAK,EACL,OAAO,GACe;IACtB,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAe,QAAQ,CAAC,CAAC;IAC/D,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAmB,WAAW,CAAC,CAAC;IAC9E,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAc,KAAK,CAAC,CAAC;IAEnE,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,MAAM,EACJ,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,QAAQ,EACR,KAAK,EACL,OAAO,EACP,kBAAkB,EAClB,WAAW,EACX,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,WAAW,GACnB,GAAG,UAAU,CAAC;IAEf,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1C,MAAM,MAAM,GAAsB;YAChC,OAAO;YACP,GAAG;YACH,WAAW;YACX,WAAW;YACX,MAAM;YACN,KAAK;YACL,aAAa;YACb,YAAY;SACb,CAAC;QACF,MAAM,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC,EAAE;QACD,GAAG;QACH,OAAO;QACP,GAAG;QACH,WAAW;QACX,WAAW;QACX,MAAM;QACN,KAAK;QACL,aAAa;QACb,YAAY;QACZ,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,IAAI,CAAC,WAAW;YAAE,OAAO;QACzB,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC;QACrB,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,CAAC,CAAC,QAAQ,GAAG,YAAY,EAAE,MAAM,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;YAC3E,YAAY,EAAE,CAAC;QACjB,CAAC;QACD,WAAW,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,UAAU,CAAC;IAE3F,OAAO,CACL,cAAK,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,YAC5C,eAAK,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,aACzD,aAAI,KAAK,EAAE,UAAU,6BAAmB,EAGvC,KAAK,KAAK,MAAM,IAAI,CACnB,8BACE,0BACE,gBAAO,KAAK,EAAE,UAAU,wBAAiB,EACzC,kBACE,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAqB,CAAC,aAE3D,iBAAQ,KAAK,EAAC,OAAO,iDAAqC,EAC1D,iBAAQ,KAAK,EAAC,QAAQ,uCAA2B,EACjD,iBAAQ,KAAK,EAAC,MAAM,iDAAqC,IAClD,IACL,EAEN,0BACE,gBAAO,KAAK,EAAE,UAAU,2BAAoB,EAC5C,kBACE,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,aAE/C,iBAAQ,KAAK,EAAE,EAAE,0CAA+B,EAChD,iBAAQ,KAAK,EAAE,EAAE,wCAA6B,EAC9C,iBAAQ,KAAK,EAAE,EAAE,qCAA0B,IACpC,IACL,EAEN,0BACE,gBAAO,KAAK,EAAE,UAAU,4BAAqB,EAC7C,kBACE,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAyB,CAAC,aAEnE,iBAAQ,KAAK,EAAC,WAAW,6CAAiC,EAC1D,iBAAQ,KAAK,EAAC,UAAU,4CAAgC,IACjD,IACL,EAEN,0BACE,gBAAO,KAAK,EAAE,UAAU,yBAAkB,EAC1C,kBACE,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAoB,CAAC,aAE9D,iBAAQ,KAAK,EAAC,KAAK,qBAAc,EACjC,iBAAQ,KAAK,EAAC,UAAU,mCAA4B,EACpD,iBAAQ,KAAK,EAAC,QAAQ,2CAAoC,IACnD,IACL,EAEN,eAAK,KAAK,EAAE,WAAW,aACrB,iBAAQ,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,uBAExC,EACT,iBAAQ,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,6BAEvC,IACL,IACL,CACJ,EAGA,WAAW,IAAI,CACd,8BACG,OAAO,IAAI,CACV,YAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,2CAE7D,CACL,EAED,cAAK,KAAK,EAAE,qBAAqB,YAC/B,cACE,KAAK,EAAE;oCACL,KAAK,EAAE,GAAG,QAAQ,GAAG;oCACrB,MAAM,EAAE,MAAM;oCACd,UAAU,EAAE,SAAS;oCACrB,UAAU,EAAE,iBAAiB;iCAC9B,GACD,GACE,EAEN,aAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,aAAG,QAAQ,kBAAe,EACzE,aAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,aACpD,cAAc,CAAC,OAAO,CAAC,cACvB,kBAAkB,GAAG,CAAC,IAAI,OAAO,cAAc,CAAC,kBAAkB,CAAC,YAAY,IAC9E,EAEJ,cAAK,KAAK,EAAE,WAAW,YACrB,iBAAQ,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,uBAEzC,GACL,IACL,CACJ,EAGA,KAAK,KAAK,UAAU,IAAI,CACvB,8BACE,YAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,iCAAsB,EACvF,aAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,4BACnD,CAAC,QAAQ,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAC/C,EACH,OAAO,IAAI,CACV,YAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,+CAE9D,CACL,EAED,eAAK,KAAK,EAAE,WAAW,aACrB,iBAAQ,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,sBAExC,EACT,iBAAQ,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,6BAEzC,IACL,IACL,CACJ,EAGA,KAAK,KAAK,OAAO,IAAI,CACpB,8BACE,YAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,8BAAmB,EACpF,YACE,KAAK,EAAE;gCACL,QAAQ,EAAE,EAAE;gCACZ,KAAK,EAAE,SAAS;gCAChB,MAAM,EAAE,YAAY;gCACpB,SAAS,EAAE,YAAY;6BACxB,YAEA,KAAK,GACJ,EAEJ,eAAK,KAAK,EAAE,WAAW,aACrB,iBAAQ,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,sBAExC,EACT,iBAAQ,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,sBAEvC,IACL,IACL,CACJ,IACG,GACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useFrameCapture — Hidden div + html2canvas frame capture.
|
|
3
|
-
*
|
|
4
|
-
* Mounts a DocPlayer in renderMode inside a hidden div (same document),
|
|
5
|
-
* then captures individual frames by seeking the player and rendering
|
|
6
|
-
* the DOM to a canvas via html2canvas.
|
|
7
|
-
*
|
|
8
|
-
* Uses React directly — no script injection, no iframes, no eval.
|
|
9
|
-
*
|
|
10
|
-
* Returns an ImageBitmap for each frame (transferable to a Worker).
|
|
11
|
-
*/
|
|
12
|
-
import type { Doc } from '@bendyline/squisq/schemas';
|
|
13
|
-
import type { RenderHtmlOptions } from '@bendyline/squisq-video';
|
|
14
|
-
import type { CaptionMode } from '@bendyline/squisq-react';
|
|
15
|
-
export interface FrameCaptureHandle {
|
|
16
|
-
/** Initialize the hidden player. Returns the video duration in seconds. */
|
|
17
|
-
init: (doc: Doc, renderOptions: Omit<RenderHtmlOptions, 'playerScript'>, captionMode?: CaptionMode) => Promise<number>;
|
|
18
|
-
/** Capture a single frame at the given time (seconds). Returns an ImageBitmap. */
|
|
19
|
-
captureFrame: (time: number) => Promise<ImageBitmap>;
|
|
20
|
-
/** Clean up resources. */
|
|
21
|
-
destroy: () => void;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Hook that manages a hidden div for frame capture.
|
|
25
|
-
*/
|
|
26
|
-
export declare function useFrameCapture(): FrameCaptureHandle;
|
|
27
|
-
//# sourceMappingURL=useFrameCapture.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useFrameCapture.d.ts","sourceRoot":"","sources":["../../src/hooks/useFrameCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAgB,WAAW,EAAgB,MAAM,yBAAyB,CAAC;AAGvF,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,IAAI,EAAE,CACJ,GAAG,EAAE,GAAG,EACR,aAAa,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,EACtD,WAAW,CAAC,EAAE,WAAW,KACtB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,kFAAkF;IAClF,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,0BAA0B;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA2DD;;GAEG;AACH,wBAAgB,eAAe,IAAI,kBAAkB,CAwKpD"}
|