- Remotion composition (ShortsVideo) renders 1080x1920 9:16 shorts from script segments (hook/setup/conflict/insight/cta) with animated gradient background, word-by-word captions, progress bar - render-worker.mjs: standalone poller (systemd hermyhq-render.service) TTS via edge-tts → Remotion render via Chrome headless → ffmpeg mux + thumbnail; ≤60s gate; marks YoutubeScript rendered - API: POST /api/youtube/render (queue approved→render_queued), GET status, GET /render/file (stream video/thumb with Range support) - Schema: YoutubeScript.videoUrl/thumbnailUrl + YoutubeRender model - UI: youtube tab gains Renders view (preview/review/approve/reject/ download), Render Shorts button on approved scripts - Prisma db push applied to prod DB
26 lines
706 B
TypeScript
26 lines
706 B
TypeScript
import { registerRoot, Composition } from "remotion";
|
|
import { ShortsVideo, useTotalDuration } from "./ShortsVideo";
|
|
|
|
const DEFAULT_SEGMENTS = [
|
|
{ text: "Demo shorts — configure --props to customize.", duration: 60 },
|
|
];
|
|
|
|
const Shorts: React.FC = () => {
|
|
return (
|
|
<Composition
|
|
id="Shorts"
|
|
component={ShortsVideo as any}
|
|
durationInFrames={60}
|
|
fps={30}
|
|
width={1080}
|
|
height={1920}
|
|
defaultProps={{ segments: DEFAULT_SEGMENTS }}
|
|
calculateMetadata={({ props }) => {
|
|
const segs = props.segments?.length ? props.segments : DEFAULT_SEGMENTS;
|
|
return { durationInFrames: useTotalDuration(segs) };
|
|
}}
|
|
/>
|
|
);
|
|
};
|
|
|
|
registerRoot(Shorts); |