@gorenku/compositions 0.1.3
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/browser.d.ts +5 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +3 -0
- package/dist/compositions/documentary/KenBurnsClip.d.ts +8 -0
- package/dist/compositions/documentary/KenBurnsClip.d.ts.map +1 -0
- package/dist/compositions/documentary/KenBurnsClip.js +30 -0
- package/dist/compositions/documentary/KenBurnsEffectFrame.d.ts +8 -0
- package/dist/compositions/documentary/KenBurnsEffectFrame.d.ts.map +1 -0
- package/dist/compositions/documentary/KenBurnsEffectFrame.js +24 -0
- package/dist/compositions/documentary/VideoClipSequence.d.ts +12 -0
- package/dist/compositions/documentary/VideoClipSequence.d.ts.map +1 -0
- package/dist/compositions/documentary/VideoClipSequence.js +63 -0
- package/dist/compositions/documentary/VideoComposition.d.ts +10 -0
- package/dist/compositions/documentary/VideoComposition.d.ts.map +1 -0
- package/dist/compositions/documentary/VideoComposition.js +79 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/lib/remotion/remap-speed.d.ts +6 -0
- package/dist/lib/remotion/remap-speed.d.ts.map +1 -0
- package/dist/lib/remotion/remap-speed.js +13 -0
- package/dist/remotion/documentary-root.d.ts +9 -0
- package/dist/remotion/documentary-root.d.ts.map +1 -0
- package/dist/remotion/documentary-root.js +37 -0
- package/dist/remotion/entry.d.ts +2 -0
- package/dist/remotion/entry.d.ts.map +1 -0
- package/dist/remotion/entry.js +3 -0
- package/dist/remotion/index.d.ts +2 -0
- package/dist/remotion/index.d.ts.map +1 -0
- package/dist/remotion/index.js +1 -0
- package/dist/types/timeline.d.ts +78 -0
- package/dist/types/timeline.d.ts.map +1 -0
- package/dist/types/timeline.js +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { TimelineDocument, TimelineTrack, ImageTrack, AudioTrack, MusicTrack, VideoTrack, CaptionsTrack, UnknownTrack, TimelineClip, ImageClip, AudioClip, MusicClip, VideoClip, CaptionsClip, KenBurnsEffect, AssetMap, } from "./types/timeline.js";
|
|
2
|
+
export { remapSpeed } from "./lib/remotion/remap-speed.js";
|
|
3
|
+
export { DocumentaryComposition, type DocumentaryCompositionProps } from "./compositions/documentary/VideoComposition.js";
|
|
4
|
+
export { DOCUMENTARY_COMPOSITION_ID, DocumentaryRoot } from "./remotion/index.js";
|
|
5
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,KAAK,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAC1H,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ImageClip, AssetMap } from "../../types/timeline.js";
|
|
2
|
+
interface KenBurnsClipProps {
|
|
3
|
+
clip: ImageClip;
|
|
4
|
+
assets: AssetMap;
|
|
5
|
+
}
|
|
6
|
+
export declare const KenBurnsClip: ({ clip, assets }: KenBurnsClipProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=KenBurnsClip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KenBurnsClip.d.ts","sourceRoot":"","sources":["../../../src/compositions/documentary/KenBurnsClip.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnE,UAAU,iBAAiB;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,QAAQ,CAAC;CAClB;AAWD,eAAO,MAAM,YAAY,GAAI,kBAAkB,iBAAiB,mDAmC/D,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AbsoluteFill, Sequence, useVideoConfig } from "remotion";
|
|
3
|
+
import { KenBurnsEffectFrame } from "./KenBurnsEffectFrame.js";
|
|
4
|
+
const allocateFrames = (totalFrames, segments) => {
|
|
5
|
+
if (segments <= 0) {
|
|
6
|
+
return [totalFrames];
|
|
7
|
+
}
|
|
8
|
+
const base = Math.floor(totalFrames / segments);
|
|
9
|
+
const remainder = totalFrames % segments;
|
|
10
|
+
return Array.from({ length: segments }, (_, index) => base + (index < remainder ? 1 : 0));
|
|
11
|
+
};
|
|
12
|
+
export const KenBurnsClip = ({ clip, assets }) => {
|
|
13
|
+
const { fps } = useVideoConfig();
|
|
14
|
+
const effects = clip.properties.effects ?? [];
|
|
15
|
+
if (effects.length === 0) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const totalFrames = Math.max(1, Math.round(clip.duration * fps));
|
|
19
|
+
const segments = allocateFrames(totalFrames, effects.length);
|
|
20
|
+
const offsets = segments.map((_, index) => segments.slice(0, index).reduce((sum, value) => sum + value, 0));
|
|
21
|
+
return (_jsx(AbsoluteFill, { children: effects.map((effect, index) => {
|
|
22
|
+
const frames = segments[index] ?? 1;
|
|
23
|
+
const from = offsets[index] ?? 0;
|
|
24
|
+
const assetUrl = assets[effect.assetId];
|
|
25
|
+
if (!assetUrl) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return (_jsx(Sequence, { from: from, durationInFrames: frames, children: _jsx(KenBurnsEffectFrame, { effect: effect, imageUrl: assetUrl }) }, `${clip.id}-${effect.assetId}-${index}`));
|
|
29
|
+
}) }));
|
|
30
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { KenBurnsEffect } from "../../types/timeline.js";
|
|
2
|
+
interface KenBurnsEffectFrameProps {
|
|
3
|
+
effect: KenBurnsEffect;
|
|
4
|
+
imageUrl: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const KenBurnsEffectFrame: ({ effect, imageUrl }: KenBurnsEffectFrameProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=KenBurnsEffectFrame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KenBurnsEffectFrame.d.ts","sourceRoot":"","sources":["../../../src/compositions/documentary/KenBurnsEffectFrame.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,UAAU,wBAAwB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,mBAAmB,GAAI,sBAAsB,wBAAwB,4CA8BjF,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AbsoluteFill, Img, interpolate, useCurrentFrame, useVideoConfig } from "remotion";
|
|
3
|
+
export const KenBurnsEffectFrame = ({ effect, imageUrl }) => {
|
|
4
|
+
const frame = useCurrentFrame();
|
|
5
|
+
const { durationInFrames } = useVideoConfig();
|
|
6
|
+
const maxFrames = Math.max(1, durationInFrames);
|
|
7
|
+
const progress = maxFrames <= 1 ? 0 : frame / (maxFrames - 1);
|
|
8
|
+
const startScale = effect.startScale ?? 1;
|
|
9
|
+
const endScale = effect.endScale ?? startScale;
|
|
10
|
+
const startX = effect.startX ?? 0;
|
|
11
|
+
const endX = effect.endX ?? startX;
|
|
12
|
+
const startY = effect.startY ?? 0;
|
|
13
|
+
const endY = effect.endY ?? startY;
|
|
14
|
+
const scale = interpolate(progress, [0, 1], [startScale, endScale]);
|
|
15
|
+
const translateX = interpolate(progress, [0, 1], [startX, endX]);
|
|
16
|
+
const translateY = interpolate(progress, [0, 1], [startY, endY]);
|
|
17
|
+
return (_jsx(AbsoluteFill, { style: { justifyContent: "center", alignItems: "center", overflow: "hidden" }, children: _jsx(Img, { src: imageUrl, style: {
|
|
18
|
+
width: "100%",
|
|
19
|
+
height: "100%",
|
|
20
|
+
objectFit: "cover",
|
|
21
|
+
transform: `scale(${scale}) translate(${translateX}px, ${translateY}px)`,
|
|
22
|
+
transition: "none",
|
|
23
|
+
} }) }));
|
|
24
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AssetMap, VideoClip } from "../../types/timeline.js";
|
|
2
|
+
interface VideoClipSequenceProps {
|
|
3
|
+
clip: VideoClip;
|
|
4
|
+
assets: AssetMap;
|
|
5
|
+
fps: number;
|
|
6
|
+
from: number;
|
|
7
|
+
durationInFrames: number;
|
|
8
|
+
premountFor: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const VideoClipSequence: ({ clip, assets, fps, from, durationInFrames, premountFor, }: VideoClipSequenceProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=VideoClipSequence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoClipSequence.d.ts","sourceRoot":"","sources":["../../../src/compositions/documentary/VideoClipSequence.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEnE,UAAU,sBAAsB;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,QAAQ,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAID,eAAO,MAAM,iBAAiB,GAAI,6DAO/B,sBAAsB,mDA0CxB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AbsoluteFill, OffthreadVideo, Sequence, useCurrentFrame } from "remotion";
|
|
3
|
+
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
4
|
+
export const VideoClipSequence = ({ clip, assets, fps, from, durationInFrames, premountFor, }) => {
|
|
5
|
+
const assetId = clip.properties.assetId;
|
|
6
|
+
if (!assetId) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const assetSrc = assets[assetId];
|
|
10
|
+
if (!assetSrc) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const sourceUrl = `${assetSrc}#disable`;
|
|
14
|
+
const fitStrategy = clip.properties.fitStrategy ?? "stretch";
|
|
15
|
+
const volume = typeof clip.properties.volume === "number" ? clip.properties.volume : 0;
|
|
16
|
+
const originalDuration = clip.properties.originalDuration ?? clip.duration;
|
|
17
|
+
const originalFrames = Math.max(1, Math.round(originalDuration * fps));
|
|
18
|
+
const playbackRate = fitStrategy === "stretch" && clip.duration > 0 && originalDuration > 0
|
|
19
|
+
? originalDuration / clip.duration
|
|
20
|
+
: 1;
|
|
21
|
+
const localFrame = clamp(useCurrentFrame() - from, 0, durationInFrames);
|
|
22
|
+
return (_jsx(Sequence, { from: from, durationInFrames: durationInFrames, premountFor: premountFor, children: _jsxs(AbsoluteFill, { children: [renderVideoContent({
|
|
23
|
+
sourceUrl,
|
|
24
|
+
volume,
|
|
25
|
+
playbackRate,
|
|
26
|
+
fitStrategy,
|
|
27
|
+
durationInFrames,
|
|
28
|
+
}), fitStrategy === "freeze-fade" ? (_jsx(FreezeFadeOverlay, { localFrame: localFrame, durationInFrames: durationInFrames, originalFrames: originalFrames })) : null] }) }));
|
|
29
|
+
};
|
|
30
|
+
function renderVideoContent(args) {
|
|
31
|
+
const { sourceUrl, volume, playbackRate, fitStrategy } = args;
|
|
32
|
+
if (fitStrategy === "stretch") {
|
|
33
|
+
return (_jsx(OffthreadVideo, { src: sourceUrl, muted: volume === 0, volume: volume, playbackRate: playbackRate, style: { width: "100%", height: "100%", objectFit: "cover" } }));
|
|
34
|
+
}
|
|
35
|
+
return (_jsx(OffthreadVideo, { src: sourceUrl, muted: volume === 0, volume: volume, playbackRate: 1, startFrom: 0, style: { width: "100%", height: "100%", objectFit: "cover" } }));
|
|
36
|
+
}
|
|
37
|
+
function FreezeFadeOverlay({ localFrame, durationInFrames, originalFrames, }) {
|
|
38
|
+
if (durationInFrames === originalFrames) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
if (originalFrames < durationInFrames) {
|
|
42
|
+
const freezeStart = originalFrames;
|
|
43
|
+
const fadeFrames = Math.max(1, durationInFrames - originalFrames);
|
|
44
|
+
const progress = clamp((localFrame - freezeStart) / fadeFrames, 0, 1);
|
|
45
|
+
if (progress <= 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return (_jsx(AbsoluteFill, { style: {
|
|
49
|
+
backgroundColor: "black",
|
|
50
|
+
opacity: progress,
|
|
51
|
+
} }));
|
|
52
|
+
}
|
|
53
|
+
const fadeFrames = Math.max(1, Math.min(originalFrames - durationInFrames, durationInFrames));
|
|
54
|
+
const fadeStart = Math.max(0, durationInFrames - fadeFrames);
|
|
55
|
+
const progress = clamp((localFrame - fadeStart) / fadeFrames, 0, 1);
|
|
56
|
+
if (progress <= 0) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return (_jsx(AbsoluteFill, { style: {
|
|
60
|
+
backgroundColor: "black",
|
|
61
|
+
opacity: progress,
|
|
62
|
+
} }));
|
|
63
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AssetMap, TimelineDocument } from "../../types/timeline.js";
|
|
2
|
+
export interface DocumentaryCompositionProps {
|
|
3
|
+
timeline: TimelineDocument;
|
|
4
|
+
assets: AssetMap;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
fps?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const DocumentaryComposition: ({ timeline, assets }: DocumentaryCompositionProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=VideoComposition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoComposition.d.ts","sourceRoot":"","sources":["../../../src/compositions/documentary/VideoComposition.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EAIR,gBAAgB,EAGjB,MAAM,yBAAyB,CAAC;AAIjC,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAID,eAAO,MAAM,sBAAsB,GAAI,sBAAsB,2BAA2B,4CAQvF,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AbsoluteFill, Audio, Sequence, useVideoConfig } from "remotion";
|
|
3
|
+
import { KenBurnsClip } from "./KenBurnsClip.js";
|
|
4
|
+
import { VideoClipSequence } from "./VideoClipSequence.js";
|
|
5
|
+
const secondsToFrames = (seconds, fps) => Math.max(1, Math.round(seconds * fps));
|
|
6
|
+
export const DocumentaryComposition = ({ timeline, assets }) => {
|
|
7
|
+
const { fps } = useVideoConfig();
|
|
8
|
+
return (_jsx(AbsoluteFill, { style: { backgroundColor: "black" }, children: timeline.tracks.map((track) => renderTrack(track, assets, fps)) }));
|
|
9
|
+
};
|
|
10
|
+
function renderTrack(track, assets, fps) {
|
|
11
|
+
if (isImageTrack(track)) {
|
|
12
|
+
return renderImageTrack(track, assets, fps);
|
|
13
|
+
}
|
|
14
|
+
if (isAudioTrack(track)) {
|
|
15
|
+
return renderAudioTrack(track, assets, fps);
|
|
16
|
+
}
|
|
17
|
+
if (isMusicTrack(track)) {
|
|
18
|
+
return renderMusicTrack(track, assets, fps);
|
|
19
|
+
}
|
|
20
|
+
if (isVideoTrack(track)) {
|
|
21
|
+
return renderVideoTrack(track, assets, fps);
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function isImageTrack(track) {
|
|
26
|
+
return track.kind === "Image";
|
|
27
|
+
}
|
|
28
|
+
function isAudioTrack(track) {
|
|
29
|
+
return track.kind === "Audio";
|
|
30
|
+
}
|
|
31
|
+
function isMusicTrack(track) {
|
|
32
|
+
return track.kind === "Music";
|
|
33
|
+
}
|
|
34
|
+
function isVideoTrack(track) {
|
|
35
|
+
return track.kind === "Video";
|
|
36
|
+
}
|
|
37
|
+
function renderImageTrack(track, assets, fps) {
|
|
38
|
+
return track.clips.map((clip) => {
|
|
39
|
+
const from = secondsToFrames(clip.startTime, fps);
|
|
40
|
+
const durationInFrames = secondsToFrames(clip.duration, fps);
|
|
41
|
+
return (_jsx(Sequence, { from: from, durationInFrames: durationInFrames, children: _jsx(KenBurnsClip, { clip: clip, assets: assets }) }, clip.id));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function renderAudioTrack(track, assets, fps) {
|
|
45
|
+
return track.clips.map((clip) => {
|
|
46
|
+
const assetId = clip.properties.assetId;
|
|
47
|
+
const src = assets[assetId];
|
|
48
|
+
if (!assetId || !src) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const from = secondsToFrames(clip.startTime, fps);
|
|
52
|
+
const durationInFrames = secondsToFrames(clip.duration, fps);
|
|
53
|
+
const volume = clip.properties.volume ?? 1;
|
|
54
|
+
const premountFor = Math.max(1, Math.round(fps * 0.5));
|
|
55
|
+
return (_jsx(Sequence, { from: from, durationInFrames: durationInFrames, premountFor: premountFor, children: _jsx(Audio, { src: src, volume: volume }) }, clip.id));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function renderMusicTrack(track, assets, fps) {
|
|
59
|
+
return track.clips.map((clip) => {
|
|
60
|
+
const assetId = clip.properties.assetId;
|
|
61
|
+
const src = assets[assetId];
|
|
62
|
+
if (!assetId || !src) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const from = secondsToFrames(clip.startTime, fps);
|
|
66
|
+
const durationInFrames = secondsToFrames(clip.duration, fps);
|
|
67
|
+
const volume = clip.properties.volume ?? 1;
|
|
68
|
+
const premountFor = Math.max(1, Math.round(fps * 0.5));
|
|
69
|
+
return (_jsx(Sequence, { from: from, durationInFrames: durationInFrames, premountFor: premountFor, children: _jsx(Audio, { src: src, volume: volume }) }, clip.id));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function renderVideoTrack(track, assets, fps) {
|
|
73
|
+
return track.clips.map((clip) => {
|
|
74
|
+
const from = secondsToFrames(clip.startTime, fps);
|
|
75
|
+
const durationInFrames = secondsToFrames(clip.duration, fps);
|
|
76
|
+
const premountFor = Math.max(1, Math.round(fps * 0.5));
|
|
77
|
+
return (_jsx(VideoClipSequence, { clip: clip, assets: assets, fps: fps, from: from, durationInFrames: durationInFrames, premountFor: premountFor }, clip.id));
|
|
78
|
+
});
|
|
79
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { TimelineDocument, TimelineTrack, ImageTrack, AudioTrack, MusicTrack, VideoTrack, CaptionsTrack, UnknownTrack, TimelineClip, ImageClip, AudioClip, MusicClip, VideoClip, CaptionsClip, KenBurnsEffect, AssetMap, } from "./types/timeline.js";
|
|
2
|
+
export { remapSpeed } from "./lib/remotion/remap-speed.js";
|
|
3
|
+
export { DocumentaryComposition, type DocumentaryCompositionProps } from "./compositions/documentary/VideoComposition.js";
|
|
4
|
+
export { DOCUMENTARY_COMPOSITION_ID, DocumentaryRoot } from "./remotion/index.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,KAAK,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAC1H,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remap-speed.d.ts","sourceRoot":"","sources":["../../../src/lib/remotion/remap-speed.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAUtE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps a composition frame to the corresponding source frame when playing
|
|
3
|
+
* a video at a constant speed multiplier.
|
|
4
|
+
*/
|
|
5
|
+
export function remapSpeed(frame, playbackRate) {
|
|
6
|
+
if (!Number.isFinite(frame) || frame <= 0) {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
if (!Number.isFinite(playbackRate) || playbackRate <= 0) {
|
|
10
|
+
return frame;
|
|
11
|
+
}
|
|
12
|
+
return frame * playbackRate;
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DocumentaryCompositionProps } from "../compositions/documentary/VideoComposition.js";
|
|
2
|
+
export declare const DOCUMENTARY_COMPOSITION_ID: "DocumentaryComposition";
|
|
3
|
+
export type DocumentaryCompositionInputProps = DocumentaryCompositionProps & {
|
|
4
|
+
width?: number;
|
|
5
|
+
height?: number;
|
|
6
|
+
fps?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const DocumentaryRoot: () => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=documentary-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentary-root.d.ts","sourceRoot":"","sources":["../../src/remotion/documentary-root.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iDAAiD,CAAC;AAEnG,eAAO,MAAM,0BAA0B,EAAG,wBAAiC,CAAC;AAM5E,MAAM,MAAM,gCAAgC,GAAG,2BAA2B,GAAG;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAmBF,eAAO,MAAM,eAAe,+CA0B3B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Composition } from "remotion";
|
|
3
|
+
import { DocumentaryComposition } from "../compositions/documentary/VideoComposition.js";
|
|
4
|
+
export const DOCUMENTARY_COMPOSITION_ID = "DocumentaryComposition";
|
|
5
|
+
const DEFAULT_WIDTH = 1920;
|
|
6
|
+
const DEFAULT_HEIGHT = 1080;
|
|
7
|
+
const DEFAULT_FPS = 30;
|
|
8
|
+
const defaultProps = {
|
|
9
|
+
timeline: {
|
|
10
|
+
id: "placeholder",
|
|
11
|
+
duration: 1,
|
|
12
|
+
tracks: [],
|
|
13
|
+
},
|
|
14
|
+
assets: {},
|
|
15
|
+
width: DEFAULT_WIDTH,
|
|
16
|
+
height: DEFAULT_HEIGHT,
|
|
17
|
+
fps: DEFAULT_FPS,
|
|
18
|
+
};
|
|
19
|
+
const DocumentaryComponent = (props) => {
|
|
20
|
+
const input = props;
|
|
21
|
+
return _jsx(DocumentaryComposition, { ...input });
|
|
22
|
+
};
|
|
23
|
+
export const DocumentaryRoot = () => (_jsx(Composition, { id: DOCUMENTARY_COMPOSITION_ID, component: DocumentaryComponent, width: defaultProps.width, height: defaultProps.height, fps: defaultProps.fps, durationInFrames: Math.max(1, Math.round(defaultProps.timeline.duration * defaultProps.fps)), defaultProps: defaultProps, calculateMetadata: ({ props }) => {
|
|
24
|
+
const input = props;
|
|
25
|
+
const width = input.width ?? DEFAULT_WIDTH;
|
|
26
|
+
const height = input.height ?? DEFAULT_HEIGHT;
|
|
27
|
+
const fps = input.fps ?? DEFAULT_FPS;
|
|
28
|
+
const timelineDuration = input.timeline?.duration ?? 1;
|
|
29
|
+
const durationInFrames = Math.max(1, Math.round(timelineDuration * fps));
|
|
30
|
+
return {
|
|
31
|
+
width,
|
|
32
|
+
height,
|
|
33
|
+
fps,
|
|
34
|
+
durationInFrames,
|
|
35
|
+
props,
|
|
36
|
+
};
|
|
37
|
+
} }));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/remotion/entry.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/remotion/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DocumentaryRoot, DOCUMENTARY_COMPOSITION_ID } from "./documentary-root.js";
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export type TimelineTrackKind = "Image" | "Audio" | "Music" | "Video" | "Captions";
|
|
2
|
+
export interface TimelineDocument {
|
|
3
|
+
id: string;
|
|
4
|
+
duration: number;
|
|
5
|
+
name?: string;
|
|
6
|
+
movieId?: string;
|
|
7
|
+
movieTitle?: string;
|
|
8
|
+
assetFolder?: {
|
|
9
|
+
source?: string;
|
|
10
|
+
rootPath?: string;
|
|
11
|
+
};
|
|
12
|
+
tracks: TimelineTrack[];
|
|
13
|
+
}
|
|
14
|
+
export type TimelineTrack = ImageTrack | AudioTrack | MusicTrack | VideoTrack | CaptionsTrack | UnknownTrack;
|
|
15
|
+
interface TimelineTrackBase<TKind extends string, TClip extends TimelineClip> {
|
|
16
|
+
id: string;
|
|
17
|
+
kind: TKind;
|
|
18
|
+
clips: TClip[];
|
|
19
|
+
}
|
|
20
|
+
interface TimelineClipBase<TKind extends string, TProps extends Record<string, unknown>> {
|
|
21
|
+
id: string;
|
|
22
|
+
kind: TKind;
|
|
23
|
+
startTime: number;
|
|
24
|
+
duration: number;
|
|
25
|
+
properties: TProps;
|
|
26
|
+
}
|
|
27
|
+
export interface KenBurnsEffect {
|
|
28
|
+
name?: string;
|
|
29
|
+
style?: string;
|
|
30
|
+
assetId: string;
|
|
31
|
+
startX?: number;
|
|
32
|
+
startY?: number;
|
|
33
|
+
endX?: number;
|
|
34
|
+
endY?: number;
|
|
35
|
+
startScale?: number;
|
|
36
|
+
endScale?: number;
|
|
37
|
+
}
|
|
38
|
+
export type ImageClip = TimelineClipBase<"Image", {
|
|
39
|
+
effect?: string;
|
|
40
|
+
effects: KenBurnsEffect[];
|
|
41
|
+
}>;
|
|
42
|
+
export type AudioClip = TimelineClipBase<"Audio", {
|
|
43
|
+
assetId: string;
|
|
44
|
+
volume?: number;
|
|
45
|
+
fadeInDuration?: number;
|
|
46
|
+
fadeOutDuration?: number;
|
|
47
|
+
}>;
|
|
48
|
+
export type MusicClip = TimelineClipBase<"Music", {
|
|
49
|
+
assetId: string;
|
|
50
|
+
volume?: number;
|
|
51
|
+
duration?: "full" | "match";
|
|
52
|
+
play?: "loop" | "no-loop";
|
|
53
|
+
}>;
|
|
54
|
+
export type VideoClip = TimelineClipBase<"Video", {
|
|
55
|
+
assetId: string;
|
|
56
|
+
originalDuration?: number;
|
|
57
|
+
fitStrategy?: string;
|
|
58
|
+
volume?: number;
|
|
59
|
+
}>;
|
|
60
|
+
export type CaptionsClip = TimelineClipBase<"Captions", {
|
|
61
|
+
assetId?: string;
|
|
62
|
+
captions?: string[];
|
|
63
|
+
partitionBy?: number;
|
|
64
|
+
captionAlgorithm?: string;
|
|
65
|
+
}>;
|
|
66
|
+
export type UnknownClip = TimelineClipBase<string, Record<string, unknown>>;
|
|
67
|
+
export type TimelineClip = ImageClip | AudioClip | MusicClip | VideoClip | CaptionsClip | UnknownClip;
|
|
68
|
+
export type ImageTrack = TimelineTrackBase<"Image", ImageClip>;
|
|
69
|
+
export type AudioTrack = TimelineTrackBase<"Audio", AudioClip>;
|
|
70
|
+
export type MusicTrack = TimelineTrackBase<"Music", MusicClip>;
|
|
71
|
+
export type VideoTrack = TimelineTrackBase<"Video", VideoClip>;
|
|
72
|
+
export type CaptionsTrack = TimelineTrackBase<"Captions", CaptionsClip>;
|
|
73
|
+
export type UnknownTrack = TimelineTrackBase<string, TimelineClip>;
|
|
74
|
+
export interface AssetMap {
|
|
75
|
+
[canonicalId: string]: string;
|
|
76
|
+
}
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/types/timeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gorenku/compositions",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Shared Remotion compositions and renderers for Renku",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./browser": {
|
|
22
|
+
"types": "./dist/browser.d.ts",
|
|
23
|
+
"default": "./dist/browser.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"type-check": "tsc --noEmit",
|
|
29
|
+
"dev": "tsc --watch"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@remotion/bundler": "4.0.382",
|
|
33
|
+
"@remotion/cli": "4.0.382",
|
|
34
|
+
"@remotion/renderer": "4.0.382",
|
|
35
|
+
"react": "19.2.1",
|
|
36
|
+
"react-dom": "19.2.1",
|
|
37
|
+
"remotion": "4.0.382",
|
|
38
|
+
"serve-handler": "^6.1.6"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/react": "^19.2.7",
|
|
42
|
+
"@types/react-dom": "^19.2.3",
|
|
43
|
+
"typescript": "~5.9.3"
|
|
44
|
+
}
|
|
45
|
+
}
|