@orangecatai/adgen-canvas 0.0.26 → 0.0.28
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/dev/{chunk-HAGQZMXY.js → chunk-OTDOAN2W.js} +3 -3
- package/dist/dev/{chunk-M6SLPQMN.js → chunk-WELJ6MTO.js} +2 -2
- package/dist/dev/data/{image-TSTRTL65.js → image-F5HBZTBB.js} +3 -3
- package/dist/dev/index.css +377 -0
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +4506 -2591
- package/dist/dev/index.js.map +4 -4
- package/dist/dev/subset-shared.chunk.js +1 -1
- package/dist/dev/subset-worker.chunk.js +1 -1
- package/dist/prod/{chunk-FABLWJ5B.js → chunk-INDX7AB6.js} +1 -1
- package/dist/prod/{chunk-PIJUOUUJ.js → chunk-RI6ZX32X.js} +2 -2
- package/dist/prod/data/image-P4AE4WIT.js +1 -0
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +69 -63
- package/dist/prod/subset-shared.chunk.js +1 -1
- package/dist/prod/subset-worker.chunk.js +1 -1
- package/dist/types/excalidraw/components/AIChatPanel.d.ts +25 -0
- package/dist/types/excalidraw/components/App.d.ts +9 -0
- package/dist/types/excalidraw/components/CampaignDropdown.d.ts +14 -0
- package/dist/types/excalidraw/components/FrameToolbar.d.ts +11 -2
- package/dist/types/excalidraw/components/ImageGeneratorPanel.d.ts +14 -0
- package/dist/types/excalidraw/components/VideoChainPanel.d.ts +58 -0
- package/dist/types/excalidraw/components/VideoElement.d.ts +26 -1
- package/dist/types/excalidraw/components/ai-chat/canvasTools.d.ts +272 -3
- package/dist/types/excalidraw/components/frameToolbarVariant.d.ts +23 -0
- package/dist/types/excalidraw/components/video/videoActions.d.ts +37 -0
- package/dist/types/excalidraw/index.d.ts +1 -0
- package/dist/types/excalidraw/types.d.ts +61 -0
- package/dist/types/excalidraw/utils/brandContextUtils.d.ts +21 -0
- package/dist/types/excalidraw/utils/videoApi.d.ts +81 -0
- package/dist/types/excalidraw/utils/videoDurationStops.d.ts +14 -0
- package/dist/types/excalidraw/utils/videoStitch.d.ts +24 -0
- package/package.json +2 -1
- package/dist/prod/data/image-D6B2C7FH.js +0 -1
- /package/dist/dev/{chunk-HAGQZMXY.js.map → chunk-OTDOAN2W.js.map} +0 -0
- /package/dist/dev/{chunk-M6SLPQMN.js.map → chunk-WELJ6MTO.js.map} +0 -0
- /package/dist/dev/data/{image-TSTRTL65.js.map → image-F5HBZTBB.js.map} +0 -0
|
@@ -21,3 +21,24 @@ export declare function buildImageGenSafePrompt(prompt: string, brandContext: Br
|
|
|
21
21
|
width: number;
|
|
22
22
|
height: number;
|
|
23
23
|
}): string;
|
|
24
|
+
/**
|
|
25
|
+
* Augments a video prompt with brand direction reframed for motion.
|
|
26
|
+
*
|
|
27
|
+
* Deliberately NOT a reuse of buildBrandContextMessage: that builder targets
|
|
28
|
+
* static image ads and emits px size scales, layout patterns, and "render all
|
|
29
|
+
* on-image text in this exact typeface" mandates. Video models ignore px hints
|
|
30
|
+
* and garble text when pushed to reproduce a typeface, so this builder drops
|
|
31
|
+
* `layoutPattern` and `sizeScale` entirely and demotes typography to a soft
|
|
32
|
+
* note inside the on-screen-text clause.
|
|
33
|
+
*
|
|
34
|
+
* The logo is only mentioned when `opts.hasLogoReference` is true — i.e. the
|
|
35
|
+
* logo is actually attached as an input reference (seedance in reference mode).
|
|
36
|
+
* Asking a model to draw a brand mark it has never seen yields a mangled
|
|
37
|
+
* pseudo-logo, which is worse for brand safety than no logo at all.
|
|
38
|
+
*
|
|
39
|
+
* Returns `prompt` unchanged when the brand kit carries no usable direction, so
|
|
40
|
+
* a half-filled kit never appends an empty header.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildVideoBrandPrompt(prompt: string, ctx: BrandContext, opts?: {
|
|
43
|
+
hasLogoReference?: boolean;
|
|
44
|
+
}): string;
|
|
@@ -13,6 +13,13 @@ export interface VideoJobParams {
|
|
|
13
13
|
}
|
|
14
14
|
export interface VideoJobResult {
|
|
15
15
|
videoPresignedUrl: string;
|
|
16
|
+
/**
|
|
17
|
+
* The S3 object key the host persisted the finished segment under (see
|
|
18
|
+
* `/api/sdk/video-gen/status`). Chains persist this per segment so a
|
|
19
|
+
* resumed chain can re-fetch a segment's bytes after its presigned URL
|
|
20
|
+
* (1hr TTL) has expired.
|
|
21
|
+
*/
|
|
22
|
+
videoS3Key?: string;
|
|
16
23
|
}
|
|
17
24
|
/**
|
|
18
25
|
* Submit a video generation job to the host proxy.
|
|
@@ -28,3 +35,77 @@ export declare function submitVideoJob(params: VideoJobParams, videoGenUrl: stri
|
|
|
28
35
|
* Rejects with an Error on failure or abort.
|
|
29
36
|
*/
|
|
30
37
|
export declare function pollVideoJob(jobId: string, videoGenStatusUrl: string, onProgress: (progress: number) => void, signal?: AbortSignal): Promise<VideoJobResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Presigned S3 URLs can't be fetched directly from the browser — S3 buckets
|
|
40
|
+
* generally don't grant CORS to the app's origin for arbitrary GET-with-body-
|
|
41
|
+
* read requests, so a bare `fetch()` fails with an opaque "Failed to fetch"
|
|
42
|
+
* (unlike a `<video src>`, which the browser loads without a CORS check).
|
|
43
|
+
* Route through the host's download proxy when available: it fetches
|
|
44
|
+
* server-side (no CORS involved) and streams the bytes back same-origin.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveFetchUrl(videoPresignedUrl: string, videoDownloadProxyUrl: string | undefined): string;
|
|
47
|
+
export declare function fetchSegmentBlob(videoPresignedUrl: string, videoDownloadProxyUrl: string | undefined, signal?: AbortSignal): Promise<Blob>;
|
|
48
|
+
export declare function uploadMergedVideo(blob: Blob, uploadUrl: string | undefined): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Narrative role of a segment within the ad's arc, assigned by the
|
|
51
|
+
* shot-splitter (`/api/sdk/video-plan`). "hold" marks a segment generated
|
|
52
|
+
* after the story has already resolved — an ambient continuation rather than
|
|
53
|
+
* new plot action.
|
|
54
|
+
*/
|
|
55
|
+
export type ChainSegmentBeat = "setup" | "build" | "turn" | "resolution" | "hold";
|
|
56
|
+
export interface VideoPlan {
|
|
57
|
+
styleAnchor: string;
|
|
58
|
+
segments: Array<{
|
|
59
|
+
beat: ChainSegmentBeat;
|
|
60
|
+
prompt: string;
|
|
61
|
+
}>;
|
|
62
|
+
}
|
|
63
|
+
/** Calls the host shot-splitter to divide a concept into per-segment prompts. */
|
|
64
|
+
export declare function planVideoChain(videoPlanUrl: string, params: {
|
|
65
|
+
concept: string;
|
|
66
|
+
segmentCount: number;
|
|
67
|
+
segmentDurationSeconds: number;
|
|
68
|
+
}, signal?: AbortSignal): Promise<VideoPlan>;
|
|
69
|
+
export interface ChainSegmentPlan {
|
|
70
|
+
index: number;
|
|
71
|
+
prompt: string;
|
|
72
|
+
}
|
|
73
|
+
export interface ChainSegmentResult {
|
|
74
|
+
index: number;
|
|
75
|
+
jobId: string;
|
|
76
|
+
videoBlob: Blob;
|
|
77
|
+
videoS3Key?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface ChainParams {
|
|
80
|
+
segments: ChainSegmentPlan[];
|
|
81
|
+
/** Every VideoJobParams field except prompt/firstFrameDataUrl, which vary per segment. */
|
|
82
|
+
baseParams: Omit<VideoJobParams, "prompt" | "firstFrameDataUrl">;
|
|
83
|
+
videoGenUrl: string;
|
|
84
|
+
videoGenStatusUrl: string;
|
|
85
|
+
/** First frame for segment 0, e.g. a user-uploaded starting image. Omit to let the model choose its own opening frame. */
|
|
86
|
+
initialFirstFrameDataUrl?: string;
|
|
87
|
+
/** Segment index to resume from. Requires `resumeFirstFrameDataUrl`. */
|
|
88
|
+
resumeFromIndex?: number;
|
|
89
|
+
/** The last frame extracted from segment `resumeFromIndex - 1`, re-derived by the caller from its persisted `videoS3Key`. */
|
|
90
|
+
resumeFirstFrameDataUrl?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface ChainDeps {
|
|
93
|
+
submit: typeof submitVideoJob;
|
|
94
|
+
poll: typeof pollVideoJob;
|
|
95
|
+
fetchSegment: (videoPresignedUrl: string, signal?: AbortSignal) => Promise<Blob>;
|
|
96
|
+
extractLastFrame: (video: Blob) => Promise<string>;
|
|
97
|
+
}
|
|
98
|
+
export interface ChainCallbacks {
|
|
99
|
+
onSegmentStart?: (index: number) => void;
|
|
100
|
+
onSegmentProgress?: (index: number, progress: number) => void;
|
|
101
|
+
onSegmentDone?: (index: number, result: ChainSegmentResult) => void | Promise<void>;
|
|
102
|
+
}
|
|
103
|
+
export interface ChainResult {
|
|
104
|
+
segments: ChainSegmentResult[];
|
|
105
|
+
}
|
|
106
|
+
/** Thrown when a chain segment fails. `segmentIndex` identifies which one, for a "Retry from segment N" UI. */
|
|
107
|
+
export declare class ChainSegmentError extends Error {
|
|
108
|
+
readonly segmentIndex: number;
|
|
109
|
+
constructor(segmentIndex: number, cause: unknown);
|
|
110
|
+
}
|
|
111
|
+
export declare function runVideoChain(params: ChainParams, deps: ChainDeps, callbacks?: ChainCallbacks, signal?: AbortSignal): Promise<ChainResult>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const MAX_CHAIN_SEGMENTS = 6;
|
|
2
|
+
export interface DurationStopsConfig {
|
|
3
|
+
supportsDuration: boolean;
|
|
4
|
+
durationMode?: "choices" | "slider";
|
|
5
|
+
durationValues?: readonly number[];
|
|
6
|
+
minDuration?: number;
|
|
7
|
+
maxDuration?: number;
|
|
8
|
+
}
|
|
9
|
+
/** The model's largest single-generation duration, or null if it doesn't support duration at all. */
|
|
10
|
+
export declare function nativeMaxFor(cfg: DurationStopsConfig): number | null;
|
|
11
|
+
/** The full ascending list of valid duration values for this model's duration control. */
|
|
12
|
+
export declare function stopsFor(cfg: DurationStopsConfig): number[];
|
|
13
|
+
/** How many chain segments a given stop implies (1 = single-shot, no chaining). */
|
|
14
|
+
export declare function segmentCountAt(stop: number, nativeMax: number): number;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type AudioPolicy = "first-only" | "none";
|
|
2
|
+
/**
|
|
3
|
+
* Decodes the final frame of a video and returns it as a lossless PNG data
|
|
4
|
+
* URL, suitable as the next chain segment's `firstFrameDataUrl`.
|
|
5
|
+
*
|
|
6
|
+
* Uses `CanvasSink.getCanvas(Infinity)` rather than seeking a `<video>`
|
|
7
|
+
* element to `duration - epsilon`: a time-based seek can land on a keyframe
|
|
8
|
+
* boundary or a black tail frame depending on the encoder, which poisons the
|
|
9
|
+
* next segment's starting state.
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractLastFrame(video: Blob): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Stream-copy concatenates segments produced by the same model at the same
|
|
14
|
+
* codec/resolution/fps into one MP4. No re-encode — packets are demuxed
|
|
15
|
+
* from each input and remuxed with shifted timestamps, so this is fast and
|
|
16
|
+
* lossless.
|
|
17
|
+
*
|
|
18
|
+
* Audio policy exists because Veo and Seedance are always-on-audio models
|
|
19
|
+
* with no way to request a silent segment — muting has to happen here, at
|
|
20
|
+
* merge time, to behave the same across every model.
|
|
21
|
+
*/
|
|
22
|
+
export declare function concatSegments(segments: Blob[], opts: {
|
|
23
|
+
audio: AudioPolicy;
|
|
24
|
+
}): Promise<Blob>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orangecatai/adgen-canvas",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/types/excalidraw/index.d.ts",
|
|
6
6
|
"main": "./dist/prod/index.js",
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
"lodash.throttle": "4.1.1",
|
|
107
107
|
"lucide-react": "0.577.0",
|
|
108
108
|
"marked": "17.0.4",
|
|
109
|
+
"mediabunny": "1.51.0",
|
|
109
110
|
"nanoid": "3.3.3",
|
|
110
111
|
"pako": "2.0.3",
|
|
111
112
|
"perfect-freehand": "1.2.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{S as a,T as b,U as c}from"../chunk-PIJUOUUJ.js";import"../chunk-FABLWJ5B.js";import"../chunk-SRAX5OIU.js";export{c as decodePngMetadata,b as encodePngMetadata,a as getTEXtChunk};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|