Skip to main content

compositing

使用 Remotion 合成最终视频。当需要将片头、录屏、配音、片尾组合成完整视频时使用。包含动画效果、时间线管理、多尺寸模板和故障处理。

الانتقال إلى التثبيت

معلومات المصدر

المستودع
MatrixReligio/ProductVideoCreator
آخر نشاط في المصدر
٢٦ يناير ٢٠٢٦ في ٠٥:٢٠
لغة SKILL.md المكتشفة
الصينية
النجوم
٤١
التفرعات
٨

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
compositing
description
使用 Remotion 合成最终视频。当需要将片头、录屏、配音、片尾组合成完整视频时使用。包含动画效果、时间线管理、多尺寸模板和故障处理。
# 视频合成技能 ## 快速开始:使用模板 项目提供了可复用的配置和组件模板,位于 `templates/` 目录: ```bash templates/ ├── config/ # 配置模板 │ ├── scenes.ts # 场景时间配置 │ ├── theme.ts # 主题颜色配置 │ ├── types.ts # TypeScript 类型定义 │ ├── videoPresets.ts # 多尺寸视频预设 │ └── index.ts # 统一导出 └── components/ # 组件模板 ├── SubtitleDisplay.tsx # 字幕组件 ├── AnimatedText.tsx # 动画文字组件 ├── BackgroundEffects.tsx # 背景效果组件 ├── BrandElements.tsx # 品牌元素组件 ├── useResponsive.ts # 响应式 Hook └── index.ts # 统一导出 ``` ### 使用方法 1. 复制模板到项目目录: ```bash cp -r templates/config src/config cp -r templates/components src/components ``` 2. 根据项目需要修改配置(颜色、场景时间等) 3. 在组件中导入使用: ```tsx import { SCENES, FPS, VIDEO_DURATION } from "./config"; import { THEME, getGlowStyle } from "./config"; import { SubtitleDisplay, FadeInText, ParticleField } from "./components"; ``` --- ## 多尺寸视频模板 ### 预设尺寸 | 名称 | 分辨率 | 比例 | 适用平台 | |------|--------|------|----------| | 1080p (默认) | 1920×1080 | 16:9 | YouTube, 官网 | | 720p | 1280×720 | 16:9 | 快速预览, 低带宽 | | vertical | 1080×1920 | 9:16 | 抖音, 小红书, Reels | | square | 1080×1080 | 1:1 | Instagram, 微信 | | 4K | 3840×2160 | 16:9 | 高端展示 | ### Remotion 多尺寸配置 ```tsx // videoPresets.ts export const VIDEO_PRESETS = { "1080p": { width: 1920, height: 1080, name: "Full HD" }, "720p": { width: 1280, height: 720, name: "HD" }, "vertical": { width: 1080, height: 1920, name: "Vertical" }, "square": { width: 1080, height: 1080, name: "Square" }, "4k": { width: 3840, height: 2160, name: "4K" }, } as const; export type VideoPreset = keyof typeof VIDEO_PRESETS; ``` ### Root.tsx 多尺寸定义 ```tsx import { Composition } from "remotion"; import { MainVideo } from "./MainVideo"; import { VIDEO_PRESETS, VideoPreset } from "./videoPresets"; const FPS = 30; const DURATION_SECONDS = 85; export const RemotionRoot: React.FC = () => { return ( <> {/* 为每个尺寸创建 Composition */} {Object.entries(VIDEO_PRESETS).map(([key, preset]) => ( <Composition key={key} id={`Video-${key}`} component={MainVideo} durationInFrames={DURATION_SECONDS * FPS} fps={FPS} width={preset.width} height={preset.height} defaultProps={{ preset: key as VideoPreset }} /> ))} </> ); }; ``` ### 响应式组件适配 ```tsx // 根据视频尺寸调整布局 const ResponsiveLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => { const { width, height } = useVideoConfig(); const aspectRatio = width / height; // 竖屏布局 (9:16) if (aspectRatio < 1) { return ( <AbsoluteFill style={{ flexDirection: "column", padding: "60px 40px" }}> {children} </AbsoluteFill> ); } // 方形布局 (1:1) if (aspectRatio === 1) { return ( <AbsoluteFill style={{ padding: "40px" }}> {children} </AbsoluteFill> ); } // 横屏布局 (16:9) return ( <AbsoluteFill style={{ padding: "60px 120px" }}> {children} </AbsoluteFill> ); }; ``` ### 字体大小适配 ```tsx // 根据分辨率计算字体大小 const getResponsiveFontSize = (baseSize: number): number => { const { width, height } = useVideoConfig(); const scale = Math.min(width / 1920, height / 1080); return Math.round(baseSize * scale); }; // 使用示例 const title = getResponsiveFontSize(72); // 1080p 下 72px ``` ### 批量渲染脚本 ```bash #!/bin/bash # render_all_sizes.sh SIZES=("1080p" "720p" "vertical" "square") OUTPUT_DIR="out" for size in "${SIZES[@]}"; do echo "渲染 $size..." npx remotion render src/index.ts "Video-$size" "$OUTPUT_DIR/video_$size.mp4" done echo "所有尺寸渲染完成!" ``` --- ## Remotion 基础 Remotion 是 React-based 的视频渲染框架,使用 React 组件定义视频内容。 ### 核心概念 | 概念 | 说明 | |------|------| | Composition | 视频组合定义(分辨率、帧率、时长) | | Sequence | 时间序列,控制内容出现时机 | | useCurrentFrame | 获取当前帧数 | | interpolate | 数值插值,用于动画 | | spring | 弹性动画 | ### 基本结构 ```tsx import { Composition } from "remotion"; export const RemotionRoot = () => { return ( <Composition id="FinalVideo" component={FinalVideo} durationInFrames={2550} // 85秒 * 30fps fps={30} width={1920} height={1080} /> ); }; ``` ## 故障处理 (重要) ### 浏览器下载失败 **问题表现**: ``` Error: Tried to download file xxx, but the server sent no data for 20 seconds ``` **解决方案 A: 手动下载 Chrome Headless Shell** ```bash # 1. 手动下载 (更长超时) curl -L --connect-timeout 30 --max-time 300 \ "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/mac-arm64/chrome-headless-shell-mac-arm64.zip" \ -o /tmp/chrome-headless-shell.zip # 2. 解压到 Remotion 缓存目录 mkdir -p ~/.cache/remotion unzip /tmp/chrome-headless-shell.zip -d ~/.cache/remotion/ # 3. 渲染时指定浏览器路径 npx remotion render src/index.ts VideoId out/video.mp4 \ --browser-executable="$HOME/.cache/remotion/chrome-headless-shell-mac-arm64/chrome-headless-shell" ``` **解决方案 B: 使用代理** ```bash export HTTP_PROXY=http://your-proxy:port export HTTPS_PROXY=http://your-proxy:port npx remotion browser ensure ``` ### 其他常见问题 | 问题 | 解决方案 | |------|----------| | Chrome 下载失败 | 手动下载或使用代理 | | 视频文件找不到 | 确保在 `public/` 目录,用 `staticFile()` | | 渲染内存不足 | `--concurrency=4` 减少并发 | | 字体不显示 | 使用 `@remotion/google-fonts` | ## 字体配置 ### 使用 Google Fonts (推荐) ```bash npm install @remotion/google-fonts ``` ```tsx // 加载中文字体 import { loadFont } from "@remotion/google-fonts/NotoSansSC"; const { fontFamily } = loadFont(); // 在组件中使用 <div style={{ fontFamily }}>中文文字</div> ``` ### 推荐中文字体 | 字体 | 包名 | 风格 | |------|------|------| | Noto Sans SC | NotoSansSC | 现代无衬线 | | Noto Serif SC | NotoSerifSC | 经典衬线 | | ZCOOL XiaoWei | ZCOOLXiaoWei | 手写风格 | ### 备选:系统字体栈 ```tsx const fontFamily = ` "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", system-ui, sans-serif `; ``` ## 高级动画模式 ### 1. Logo 弹性缩放 + 发光 ```tsx const LogoWithGlow: React.FC<{ src: string }> = ({ src }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const scale = spring({ frame, fps, config: { damping: 12, stiffness: 100 }, }); const glowIntensity = interpolate( Math.sin(frame * 0.08), [-1, 1], [0.3, 0.8] ); return ( <div style={{ transform: `scale(${scale})`, filter: `drop-shadow(0 0 ${40 * glowIntensity}px #76B900)`, }} > <Img src={src} style={{ width: 400 }} /> </div> ); }; ``` ### 2. 文字淡入 + 上移 ```tsx const FadeInText: React.FC<{ text: string; delay?: number }> = ({ text, delay = 0, }) => { const frame = useCurrentFrame(); const opacity = interpolate(frame, [delay, delay + 30], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", }); const translateY = interpolate(frame, [delay, delay + 30], [20, 0], { extrapolateLeft: "clamp", extrapolateRight: "clamp", }); return ( <div style={{ opacity, transform: `translateY(${translateY}px)`, }} > {text} </div> ); }; ``` ### 3. 打字机效果 ```tsx const TypewriterText: React.FC<{ text: string; speed?: number }> = ({ text, speed = 3, }) => { const frame = useCurrentFrame(); const charsToShow = Math.floor( interpolate(frame, [0, text.length * speed], [0, text.length], { extrapolateRight: "clamp", }) ); return <span>{text.slice(0, charsToShow)}</span>; }; ``` ### 4. 年份大字弹入 ```tsx const YearDisplay: React.FC<{ year: string; color?: string }> = ({ year, color = "#76B900", }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const scale = spring({ frame, fps, config: { damping: 15, stiffness: 80 }, }); return ( <div style={{ fontSize: 200, fontWeight: "bold", color, transform: `scale(${scale})`, textShadow: `0 0 60px ${color}`, }} > {year} </div> ); }; ``` ### 5. 背景图渐变叠加 ```tsx const BackgroundWithOverlay: React.FC<{ src: string; opacity?: number; }> = ({ src, opacity = 0.3 }) => { return ( <> <AbsoluteFill> <Img src={staticFile(src)} style={{ width: "100%", height: "100%", objectFit: "cover", opacity, }} /> </AbsoluteFill> {/* 渐变叠加层 */} <AbsoluteFill style={{ background: "linear-gradient(180deg, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0.8) 100%)", }} /> </> ); }; ``` ### 6. 数据卡片动画 ```tsx const DataCard: React.FC<{ value: string; label: string; delay: number;
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub