@vibecuting/video-project-core 0.1.29 → 0.1.31
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/package.json +9 -5
- package/src/base/BaseRemotionScene.test.tsx +11 -1
- package/src/base/index.ts +1 -0
- package/src/base/utils/asset-source.ts +11 -0
- package/src/base/utils/background-audio-layer.tsx +90 -0
- package/src/base/utils/background-layer.tsx +84 -0
- package/src/base/utils/chapter-progress-foreground.tsx +125 -0
- package/src/base/utils/chapter-progress-state.test.ts +28 -0
- package/src/base/utils/chapter-progress-state.ts +33 -0
- package/src/base/utils/display-motion.test.ts +21 -0
- package/src/base/utils/display-motion.ts +52 -0
- package/src/base/utils/display-surface.ts +57 -0
- package/src/base/utils/index.ts +10 -0
- package/src/base/utils/subtitle-style.ts +28 -0
- package/src/base/utils/video-layer-types.test.ts +145 -0
- package/src/base/utils/video-layer-types.ts +220 -0
- package/src/base/utils/voice-captions-foreground.tsx +169 -0
- package/src/core/intro/index.ts +18 -18
- package/src/core/outro/index.ts +33 -33
- package/src/core/scene/2dscene/{default-2d-scene-Horizontal.stories.tsx → default-2d-scene/default-2d-scene-Horizontal.stories.tsx} +1 -1
- package/src/core/scene/2dscene/{default-2d-scene-Horizontal.tsx → default-2d-scene/default-2d-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/2dscene/{default-2d-scene-Landscape.tsx → default-2d-scene/default-2d-scene-Landscape.tsx} +1 -1
- package/src/core/scene/2dscene/{default-2d-scene.stories.tsx → default-2d-scene/default-2d-scene.stories.tsx} +1 -1
- package/src/core/scene/2dscene/{default-2d-scene.tsx → default-2d-scene/default-2d-scene.tsx} +4 -4
- package/src/core/scene/2dscene/index.ts +3 -3
- package/src/core/scene/3dscene/{default-3d-scene-Horizontal.stories.tsx → default-3d-scene/default-3d-scene-Horizontal.stories.tsx} +1 -1
- package/src/core/scene/3dscene/{default-3d-scene-Horizontal.tsx → default-3d-scene/default-3d-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/3dscene/{default-3d-scene-Landscape.tsx → default-3d-scene/default-3d-scene-Landscape.tsx} +1 -1
- package/src/core/scene/3dscene/{default-3d-scene.stories.tsx → default-3d-scene/default-3d-scene.stories.tsx} +1 -1
- package/src/core/scene/3dscene/{default-3d-scene.tsx → default-3d-scene/default-3d-scene.tsx} +4 -4
- package/src/core/scene/3dscene/index.ts +3 -3
- package/src/core/scene/html-in-canvas/browser/default-html-in-canvas-browser-scene-Horizontal.stories.tsx +35 -0
- package/src/core/scene/html-in-canvas/browser/default-html-in-canvas-browser-scene-Landscape.stories.tsx +80 -0
- package/src/core/scene/html-in-canvas/dashboard/default-html-in-canvas-dashboard-scene-Horizontal.stories.tsx +35 -0
- package/src/core/scene/html-in-canvas/dashboard/default-html-in-canvas-dashboard-scene-Landscape.stories.tsx +35 -0
- package/src/core/scene/html-in-canvas/dashboard-shell/default-dashboard-shell-html-in-canvas-scene.stories.tsx +40 -0
- package/src/core/scene/html-in-canvas/dashboard-shell/default-dashboard-shell-html-in-canvas-scene.tsx +44 -0
- package/src/core/scene/html-in-canvas/dashboard-shell/index.ts +8 -0
- package/src/core/scene/html-in-canvas/docs/default-html-in-canvas-docs-scene-Horizontal.stories.tsx +35 -0
- package/src/core/scene/html-in-canvas/docs/default-html-in-canvas-docs-scene-Landscape.stories.tsx +35 -0
- package/src/core/scene/html-in-canvas/document/article/default-article-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/document/article/default-article-html-in-canvas-scene.tsx +50 -0
- package/src/core/scene/html-in-canvas/document/article/index.ts +8 -0
- package/src/core/scene/html-in-canvas/document/default-document-html-in-canvas-scene.stories.tsx +40 -0
- package/src/core/scene/html-in-canvas/document/default-document-html-in-canvas-scene.tsx +50 -0
- package/src/core/scene/html-in-canvas/document/index.ts +31 -0
- package/src/core/scene/html-in-canvas/document/report/default-report-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/document/report/default-report-html-in-canvas-scene.tsx +51 -0
- package/src/core/scene/html-in-canvas/document/report/index.ts +8 -0
- package/src/core/scene/html-in-canvas/document/whitepaper/default-whitepaper-html-in-canvas-scene.stories.tsx +41 -0
- package/src/core/scene/html-in-canvas/document/whitepaper/default-whitepaper-html-in-canvas-scene.tsx +50 -0
- package/src/core/scene/html-in-canvas/document/whitepaper/index.ts +8 -0
- package/src/core/scene/html-in-canvas/editor/default-html-in-canvas-editor-scene-Horizontal.stories.tsx +35 -0
- package/src/core/scene/html-in-canvas/editor/default-html-in-canvas-editor-scene-Landscape.stories.tsx +35 -0
- package/src/core/scene/html-in-canvas/full-bleed/default-full-bleed-html-in-canvas-scene.stories.tsx +40 -0
- package/src/core/scene/html-in-canvas/full-bleed/default-full-bleed-html-in-canvas-scene.tsx +38 -0
- package/src/core/scene/html-in-canvas/full-bleed/index.ts +8 -0
- package/src/core/scene/html-in-canvas/index.ts +6 -0
- package/src/core/scene/html-in-canvas/landing-page/default-landing-page-html-in-canvas-scene.stories.tsx +40 -0
- package/src/core/scene/html-in-canvas/landing-page/default-landing-page-html-in-canvas-scene.tsx +46 -0
- package/src/core/scene/html-in-canvas/landing-page/feature-grid/default-feature-grid-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/landing-page/feature-grid/default-feature-grid-html-in-canvas-scene.tsx +41 -0
- package/src/core/scene/html-in-canvas/landing-page/feature-grid/index.ts +8 -0
- package/src/core/scene/html-in-canvas/landing-page/hero/default-hero-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/landing-page/hero/default-hero-html-in-canvas-scene.tsx +46 -0
- package/src/core/scene/html-in-canvas/landing-page/hero/index.ts +8 -0
- package/src/core/scene/html-in-canvas/landing-page/index.ts +31 -0
- package/src/core/scene/html-in-canvas/landing-page/pricing/default-pricing-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/landing-page/pricing/default-pricing-html-in-canvas-scene.tsx +42 -0
- package/src/core/scene/html-in-canvas/landing-page/pricing/index.ts +8 -0
- package/src/core/scene/html-in-canvas/media-wall/collage/default-collage-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/media-wall/collage/default-collage-html-in-canvas-scene.tsx +42 -0
- package/src/core/scene/html-in-canvas/media-wall/collage/index.ts +8 -0
- package/src/core/scene/html-in-canvas/media-wall/default-media-wall-html-in-canvas-scene.stories.tsx +40 -0
- package/src/core/scene/html-in-canvas/media-wall/default-media-wall-html-in-canvas-scene.tsx +35 -0
- package/src/core/scene/html-in-canvas/media-wall/gallery/default-gallery-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/media-wall/gallery/default-gallery-html-in-canvas-scene.tsx +43 -0
- package/src/core/scene/html-in-canvas/media-wall/gallery/index.ts +8 -0
- package/src/core/scene/html-in-canvas/media-wall/grid/default-grid-html-in-canvas-scene.stories.tsx +38 -0
- package/src/core/scene/html-in-canvas/media-wall/grid/default-grid-html-in-canvas-scene.tsx +35 -0
- package/src/core/scene/html-in-canvas/media-wall/grid/index.ts +8 -0
- package/src/core/scene/html-in-canvas/media-wall/index.ts +31 -0
- package/src/core/scene/html-in-canvas/shared/default-html-in-canvas-scene.tsx +1315 -0
- package/src/core/scene/index.ts +1 -0
- package/src/core/scene/photo/3dvr-photo/{default-3dvr-photo-scene.stories.tsx → default-3dvr-photo-scene/default-3dvr-photo-scene.stories.tsx} +2 -2
- package/src/core/scene/photo/3dvr-photo/{default-3dvr-photo-scene.tsx → default-3dvr-photo-scene/default-3dvr-photo-scene.tsx} +4 -4
- package/src/core/scene/photo/3dvr-photo/{default-3dvr-photo-scene-Horizontal.stories.tsx → default-3dvr-photo-scene-Horizontal/default-3dvr-photo-scene-Horizontal.stories.tsx} +1 -1
- package/src/core/scene/photo/3dvr-photo/{default-3dvr-photo-scene-Horizontal.tsx → default-3dvr-photo-scene-Horizontal/default-3dvr-photo-scene-Horizontal.tsx} +4 -4
- package/src/core/scene/photo/3dvr-photo/{default-3dvr-photo-scene-Landscape.tsx → default-3dvr-photo-scene-Landscape/default-3dvr-photo-scene-Landscape.tsx} +4 -4
- package/src/core/scene/photo/3dvr-photo/default-dolly-3dvr-photo-scene/default-dolly-3dvr-photo-scene.stories.tsx +38 -0
- package/src/core/scene/photo/3dvr-photo/default-dolly-3dvr-photo-scene/default-dolly-3dvr-photo-scene.tsx +36 -0
- package/src/core/scene/photo/3dvr-photo/default-orbit-3dvr-photo-scene/default-orbit-3dvr-photo-scene.stories.tsx +38 -0
- package/src/core/scene/photo/3dvr-photo/default-orbit-3dvr-photo-scene/default-orbit-3dvr-photo-scene.tsx +34 -0
- package/src/core/scene/photo/3dvr-photo/default-poster-3dvr-photo-scene/default-poster-3dvr-photo-scene.stories.tsx +38 -0
- package/src/core/scene/photo/3dvr-photo/default-poster-3dvr-photo-scene/default-poster-3dvr-photo-scene.tsx +39 -0
- package/src/core/scene/photo/3dvr-photo/index.ts +6 -3
- package/src/core/scene/photo/effects-photo/default-chrome-effects-photo-scene/default-chrome-effects-photo-scene.stories.tsx +24 -0
- package/src/core/scene/photo/effects-photo/default-chrome-effects-photo-scene/default-chrome-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-cool-tone-effects-photo-scene/default-cool-tone-effects-photo-scene.stories.tsx +24 -0
- package/src/core/scene/photo/effects-photo/default-cool-tone-effects-photo-scene/default-cool-tone-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-dream-effects-photo-scene/default-dream-effects-photo-scene.stories.tsx +23 -0
- package/src/core/scene/photo/effects-photo/default-dream-effects-photo-scene/default-dream-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-duotone-effects-photo-scene/default-duotone-effects-photo-scene.stories.tsx +25 -0
- package/src/core/scene/photo/effects-photo/default-duotone-effects-photo-scene/default-duotone-effects-photo-scene.tsx +41 -0
- package/src/core/scene/photo/effects-photo/{default-effects-photo-scene.stories.tsx → default-effects-photo-scene/default-effects-photo-scene.stories.tsx} +2 -2
- package/src/core/scene/photo/effects-photo/default-effects-photo-scene/default-effects-photo-scene.tsx +639 -0
- package/src/core/scene/photo/effects-photo/{default-effects-photo-scene-Horizontal.stories.tsx → default-effects-photo-scene-Horizontal/default-effects-photo-scene-Horizontal.stories.tsx} +1 -1
- package/src/core/scene/photo/effects-photo/{default-effects-photo-scene-Horizontal.tsx → default-effects-photo-scene-Horizontal/default-effects-photo-scene-Horizontal.tsx} +4 -4
- package/src/core/scene/photo/effects-photo/{default-effects-photo-scene-Landscape.tsx → default-effects-photo-scene-Landscape/default-effects-photo-scene-Landscape.tsx} +4 -4
- package/src/core/scene/photo/effects-photo/default-glow-effects-photo-scene/default-glow-effects-photo-scene.stories.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-glow-effects-photo-scene/default-glow-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-grain-effects-photo-scene/default-grain-effects-photo-scene.stories.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-grain-effects-photo-scene/default-grain-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-halation-effects-photo-scene/default-halation-effects-photo-scene.stories.tsx +24 -0
- package/src/core/scene/photo/effects-photo/default-halation-effects-photo-scene/default-halation-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-infrared-effects-photo-scene/default-infrared-effects-photo-scene.stories.tsx +24 -0
- package/src/core/scene/photo/effects-photo/default-infrared-effects-photo-scene/default-infrared-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-light-leak-effects-photo-scene/default-light-leak-effects-photo-scene.stories.tsx +24 -0
- package/src/core/scene/photo/effects-photo/default-light-leak-effects-photo-scene/default-light-leak-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-mono-effects-photo-scene/default-mono-effects-photo-scene.stories.tsx +23 -0
- package/src/core/scene/photo/effects-photo/default-mono-effects-photo-scene/default-mono-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-noir-effects-photo-scene/default-noir-effects-photo-scene.stories.tsx +23 -0
- package/src/core/scene/photo/effects-photo/default-noir-effects-photo-scene/default-noir-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-pastel-effects-photo-scene/default-pastel-effects-photo-scene.stories.tsx +24 -0
- package/src/core/scene/photo/effects-photo/default-pastel-effects-photo-scene/default-pastel-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-retro-effects-photo-scene/default-retro-effects-photo-scene.stories.tsx +24 -0
- package/src/core/scene/photo/effects-photo/default-retro-effects-photo-scene/default-retro-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-sepia-effects-photo-scene/default-sepia-effects-photo-scene.stories.tsx +23 -0
- package/src/core/scene/photo/effects-photo/default-sepia-effects-photo-scene/default-sepia-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-soft-focus-effects-photo-scene/default-soft-focus-effects-photo-scene.stories.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-soft-focus-effects-photo-scene/default-soft-focus-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-vibrant-effects-photo-scene/default-vibrant-effects-photo-scene.stories.tsx +23 -0
- package/src/core/scene/photo/effects-photo/default-vibrant-effects-photo-scene/default-vibrant-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-vignette-effects-photo-scene/default-vignette-effects-photo-scene.stories.tsx +39 -0
- package/src/core/scene/photo/effects-photo/default-vignette-effects-photo-scene/default-vignette-effects-photo-scene.tsx +37 -0
- package/src/core/scene/photo/effects-photo/default-warmth-effects-photo-scene/default-warmth-effects-photo-scene.stories.tsx +40 -0
- package/src/core/scene/photo/effects-photo/default-warmth-effects-photo-scene/default-warmth-effects-photo-scene.tsx +39 -0
- package/src/core/scene/photo/effects-photo/index.ts +21 -3
- package/src/core/scene/photo/index.ts +25 -9
- package/src/core/scene/photo/{default-live-photo-scene-Horizontal.stories.tsx → live-photo/default-live-photo-scene-Horizontal.stories.tsx} +1 -1
- package/src/core/scene/photo/{default-live-photo-scene-Horizontal.tsx → live-photo/default-live-photo-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/photo/{default-live-photo-scene-Landscape.tsx → live-photo/default-live-photo-scene-Landscape.tsx} +1 -1
- package/src/core/scene/photo/{default-live-photo-scene.stories.tsx → live-photo/default-live-photo-scene.stories.tsx} +1 -1
- package/src/core/scene/photo/{default-live-photo-scene.tsx → live-photo/default-live-photo-scene.tsx} +5 -3
- package/src/core/scene/photo/photo-storybook.test.tsx +2 -2
- package/src/core/scene/photo/{default-photo-strip-scene-Horizontal.tsx → photo-strip/default-photo-strip-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/photo/{default-photo-strip-scene-Landscape.tsx → photo-strip/default-photo-strip-scene-Landscape.tsx} +1 -1
- package/src/core/scene/photo/{default-photo-strip-scene.stories.tsx → photo-strip/default-photo-strip-scene.stories.tsx} +1 -1
- package/src/core/scene/photo/{default-photo-strip-scene.tsx → photo-strip/default-photo-strip-scene.tsx} +2 -2
- package/src/core/scene/photo/{default-photo-wall-scene-Horizontal.tsx → photo-wall/default-photo-wall-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/photo/{default-photo-wall-scene-Landscape.tsx → photo-wall/default-photo-wall-scene-Landscape.tsx} +1 -1
- package/src/core/scene/photo/{default-photo-wall-scene.stories.tsx → photo-wall/default-photo-wall-scene.stories.tsx} +1 -1
- package/src/core/scene/photo/{default-photo-wall-scene.tsx → photo-wall/default-photo-wall-scene.tsx} +2 -2
- package/src/core/scene/slide/{default-slide-scene-Horizontal.animated.stories.tsx → default-slide-scene/default-slide-scene-Horizontal.animated.stories.tsx} +1 -1
- package/src/core/scene/slide/{default-slide-scene-Horizontal.tsx → default-slide-scene/default-slide-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/slide/{default-slide-scene-Landscape.tsx → default-slide-scene/default-slide-scene-Landscape.tsx} +1 -1
- package/src/core/scene/slide/{default-slide-scene.animated.stories.tsx → default-slide-scene/default-slide-scene.animated.stories.tsx} +1 -1
- package/src/core/scene/slide/{default-slide-scene.tsx → default-slide-scene/default-slide-scene.tsx} +5 -5
- package/src/core/scene/slide/index.ts +3 -3
- package/src/core/scene/video/{default-video-scene-Horizontal.stories.tsx → default-video-scene/default-video-scene-Horizontal.stories.tsx} +1 -1
- package/src/core/scene/video/{default-video-scene-Horizontal.tsx → default-video-scene/default-video-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/video/{default-video-scene-Landscape.tsx → default-video-scene/default-video-scene-Landscape.tsx} +1 -1
- package/src/core/scene/video/{default-video-scene.stories.tsx → default-video-scene/default-video-scene.stories.tsx} +1 -1
- package/src/core/scene/video/{default-video-scene.tsx → default-video-scene/default-video-scene.tsx} +3 -3
- package/src/core/scene/video/{default-video-split-scene-Horizontal.tsx → default-video-split-scene/default-video-split-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/video/{default-video-split-scene-Landscape.tsx → default-video-split-scene/default-video-split-scene-Landscape.tsx} +1 -1
- package/src/core/scene/video/{default-video-split-scene.stories.tsx → default-video-split-scene/default-video-split-scene.stories.tsx} +1 -1
- package/src/core/scene/video/{default-video-split-scene.tsx → default-video-split-scene/default-video-split-scene.tsx} +2 -2
- package/src/core/scene/video/{default-video-wall-scene-Horizontal.tsx → default-video-wall-scene/default-video-wall-scene-Horizontal.tsx} +1 -1
- package/src/core/scene/video/{default-video-wall-scene-Landscape.tsx → default-video-wall-scene/default-video-wall-scene-Landscape.tsx} +1 -1
- package/src/core/scene/video/{default-video-wall-scene.stories.tsx → default-video-wall-scene/default-video-wall-scene.stories.tsx} +1 -1
- package/src/core/scene/video/{default-video-wall-scene.tsx → default-video-wall-scene/default-video-wall-scene.tsx} +2 -2
- package/src/core/scene/video/index.ts +9 -9
- package/src/lint/index.ts +2 -0
- package/src/lint/scene-convention-lint.test.ts +86 -0
- package/src/lint/scene-convention-lint.ts +247 -0
- package/src/storybook/index.ts +19 -0
- package/src/storybook/remotion-preview.test.tsx +53 -0
- package/src/storybook/remotion-preview.tsx +85 -11
- package/src/core/scene/photo/effects-photo/default-effects-photo-scene.tsx +0 -352
- /package/src/core/scene/slide/{default-slide-scene-Horizontal.stories.tsx → default-slide-scene/default-slide-scene-Horizontal.stories.tsx} +0 -0
- /package/src/core/scene/slide/{default-slide-scene.stories.tsx → default-slide-scene/default-slide-scene.stories.tsx} +0 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
videoLayerBackgroundSchema,
|
|
4
|
+
videoLayerDisplaySchema,
|
|
5
|
+
videoLayerDialogueAudioManifestSchema,
|
|
6
|
+
} from "./video-layer-types";
|
|
7
|
+
import { buildVideoLayerBgmCues, getVideoLayerCueVolume } from "./background-audio-layer";
|
|
8
|
+
import { getDialogueManifestDurationInFrames } from "./voice-captions-foreground";
|
|
9
|
+
|
|
10
|
+
describe("video layer schemas", () => {
|
|
11
|
+
it("accepts image backgrounds", () => {
|
|
12
|
+
expect(
|
|
13
|
+
videoLayerBackgroundSchema.parse({
|
|
14
|
+
mode: "image",
|
|
15
|
+
baseColor: "#020617",
|
|
16
|
+
imageUrl: "https://example.com/bg.jpg",
|
|
17
|
+
imageOpacity: 0.8,
|
|
18
|
+
accentColor: "rgba(56, 189, 248, 0.4)",
|
|
19
|
+
}),
|
|
20
|
+
).toEqual({
|
|
21
|
+
mode: "image",
|
|
22
|
+
baseColor: "#020617",
|
|
23
|
+
imageUrl: "https://example.com/bg.jpg",
|
|
24
|
+
imageOpacity: 0.8,
|
|
25
|
+
accentColor: "rgba(56, 189, 248, 0.4)",
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("rejects middle chapter progress placement", () => {
|
|
30
|
+
const surface = {
|
|
31
|
+
enabled: true,
|
|
32
|
+
position: { placement: "top" as const, align: "center" as const },
|
|
33
|
+
style: {
|
|
34
|
+
fontFamily: "sans-serif",
|
|
35
|
+
fontSize: 24,
|
|
36
|
+
fontWeight: 700,
|
|
37
|
+
color: "#fff",
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
expect(() =>
|
|
42
|
+
videoLayerDisplaySchema.parse({
|
|
43
|
+
title: surface,
|
|
44
|
+
subtitles: surface,
|
|
45
|
+
chapterInfo: {
|
|
46
|
+
...surface,
|
|
47
|
+
position: { placement: "middle", align: "center" },
|
|
48
|
+
},
|
|
49
|
+
watermark: surface,
|
|
50
|
+
}),
|
|
51
|
+
).toThrow("只支持 top 或 bottom");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("accepts dialogue manifests used by voice captions", () => {
|
|
55
|
+
expect(
|
|
56
|
+
videoLayerDialogueAudioManifestSchema.parse({
|
|
57
|
+
projectId: "project-a",
|
|
58
|
+
generatedAt: "2026-06-22T00:00:00.000Z",
|
|
59
|
+
backend: "litellm",
|
|
60
|
+
fps: 30,
|
|
61
|
+
entries: [
|
|
62
|
+
{
|
|
63
|
+
chapterId: "intro",
|
|
64
|
+
chapterTitle: "Intro",
|
|
65
|
+
sceneId: "scene-1",
|
|
66
|
+
sceneTitle: "Scene 1",
|
|
67
|
+
lineIndex: 0,
|
|
68
|
+
speaker: "Narrator",
|
|
69
|
+
voice: null,
|
|
70
|
+
text: "Hello",
|
|
71
|
+
captionText: "Hello",
|
|
72
|
+
startFrame: 0,
|
|
73
|
+
durationInFrames: 45,
|
|
74
|
+
audioFile: "hello.wav",
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
}).entries,
|
|
78
|
+
).toHaveLength(1);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("background audio helpers", () => {
|
|
83
|
+
it("builds bgm cues from chapter plans and runtime timings", () => {
|
|
84
|
+
expect(
|
|
85
|
+
buildVideoLayerBgmCues(
|
|
86
|
+
[{ id: "intro", bgm: { mood: "warm", source: "assets/audio/intro.mp3", volume: 0.5 } }],
|
|
87
|
+
[{ key: "intro", startFrame: 30, durationInFrames: 90 }],
|
|
88
|
+
),
|
|
89
|
+
).toEqual([
|
|
90
|
+
{
|
|
91
|
+
id: "bgm-intro",
|
|
92
|
+
source: "assets/audio/intro.mp3",
|
|
93
|
+
startFrame: 30,
|
|
94
|
+
durationInFrames: 90,
|
|
95
|
+
volume: 0.5,
|
|
96
|
+
fadeInFrames: undefined,
|
|
97
|
+
fadeOutFrames: undefined,
|
|
98
|
+
},
|
|
99
|
+
]);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("applies cue fade in and fade out volume", () => {
|
|
103
|
+
const cue = {
|
|
104
|
+
id: "sfx",
|
|
105
|
+
source: "assets/audio/hit.wav",
|
|
106
|
+
startFrame: 0,
|
|
107
|
+
durationInFrames: 100,
|
|
108
|
+
volume: 0.8,
|
|
109
|
+
fadeInFrames: 10,
|
|
110
|
+
fadeOutFrames: 20,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
expect(getVideoLayerCueVolume(cue, 5)).toBe(0.4);
|
|
114
|
+
expect(getVideoLayerCueVolume(cue, 50)).toBe(0.8);
|
|
115
|
+
expect(getVideoLayerCueVolume(cue, 90)).toBe(0.4);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("computes dialogue manifest duration from durationMs when present", () => {
|
|
119
|
+
expect(
|
|
120
|
+
getDialogueManifestDurationInFrames({
|
|
121
|
+
projectId: "p",
|
|
122
|
+
generatedAt: "2026-06-22T00:00:00.000Z",
|
|
123
|
+
backend: "test",
|
|
124
|
+
fps: 30,
|
|
125
|
+
entries: [
|
|
126
|
+
{
|
|
127
|
+
chapterId: "intro",
|
|
128
|
+
chapterTitle: "Intro",
|
|
129
|
+
sceneId: "scene-1",
|
|
130
|
+
sceneTitle: "Scene 1",
|
|
131
|
+
lineIndex: 0,
|
|
132
|
+
speaker: "Narrator",
|
|
133
|
+
voice: null,
|
|
134
|
+
text: "Hello",
|
|
135
|
+
captionText: "Hello",
|
|
136
|
+
startFrame: 10,
|
|
137
|
+
durationInFrames: 1,
|
|
138
|
+
durationMs: 2000,
|
|
139
|
+
audioFile: "hello.wav",
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
}),
|
|
143
|
+
).toBe(70);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const videoLayerAspectRatioSchema = z.enum(["16:9", "9:16"]);
|
|
4
|
+
|
|
5
|
+
export const videoLayerResolutionSchema = z.union([
|
|
6
|
+
z.literal(1024),
|
|
7
|
+
z.literal(1080),
|
|
8
|
+
z.literal(1920),
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
export const videoLayerBackgroundSchema = z
|
|
12
|
+
.object({
|
|
13
|
+
mode: z.enum(["solid", "gradient", "image"]),
|
|
14
|
+
baseColor: z.string().min(1),
|
|
15
|
+
gradient: z.string().optional(),
|
|
16
|
+
imageUrl: z.string().optional(),
|
|
17
|
+
imageOpacity: z.number().min(0).max(1).optional(),
|
|
18
|
+
accentColor: z.string().optional(),
|
|
19
|
+
})
|
|
20
|
+
.strict();
|
|
21
|
+
|
|
22
|
+
export const videoLayerSurfaceMotionStrategySchema = z.enum([
|
|
23
|
+
"static",
|
|
24
|
+
"drift",
|
|
25
|
+
"float",
|
|
26
|
+
"loop",
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
export const videoLayerSurfaceEasingSchema = z.enum([
|
|
30
|
+
"linear",
|
|
31
|
+
"easeInOut",
|
|
32
|
+
"easeOut",
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
export const videoLayerSurfaceAlignSchema = z.enum(["left", "center", "right"]);
|
|
36
|
+
|
|
37
|
+
export const videoLayerSurfacePlacementSchema = z.enum(["top", "middle", "bottom"]);
|
|
38
|
+
|
|
39
|
+
export const videoLayerSurfacePositionSchema = z
|
|
40
|
+
.object({
|
|
41
|
+
placement: videoLayerSurfacePlacementSchema,
|
|
42
|
+
align: videoLayerSurfaceAlignSchema.optional(),
|
|
43
|
+
})
|
|
44
|
+
.strict();
|
|
45
|
+
|
|
46
|
+
export const videoLayerSurfaceMotionSchema = z
|
|
47
|
+
.object({
|
|
48
|
+
enabled: z.boolean().optional(),
|
|
49
|
+
strategy: videoLayerSurfaceMotionStrategySchema.optional(),
|
|
50
|
+
amplitudeX: z.number().optional(),
|
|
51
|
+
amplitudeY: z.number().optional(),
|
|
52
|
+
speed: z.number().optional(),
|
|
53
|
+
phase: z.number().optional(),
|
|
54
|
+
easing: videoLayerSurfaceEasingSchema.optional(),
|
|
55
|
+
})
|
|
56
|
+
.strict();
|
|
57
|
+
|
|
58
|
+
export const videoLayerSurfaceStyleSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
fontFamily: z.string(),
|
|
61
|
+
fontSize: z.number(),
|
|
62
|
+
fontWeight: z.number(),
|
|
63
|
+
color: z.string(),
|
|
64
|
+
lineHeight: z.number().optional(),
|
|
65
|
+
backgroundColor: z.string().optional(),
|
|
66
|
+
borderRadius: z.number().optional(),
|
|
67
|
+
padding: z.number().optional(),
|
|
68
|
+
maxWidth: z.number().optional(),
|
|
69
|
+
shadow: z.string().optional(),
|
|
70
|
+
opacity: z.number().optional(),
|
|
71
|
+
foregroundColor: z.string().optional(),
|
|
72
|
+
foregroundGradient: z.string().optional(),
|
|
73
|
+
})
|
|
74
|
+
.strict();
|
|
75
|
+
|
|
76
|
+
export const videoLayerSurfaceResponsiveStyleSchema = z
|
|
77
|
+
.object({
|
|
78
|
+
portrait: videoLayerSurfaceStyleSchema.partial().optional(),
|
|
79
|
+
landscape: videoLayerSurfaceStyleSchema.partial().optional(),
|
|
80
|
+
})
|
|
81
|
+
.strict();
|
|
82
|
+
|
|
83
|
+
export const videoLayerSurfaceResponsivePositionSchema = z
|
|
84
|
+
.object({
|
|
85
|
+
portrait: videoLayerSurfacePositionSchema.partial().optional(),
|
|
86
|
+
landscape: videoLayerSurfacePositionSchema.partial().optional(),
|
|
87
|
+
})
|
|
88
|
+
.strict();
|
|
89
|
+
|
|
90
|
+
export const videoLayerSurfaceSchema = z
|
|
91
|
+
.object({
|
|
92
|
+
enabled: z.boolean(),
|
|
93
|
+
position: videoLayerSurfacePositionSchema,
|
|
94
|
+
style: videoLayerSurfaceStyleSchema,
|
|
95
|
+
responsiveStyle: videoLayerSurfaceResponsiveStyleSchema.optional(),
|
|
96
|
+
responsivePosition: videoLayerSurfaceResponsivePositionSchema.optional(),
|
|
97
|
+
motion: videoLayerSurfaceMotionSchema.optional(),
|
|
98
|
+
})
|
|
99
|
+
.strict();
|
|
100
|
+
|
|
101
|
+
export const videoLayerDisplaySchema = z
|
|
102
|
+
.object({
|
|
103
|
+
title: videoLayerSurfaceSchema,
|
|
104
|
+
subtitles: videoLayerSurfaceSchema,
|
|
105
|
+
chapterInfo: videoLayerSurfaceSchema,
|
|
106
|
+
watermark: videoLayerSurfaceSchema,
|
|
107
|
+
})
|
|
108
|
+
.strict()
|
|
109
|
+
.superRefine((value, ctx) => {
|
|
110
|
+
const chapterInfo = value.chapterInfo;
|
|
111
|
+
if (chapterInfo.position.placement === "middle") {
|
|
112
|
+
ctx.addIssue({
|
|
113
|
+
code: z.ZodIssueCode.custom,
|
|
114
|
+
path: ["chapterInfo", "position", "placement"],
|
|
115
|
+
message: "只支持 top 或 bottom",
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export const videoLayerLayoutSchema = z
|
|
121
|
+
.object({
|
|
122
|
+
background: videoLayerBackgroundSchema,
|
|
123
|
+
})
|
|
124
|
+
.passthrough();
|
|
125
|
+
|
|
126
|
+
export const videoLayerDesignSchema = z
|
|
127
|
+
.object({
|
|
128
|
+
layout: videoLayerLayoutSchema,
|
|
129
|
+
display: videoLayerDisplaySchema,
|
|
130
|
+
})
|
|
131
|
+
.passthrough();
|
|
132
|
+
|
|
133
|
+
export const videoLayerChapterProgressItemSchema = z
|
|
134
|
+
.object({
|
|
135
|
+
title: z.string().min(1),
|
|
136
|
+
durationInFrames: z.number().int().positive(),
|
|
137
|
+
})
|
|
138
|
+
.strict();
|
|
139
|
+
|
|
140
|
+
export const videoLayerBackgroundMusicPlanSchema = z
|
|
141
|
+
.object({
|
|
142
|
+
mood: z.string().min(1),
|
|
143
|
+
source: z.string().optional(),
|
|
144
|
+
prompt: z.string().optional(),
|
|
145
|
+
volume: z.number().min(0).max(1).optional(),
|
|
146
|
+
fadeInFrames: z.number().int().nonnegative().optional(),
|
|
147
|
+
fadeOutFrames: z.number().int().nonnegative().optional(),
|
|
148
|
+
notes: z.string().optional(),
|
|
149
|
+
})
|
|
150
|
+
.strict();
|
|
151
|
+
|
|
152
|
+
export const videoLayerAudioCueSchema = z
|
|
153
|
+
.object({
|
|
154
|
+
id: z.string().min(1),
|
|
155
|
+
source: z.string().min(1),
|
|
156
|
+
startFrame: z.number().int().nonnegative(),
|
|
157
|
+
durationInFrames: z.number().int().positive(),
|
|
158
|
+
volume: z.number().min(0).max(1).optional(),
|
|
159
|
+
fadeInFrames: z.number().int().nonnegative().optional(),
|
|
160
|
+
fadeOutFrames: z.number().int().nonnegative().optional(),
|
|
161
|
+
})
|
|
162
|
+
.strict();
|
|
163
|
+
|
|
164
|
+
export const videoLayerDialogueAudioManifestEntrySchema = z
|
|
165
|
+
.object({
|
|
166
|
+
chapterId: z.string().min(1),
|
|
167
|
+
chapterTitle: z.string().min(1),
|
|
168
|
+
sceneId: z.string().min(1),
|
|
169
|
+
sceneTitle: z.string().min(1),
|
|
170
|
+
lineIndex: z.number().int().nonnegative(),
|
|
171
|
+
speaker: z.string().min(1),
|
|
172
|
+
voice: z.string().nullable(),
|
|
173
|
+
text: z.string().min(1),
|
|
174
|
+
captionText: z.string().min(1),
|
|
175
|
+
startFrame: z.number().int().nonnegative(),
|
|
176
|
+
durationInFrames: z.number().int().positive(),
|
|
177
|
+
durationMs: z.number().positive().optional(),
|
|
178
|
+
audioFile: z.string().min(1),
|
|
179
|
+
})
|
|
180
|
+
.strict();
|
|
181
|
+
|
|
182
|
+
export const videoLayerDialogueAudioManifestSchema = z
|
|
183
|
+
.object({
|
|
184
|
+
projectId: z.string().min(1),
|
|
185
|
+
generatedAt: z.string().min(1),
|
|
186
|
+
backend: z.string().min(1),
|
|
187
|
+
fps: z.number().int().positive(),
|
|
188
|
+
entries: z.array(videoLayerDialogueAudioManifestEntrySchema),
|
|
189
|
+
})
|
|
190
|
+
.strict();
|
|
191
|
+
|
|
192
|
+
export type VideoLayerAspectRatio = z.infer<typeof videoLayerAspectRatioSchema>;
|
|
193
|
+
export type VideoLayerResolution = z.infer<typeof videoLayerResolutionSchema>;
|
|
194
|
+
export type VideoLayerBackgroundConfig = z.infer<typeof videoLayerBackgroundSchema>;
|
|
195
|
+
export type VideoLayerSurfacePositionConfig = z.infer<typeof videoLayerSurfacePositionSchema>;
|
|
196
|
+
export type VideoLayerSurfaceMotionConfig = z.infer<typeof videoLayerSurfaceMotionSchema>;
|
|
197
|
+
export type VideoLayerSurfaceStyleConfig = z.infer<typeof videoLayerSurfaceStyleSchema>;
|
|
198
|
+
export type VideoLayerSurfaceResponsiveStyleConfig = z.infer<
|
|
199
|
+
typeof videoLayerSurfaceResponsiveStyleSchema
|
|
200
|
+
>;
|
|
201
|
+
export type VideoLayerSurfaceResponsivePositionConfig = z.infer<
|
|
202
|
+
typeof videoLayerSurfaceResponsivePositionSchema
|
|
203
|
+
>;
|
|
204
|
+
export type VideoLayerSurfaceConfig = z.infer<typeof videoLayerSurfaceSchema>;
|
|
205
|
+
export type VideoLayerDisplayConfig = z.infer<typeof videoLayerDisplaySchema>;
|
|
206
|
+
export type VideoLayerLayoutConfig = z.infer<typeof videoLayerLayoutSchema>;
|
|
207
|
+
export type VideoLayerDesign = z.infer<typeof videoLayerDesignSchema>;
|
|
208
|
+
export type VideoLayerChapterProgressItem = z.infer<
|
|
209
|
+
typeof videoLayerChapterProgressItemSchema
|
|
210
|
+
>;
|
|
211
|
+
export type VideoLayerBackgroundMusicPlan = z.infer<
|
|
212
|
+
typeof videoLayerBackgroundMusicPlanSchema
|
|
213
|
+
>;
|
|
214
|
+
export type VideoLayerAudioCue = z.infer<typeof videoLayerAudioCueSchema>;
|
|
215
|
+
export type VideoLayerDialogueAudioManifestEntry = z.infer<
|
|
216
|
+
typeof videoLayerDialogueAudioManifestEntrySchema
|
|
217
|
+
>;
|
|
218
|
+
export type VideoLayerDialogueAudioManifest = z.infer<
|
|
219
|
+
typeof videoLayerDialogueAudioManifestSchema
|
|
220
|
+
>;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Audio,
|
|
3
|
+
Sequence,
|
|
4
|
+
staticFile,
|
|
5
|
+
useCurrentFrame,
|
|
6
|
+
useVideoConfig,
|
|
7
|
+
} from "remotion";
|
|
8
|
+
import { buildVideoLayerDisplaySurfaceStyle } from "./display-surface";
|
|
9
|
+
import { resolveVideoLayerSubtitleStyle } from "./subtitle-style";
|
|
10
|
+
import type {
|
|
11
|
+
VideoLayerDesign,
|
|
12
|
+
VideoLayerDialogueAudioManifest,
|
|
13
|
+
VideoLayerDialogueAudioManifestEntry,
|
|
14
|
+
} from "./video-layer-types";
|
|
15
|
+
|
|
16
|
+
type DialogueTimelineLine = {
|
|
17
|
+
chapterId: string;
|
|
18
|
+
sceneId: string;
|
|
19
|
+
lineIndex: number;
|
|
20
|
+
speaker: string;
|
|
21
|
+
voice?: string;
|
|
22
|
+
startFrame: number;
|
|
23
|
+
durationInFrames: number;
|
|
24
|
+
audioFile: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type VideoVoiceCaptionsForegroundProps = {
|
|
28
|
+
design: VideoLayerDesign;
|
|
29
|
+
manifest: VideoLayerDialogueAudioManifest;
|
|
30
|
+
captions: Array<{
|
|
31
|
+
startMs: number;
|
|
32
|
+
endMs: number;
|
|
33
|
+
text: string;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type DialogueAudioManifestEntry = VideoLayerDialogueAudioManifestEntry;
|
|
38
|
+
export type DialogueAudioManifest = VideoLayerDialogueAudioManifest;
|
|
39
|
+
|
|
40
|
+
export const getDialogueLineDurationInFrames = (
|
|
41
|
+
entry: VideoLayerDialogueAudioManifestEntry,
|
|
42
|
+
fps: number,
|
|
43
|
+
) => {
|
|
44
|
+
if (typeof entry.durationMs === "number" && Number.isFinite(entry.durationMs)) {
|
|
45
|
+
return Math.max(1, Math.round((entry.durationMs / 1000) * fps));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return Math.max(1, entry.durationInFrames);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const getDialogueManifestDurationInFrames = (
|
|
52
|
+
manifest: VideoLayerDialogueAudioManifest,
|
|
53
|
+
) => {
|
|
54
|
+
return manifest.entries.reduce((maxEndFrame, entry) => {
|
|
55
|
+
const durationInFrames = getDialogueLineDurationInFrames(entry, manifest.fps);
|
|
56
|
+
return Math.max(maxEndFrame, entry.startFrame + durationInFrames);
|
|
57
|
+
}, 0);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const normalizeDialogueAudioFile = (audioFile: string) => {
|
|
61
|
+
const normalizedAudioFile = audioFile.replace(/^public\//, "").replace(/^\/+/, "");
|
|
62
|
+
|
|
63
|
+
return normalizedAudioFile.includes("/")
|
|
64
|
+
? normalizedAudioFile
|
|
65
|
+
: `assets/audio/${normalizedAudioFile}`;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const buildDialogueTimeline = (
|
|
69
|
+
manifest: VideoLayerDialogueAudioManifest,
|
|
70
|
+
): DialogueTimelineLine[] => {
|
|
71
|
+
return manifest.entries.map((entry) => ({
|
|
72
|
+
chapterId: entry.chapterId,
|
|
73
|
+
sceneId: entry.sceneId,
|
|
74
|
+
lineIndex: entry.lineIndex,
|
|
75
|
+
speaker: entry.speaker,
|
|
76
|
+
voice: entry.voice ?? undefined,
|
|
77
|
+
startFrame: entry.startFrame,
|
|
78
|
+
durationInFrames: getDialogueLineDurationInFrames(entry, manifest.fps),
|
|
79
|
+
audioFile: normalizeDialogueAudioFile(entry.audioFile),
|
|
80
|
+
}));
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const VideoVoiceCaptionsForeground = ({
|
|
84
|
+
design,
|
|
85
|
+
manifest,
|
|
86
|
+
captions,
|
|
87
|
+
}: VideoVoiceCaptionsForegroundProps) => {
|
|
88
|
+
const { fps, width, height } = useVideoConfig();
|
|
89
|
+
const frame = useCurrentFrame();
|
|
90
|
+
const dialogueTimeline = buildDialogueTimeline(manifest);
|
|
91
|
+
const subtitleSurface = resolveVideoLayerSubtitleStyle(design.display.subtitles, {
|
|
92
|
+
width,
|
|
93
|
+
height,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<>
|
|
98
|
+
{dialogueTimeline.map((line) => (
|
|
99
|
+
<Sequence
|
|
100
|
+
key={`${line.chapterId}-${line.sceneId}-${line.lineIndex}`}
|
|
101
|
+
from={line.startFrame}
|
|
102
|
+
durationInFrames={line.durationInFrames}
|
|
103
|
+
>
|
|
104
|
+
<Audio src={staticFile(line.audioFile)} volume={1} />
|
|
105
|
+
</Sequence>
|
|
106
|
+
))}
|
|
107
|
+
{subtitleSurface.enabled && captions.length > 0 ? (
|
|
108
|
+
<div
|
|
109
|
+
style={buildVideoLayerDisplaySurfaceStyle(subtitleSurface, frame, fps, {
|
|
110
|
+
background: "transparent",
|
|
111
|
+
padding: 0,
|
|
112
|
+
})}
|
|
113
|
+
>
|
|
114
|
+
{captions.map((caption, index) => {
|
|
115
|
+
const startFrame = Math.max(0, Math.round((caption.startMs / 1000) * fps));
|
|
116
|
+
const durationInFrames = Math.max(
|
|
117
|
+
1,
|
|
118
|
+
Math.round(((caption.endMs - caption.startMs) / 1000) * fps),
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<Sequence
|
|
123
|
+
key={`${caption.startMs}-${index}`}
|
|
124
|
+
from={startFrame}
|
|
125
|
+
durationInFrames={durationInFrames}
|
|
126
|
+
>
|
|
127
|
+
<div
|
|
128
|
+
style={{
|
|
129
|
+
display: "flex",
|
|
130
|
+
alignItems: "center",
|
|
131
|
+
justifyContent: "center",
|
|
132
|
+
width: "100%",
|
|
133
|
+
opacity: 0.96,
|
|
134
|
+
boxSizing: "border-box",
|
|
135
|
+
}}
|
|
136
|
+
>
|
|
137
|
+
<div
|
|
138
|
+
style={{
|
|
139
|
+
display: "inline-flex",
|
|
140
|
+
alignItems: "center",
|
|
141
|
+
justifyContent: "center",
|
|
142
|
+
padding: subtitleSurface.style.padding ?? 0,
|
|
143
|
+
borderRadius: subtitleSurface.style.borderRadius ?? 0,
|
|
144
|
+
background:
|
|
145
|
+
subtitleSurface.style.backgroundColor ?? "rgba(2, 6, 23, 0.86)",
|
|
146
|
+
color: subtitleSurface.style.color,
|
|
147
|
+
fontFamily: subtitleSurface.style.fontFamily,
|
|
148
|
+
fontSize: subtitleSurface.style.fontSize,
|
|
149
|
+
fontWeight: subtitleSurface.style.fontWeight,
|
|
150
|
+
lineHeight: subtitleSurface.style.lineHeight ?? 1.25,
|
|
151
|
+
maxWidth: subtitleSurface.style.maxWidth ?? "100%",
|
|
152
|
+
boxShadow: subtitleSurface.style.shadow ?? "none",
|
|
153
|
+
whiteSpace: "pre-wrap",
|
|
154
|
+
textAlign: "center",
|
|
155
|
+
}}
|
|
156
|
+
>
|
|
157
|
+
{caption.text}
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</Sequence>
|
|
161
|
+
);
|
|
162
|
+
})}
|
|
163
|
+
</div>
|
|
164
|
+
) : null}
|
|
165
|
+
</>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const VoiceCaptionsForeground = VideoVoiceCaptionsForeground;
|
package/src/core/intro/index.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
export { DefaultIntroBumper } from './default-intro-bumper'
|
|
2
|
-
export { DefaultCinematicIntroBumper } from './default-cinematic-intro-bumper'
|
|
3
|
-
export { DefaultNoirIntroBumper } from './default-noir-intro-bumper'
|
|
4
|
-
export { DefaultTrailerIntroBumper } from './default-trailer-intro-bumper'
|
|
5
|
-
export { DefaultFestivalIntroBumper } from './default-festival-intro-bumper'
|
|
6
|
-
export { DefaultWesternIntroBumper } from './western-intro'
|
|
7
|
-
export { DefaultSciFiIntroBumper } from './sci-fi-intro'
|
|
8
|
-
export { DefaultNoirIntroBumperDeluxe } from './noir-intro-deluxe'
|
|
9
|
-
export { DefaultTrailerIntroBumperPremiere } from './trailer-intro-premiere'
|
|
10
|
-
export { DefaultFestivalIntroBumperSpotlight } from './festival-intro-spotlight'
|
|
11
|
-
export { DefaultNoirIntroBumperCity } from './noir-intro-city'
|
|
12
|
-
export { DefaultCyberpunkIntroBumperNeon } from './cyberpunk-intro-neon'
|
|
13
|
-
export { DefaultWesternIntroBumperGangster } from './western-intro-gangster'
|
|
14
|
-
export { DefaultCyberpunkIntroBumperHolo } from './cyberpunk-intro-holo'
|
|
15
|
-
export { DefaultDocumentaryIntroBumper } from './documentary-intro-observation'
|
|
16
|
-
export { DefaultThrillerIntroBumper } from './thriller-intro-suspense'
|
|
17
|
-
export { DefaultFamilyIntroBumper } from './family-intro-reunion'
|
|
18
|
-
export { DefaultTravelIntroBumper } from './travel-intro-journey'
|
|
1
|
+
export { DefaultIntroBumper } from './default-intro-bumper/index'
|
|
2
|
+
export { DefaultCinematicIntroBumper } from './default-cinematic-intro-bumper/index'
|
|
3
|
+
export { DefaultNoirIntroBumper } from './default-noir-intro-bumper/index'
|
|
4
|
+
export { DefaultTrailerIntroBumper } from './default-trailer-intro-bumper/index'
|
|
5
|
+
export { DefaultFestivalIntroBumper } from './default-festival-intro-bumper/index'
|
|
6
|
+
export { DefaultWesternIntroBumper } from './western-intro/index'
|
|
7
|
+
export { DefaultSciFiIntroBumper } from './sci-fi-intro/index'
|
|
8
|
+
export { DefaultNoirIntroBumperDeluxe } from './noir-intro-deluxe/index'
|
|
9
|
+
export { DefaultTrailerIntroBumperPremiere } from './trailer-intro-premiere/index'
|
|
10
|
+
export { DefaultFestivalIntroBumperSpotlight } from './festival-intro-spotlight/index'
|
|
11
|
+
export { DefaultNoirIntroBumperCity } from './noir-intro-city/index'
|
|
12
|
+
export { DefaultCyberpunkIntroBumperNeon } from './cyberpunk-intro-neon/index'
|
|
13
|
+
export { DefaultWesternIntroBumperGangster } from './western-intro-gangster/index'
|
|
14
|
+
export { DefaultCyberpunkIntroBumperHolo } from './cyberpunk-intro-holo/index'
|
|
15
|
+
export { DefaultDocumentaryIntroBumper } from './documentary-intro-observation/index'
|
|
16
|
+
export { DefaultThrillerIntroBumper } from './thriller-intro-suspense/index'
|
|
17
|
+
export { DefaultFamilyIntroBumper } from './family-intro-reunion/index'
|
|
18
|
+
export { DefaultTravelIntroBumper } from './travel-intro-journey/index'
|
package/src/core/outro/index.ts
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
export { DefaultOutroBumper } from './default-outro-bumper'
|
|
2
|
-
export { DefaultOutroBumperLandscape, DefaultOutroBumperLandscapeMetadata } from './default-outro-bumper'
|
|
3
|
-
export { DefaultOutroBumperHorizontal, DefaultOutroBumperHorizontalMetadata } from './default-outro-bumper'
|
|
1
|
+
export { DefaultOutroBumper } from './default-outro-bumper/index'
|
|
2
|
+
export { DefaultOutroBumperLandscape, DefaultOutroBumperLandscapeMetadata } from './default-outro-bumper/index'
|
|
3
|
+
export { DefaultOutroBumperHorizontal, DefaultOutroBumperHorizontalMetadata } from './default-outro-bumper/index'
|
|
4
4
|
|
|
5
|
-
export { DefaultCreditsRollOutro } from './default-credits-roll-outro'
|
|
6
|
-
export { DefaultCreditsRollOutroLandscape, DefaultCreditsRollOutroLandscapeMetadata } from './default-credits-roll-outro'
|
|
7
|
-
export { DefaultCreditsRollOutroHorizontal, DefaultCreditsRollOutroHorizontalMetadata } from './default-credits-roll-outro'
|
|
5
|
+
export { DefaultCreditsRollOutro } from './default-credits-roll-outro/index'
|
|
6
|
+
export { DefaultCreditsRollOutroLandscape, DefaultCreditsRollOutroLandscapeMetadata } from './default-credits-roll-outro/index'
|
|
7
|
+
export { DefaultCreditsRollOutroHorizontal, DefaultCreditsRollOutroHorizontalMetadata } from './default-credits-roll-outro/index'
|
|
8
8
|
|
|
9
|
-
export { DefaultEpilogueOutro } from './default-epilogue-outro'
|
|
10
|
-
export { DefaultEpilogueOutroLandscape, DefaultEpilogueOutroLandscapeMetadata } from './default-epilogue-outro'
|
|
11
|
-
export { DefaultEpilogueOutroHorizontal, DefaultEpilogueOutroHorizontalMetadata } from './default-epilogue-outro'
|
|
9
|
+
export { DefaultEpilogueOutro } from './default-epilogue-outro/index'
|
|
10
|
+
export { DefaultEpilogueOutroLandscape, DefaultEpilogueOutroLandscapeMetadata } from './default-epilogue-outro/index'
|
|
11
|
+
export { DefaultEpilogueOutroHorizontal, DefaultEpilogueOutroHorizontalMetadata } from './default-epilogue-outro/index'
|
|
12
12
|
|
|
13
|
-
export { DefaultBlackoutOutroBumper } from './default-blackout-outro-bumper'
|
|
13
|
+
export { DefaultBlackoutOutroBumper } from './default-blackout-outro-bumper/index'
|
|
14
14
|
export {
|
|
15
15
|
DefaultBlackoutOutroBumperLandscape,
|
|
16
16
|
DefaultBlackoutOutroBumperLandscapeMetadata,
|
|
17
|
-
} from './default-blackout-outro-bumper'
|
|
17
|
+
} from './default-blackout-outro-bumper/index'
|
|
18
18
|
export {
|
|
19
19
|
DefaultBlackoutOutroBumperHorizontal,
|
|
20
20
|
DefaultBlackoutOutroBumperHorizontalMetadata,
|
|
21
|
-
} from './default-blackout-outro-bumper'
|
|
21
|
+
} from './default-blackout-outro-bumper/index'
|
|
22
22
|
|
|
23
|
-
export { DefaultSunsetOutroBumper } from './default-sunset-outro-bumper'
|
|
24
|
-
export { DefaultSunsetOutroBumperLandscape, DefaultSunsetOutroBumperLandscapeMetadata } from './default-sunset-outro-bumper'
|
|
25
|
-
export { DefaultSunsetOutroBumperHorizontal, DefaultSunsetOutroBumperHorizontalMetadata } from './default-sunset-outro-bumper'
|
|
26
|
-
export { DefaultCreditsRollOutroRoyal } from './credits-roll-outro-royal'
|
|
23
|
+
export { DefaultSunsetOutroBumper } from './default-sunset-outro-bumper/index'
|
|
24
|
+
export { DefaultSunsetOutroBumperLandscape, DefaultSunsetOutroBumperLandscapeMetadata } from './default-sunset-outro-bumper/index'
|
|
25
|
+
export { DefaultSunsetOutroBumperHorizontal, DefaultSunsetOutroBumperHorizontalMetadata } from './default-sunset-outro-bumper/index'
|
|
26
|
+
export { DefaultCreditsRollOutroRoyal } from './credits-roll-outro-royal/index'
|
|
27
27
|
export {
|
|
28
28
|
DefaultCreditsRollOutroRoyalLandscape,
|
|
29
29
|
DefaultCreditsRollOutroRoyalLandscapeMetadata,
|
|
30
|
-
} from './credits-roll-outro-royal'
|
|
30
|
+
} from './credits-roll-outro-royal/index'
|
|
31
31
|
export {
|
|
32
32
|
DefaultCreditsRollOutroRoyalHorizontal,
|
|
33
33
|
DefaultCreditsRollOutroRoyalHorizontalMetadata,
|
|
34
|
-
} from './credits-roll-outro-royal'
|
|
35
|
-
export { DefaultFestivalOutroBumper } from './festival-outro-encore'
|
|
34
|
+
} from './credits-roll-outro-royal/index'
|
|
35
|
+
export { DefaultFestivalOutroBumper } from './festival-outro-encore/index'
|
|
36
36
|
export {
|
|
37
37
|
DefaultFestivalOutroBumperLandscape,
|
|
38
38
|
DefaultFestivalOutroBumperLandscapeMetadata,
|
|
39
|
-
} from './festival-outro-encore'
|
|
39
|
+
} from './festival-outro-encore/index'
|
|
40
40
|
export {
|
|
41
41
|
DefaultFestivalOutroBumperHorizontal,
|
|
42
42
|
DefaultFestivalOutroBumperHorizontalMetadata,
|
|
43
|
-
} from './festival-outro-encore'
|
|
44
|
-
export { DefaultAwardOutroBumper } from './award-outro-celebration'
|
|
43
|
+
} from './festival-outro-encore/index'
|
|
44
|
+
export { DefaultAwardOutroBumper } from './award-outro-celebration/index'
|
|
45
45
|
export {
|
|
46
46
|
DefaultAwardOutroBumperLandscape,
|
|
47
47
|
DefaultAwardOutroBumperLandscapeMetadata,
|
|
48
|
-
} from './award-outro-celebration'
|
|
48
|
+
} from './award-outro-celebration/index'
|
|
49
49
|
export {
|
|
50
50
|
DefaultAwardOutroBumperHorizontal,
|
|
51
51
|
DefaultAwardOutroBumperHorizontalMetadata,
|
|
52
|
-
} from './award-outro-celebration'
|
|
53
|
-
export { DefaultMemoirOutroBumper } from './memoir-outro-reflection'
|
|
52
|
+
} from './award-outro-celebration/index'
|
|
53
|
+
export { DefaultMemoirOutroBumper } from './memoir-outro-reflection/index'
|
|
54
54
|
export {
|
|
55
55
|
DefaultMemoirOutroBumperLandscape,
|
|
56
56
|
DefaultMemoirOutroBumperLandscapeMetadata,
|
|
57
|
-
} from './memoir-outro-reflection'
|
|
57
|
+
} from './memoir-outro-reflection/index'
|
|
58
58
|
export {
|
|
59
59
|
DefaultMemoirOutroBumperHorizontal,
|
|
60
60
|
DefaultMemoirOutroBumperHorizontalMetadata,
|
|
61
|
-
} from './memoir-outro-reflection'
|
|
61
|
+
} from './memoir-outro-reflection/index'
|
|
62
62
|
|
|
63
63
|
export {
|
|
64
64
|
DefaultHeistOutroBumper,
|
|
@@ -66,9 +66,9 @@ export {
|
|
|
66
66
|
DefaultHeistOutroBumperLandscapeMetadata,
|
|
67
67
|
DefaultHeistOutroBumperHorizontal,
|
|
68
68
|
DefaultHeistOutroBumperHorizontalMetadata,
|
|
69
|
-
} from './heist-outro'
|
|
70
|
-
export { DefaultRomanceOutroBumper } from './romance-outro'
|
|
71
|
-
export { DefaultBlackoutOutroBumperFinale } from './blackout-outro-finale'
|
|
72
|
-
export { DefaultSunsetOutroBumperCoda } from './sunset-outro-coda'
|
|
73
|
-
export { DefaultCreditsRollOutroPremium } from './credits-roll-outro-premium'
|
|
74
|
-
export { DefaultCreditsRollOutroEpic } from './credits-roll-outro-epic'
|
|
69
|
+
} from './heist-outro/index'
|
|
70
|
+
export { DefaultRomanceOutroBumper } from './romance-outro/index'
|
|
71
|
+
export { DefaultBlackoutOutroBumperFinale } from './blackout-outro-finale/index'
|
|
72
|
+
export { DefaultSunsetOutroBumperCoda } from './sunset-outro-coda/index'
|
|
73
|
+
export { DefaultCreditsRollOutroPremium } from './credits-roll-outro-premium/index'
|
|
74
|
+
export { DefaultCreditsRollOutroEpic } from './credits-roll-outro-epic/index'
|