你好美丽的人!是的,你没看错标题。在本文中,您将学习如何使用 React 创建视频。

确实,我们使用很少的视频编辑工具来创建视频。想象一下用 React 创建一个?借助 Remotion,现在可以使用 React 创建视频。

什么是Remotion?

Remotion 是一套库,为使用 React 以编程方式创建视频奠定了基础。简而言之,您可以通过编写代码来创建动画视频。

安装

我们需要为 Remotion 安装两个核心依赖项——Node.js 和 FFmpeg。

  • 安装 Node.js

  • 安装FFmpeg

安装 Node.js 和 FFmpeg 后,您就可以开始使用 Remotion。

您可以使用初始化新的 Remotion 视频

npm init video

或者

yarn create video

Linux 用户的附加步骤

Linux 用户需要安装一些额外的软件包才能使 Chrome/Puppeteer 正常工作。

Ubuntu

apt install -y gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libgbm-dev

拱形 Linux

sudo pacman -S dconf alsa-lib atk glibc cairo libcups dbus expat fontconfig gcc gdk-pixbuf2 glib2 gtk3 nspr pango gcc-libs libx11 libxcomposite libxcursor libxdamage libxext libxfixes libxi libxrandr libxrender libxss libxtst ca-certificates ttf-liberation libappindicator-gtk3 nss lsb-release xdg-utils wget mesa

这样就完成了你第一个remotion项目的初始化,你可以使用npm start或者yarn start启动项目

基础知识

让我们看一些 Remotion 基础知识以创建视频。

useVideoConfig提供对您正在制作的视频的特定信息的访问。它还返回一个包含视频属性的对象,以便它们可以跨组件使用。

  • width:合成的宽度(以像素为单位)。

  • height:合成的高度(以像素为单位)。

  • fps:合成的帧速率,以每秒帧数为单位。

  • durationInFrames:合成的持续时间,以帧为单位。

这些属性可用于配置组件的大小(以像素为单位)、帧速率和持续时间(以帧为单位)。

useCurrentFrame返回标识视频当前帧的整数。

spring功能可以让您创建漂亮的春天动画。

interpolate函数允许您使用简洁的语法将一系列值映射到另一个值,使动画更具可读性。它需要四个输入参数-

  • 输入值

  • 您期望输入假定的值的范围

  • 您希望输入映射到的输出值范围

  • 可选参数

Sequence是一个高阶组件,它允许您对动画的某些部分进行时移,从而使它们更易于重用。它还接受以下道具 -

  • from:一个必需的整数,指示序列从哪个帧开始。当序列在frame时,它的孩子在帧0

  • durationInFrames:以帧为单位的序列分量的长度。

  • name:这是一个可选道具,将在 Remotion 预览的时间轴中显示为序列的标签。

  • layout:这是一个可选属性,可以是absolute-fillnone。默认情况下,序列将被绝对定位,因此它们将相互重叠。您可以通过none来自定义行为。

Composition是一个注册视频以使其可渲染并显示在 Remotion 播放器侧边栏中的组件。除了两个额外的道具idcomponentlazyComponent之外,它还采用useVideoConfig返回的对象中包含的相同的道具 -

  • id:合成的 ID,如侧边栏所示,也是合成的唯一标识符,如果要渲染它,您需要指定它。 ID只能包含字母、数字和-

  • componentlazyComponent- 这是带有动画的 React 组件或返回动态导入的函数。不传递任何一个或两个道具都是错误的。

registerRoot函数是 Remotion 项目的根组件,它应该返回一个或多个包装在 React 片段中的组合。

现在您对 Remotion 的关键属性和组件有了基本的了解,我们可以开始制作视频了。

用 Remotion 创建一个简单的视频

我们将创建一个简单的视频,其中显示 Hashnode 徽标和一些带有动画的文本。

首先,在src文件夹中创建三个组件,分别为Logo.tsxTitle.tsxSubtitle.tsx

Logo.tsx

import {interpolate, spring, useCurrentFrame, useVideoConfig, Img, Audio} from 'remotion';

import Icon from './hashnode.png';
import audio from './audio.mp3'

export const Logo: React.FC<{
    transitionStart: number;
}> = ({transitionStart}) => {

    const videoConfig = useVideoConfig();
    const frame = useCurrentFrame();

    const scaleIn = spring({
        frame,
        config: {
            mass: 0.5,
        },
        fps: videoConfig.fps,
    });

    const translation = interpolate(
        spring({
            frame: frame - transitionStart,
            fps: videoConfig.fps,
            config: {
                damping: 100,
                mass: 0.5,
            },
        }),
        [0, 1],
        [0, -100]
    );

    const scale = frame < 50 ? scaleIn : 1;

    return (
        <div
            style={{
                textAlign: 'center',
                marginTop: '15%',
                width: videoConfig.width,
                height: videoConfig.height,
                transform: `scale(${scale}) translateY(${translation}px)`
            }}
        >
            <Img src={Icon} />
            <Audio src={audio} />
        </div>
    );
};

该组件使用spring参数和interpolate辅助函数结合scaleIntranslation弹簧函数来创建动画。

使用Audio组件,您可以将音频添加到您的视频中。该组件支持 Chromium 支持的所有音频格式。

Title.tsx

import {spring, useCurrentFrame, useVideoConfig} from 'remotion';

import "./font.css";

export const Title: React.FC<{
    titleText: string;
    titleColor: string;
}> = ({titleText, titleColor}) => {
    const videoConfig = useVideoConfig();
    const frame = useCurrentFrame();
    const text = titleText.split(' ').map((t) => ` ${t} `);
    return (
        <h1
            style={{
                fontFamily: 'Inter',
                fontWeight: 'bold',
                fontSize: 100,
                textAlign: 'center',
                position: 'absolute',
                bottom: 200,
                width: '100%',
            }}
        >
            {text.map((t, i) => {
                return (
                    <span
                        key={t}
                        style={{
                            marginLeft: 10,
                            marginRight: 10,
                            transform: `scale(${spring({
                                fps: videoConfig.fps,
                                frame: frame - i * 5,
                                config: {
                                    damping: 100,
                                    stiffness: 100,
                                    mass: 0.5,
                                },
                            })})`,
                            display: 'inline-block',
                        }}
                    >
                        {t}
                    </span>
                );
            })}
        </h1>
    );
};

这个组件有两个 props -titleTexttitleColor。使用 text 函数将titleText转换为数组。text.map函数使用弹簧动画分别渲染每个单词。

您可以通过使用@font-face将自定义字体加载到 CSS 文件中来使用它们。 Web 字体通常附带声明字体的 CSS 文件,您可以使用@import语句导入该文件。

Subtitle.tsx

Subtitle组件还与interpolate函数一起为文本设置动画。


import {interpolate, useCurrentFrame} from 'remotion';

import "./font.css";

export const Subtitle: React.FC = () => {
    const frame = useCurrentFrame();
    const opacity = interpolate(frame, [0, 30], [0, 1]);
    return (
        <div
            style={{
                fontFamily: 'Inter',
                fontWeight: 500,
                fontSize: 45,
                textAlign: 'center',
                position: 'absolute',
                bottom: 140,
                width: '100%',
                opacity,
            }}
        >
            Start blogging with Hashnode today 
            <span
                style={{
                    color: '#2962ff',
                    fontWeight: 700
                }}
            >
                 hashnode.com
            </span>
        </div>
    );
};

序列

我们现在已经完成了基本组件的设置,因此我们可以在序列和合成中使用它们来创建我们的最终视频。如上所述,我们使用序列来对视频的所有组件进行时移和排列。

创建一个名为DemoVideo.tsx的组件,并导入上述三个组件并用Sequence组件包装它们。

import {interpolate, Sequence, useCurrentFrame, useVideoConfig} from 'remotion';
import {Logo} from './Logo';
import {Title} from './Title';
import {Subtitle} from './Subtitle';

export const DemoVideo: React.FC<{
    titleText: string;
    titleColor: string;
}> = ({titleText, titleColor}) => {
    const frame = useCurrentFrame();
    const videoConfig = useVideoConfig();

    const opacity = interpolate(
        frame,
        [videoConfig.durationInFrames - 25, videoConfig.durationInFrames - 15],
        [1, 0],
        {
            extrapolateLeft: 'clamp',
            extrapolateRight: 'clamp',
        }
    );
    const transitionStart = 25;

    return (
        <div style={{flex: 1, backgroundColor: 'white'}}>
            <div style={{opacity}}>
                <Sequence from={0} durationInFrames={videoConfig.durationInFrames}>
                    <Logo transitionStart={transitionStart} />
                </Sequence>
                <Sequence from={transitionStart + 10} durationInFrames={Infinity}>
                    <Title titleText={titleText} titleColor={titleColor} />
                </Sequence>
                <Sequence from={transitionStart + 50} durationInFrames={Infinity}>
                    <Subtitle />
                </Sequence>
            </div>
        </div>
    );
};

每个序列都有一个不同的from值,表示它在组合剪辑中的时间轴上的位置,组合剪辑将包含所有三个动画组件。

组成

接下来,通过使用Composition,我们可以将我们的剪辑渲染为 MP4 文件,并使其可在 Remotion 的播放器中查看。

创建一个名为Video.tsx的组件并导入要注册的组件。每个组件在各自的component属性下被馈送到Composition组件中。

包括所有视频属性以及任何其他道具。将所有组合包装在一个 React 片段中,并将其导入到根组件index.tsx中。

Video.tsx

import {Composition} from 'remotion';
import {DemoVideo} from './DemoVideo';
import {Logo} from './Logo';
import {Title} from './Title';
import {Subtitle} from './Subtitle';

export const RemotionVideo: React.FC = () => {
    return (
        <>
            <Composition
                id="DemoVideo"
                component={DemoVideo}
                durationInFrames={150}
                fps={30}
                width={1920}
                height={1080}
                defaultProps={{
                    titleText: 'I ❤️ Hashnode',
                    titleColor: '#333333',
                }}
            />
            <Composition
                id="Logo"
                component={Logo}
                durationInFrames={200}
                fps={30}
                width={1920}
                height={1080}
            />
            <Composition
                id="Title"
                component={Title}
                durationInFrames={100}
                fps={30}
                width={1920}
                height={1080}
                defaultProps={{
                    titleText: 'Welcome to Remotion',
                    titleColor: 'black',
                }}
            />
            <Composition
                id="Subtitle"
                component={Subtitle}
                durationInFrames={100}
                fps={30}
                width={1920}
                height={1080}
            />
        </>
    );
};

index.tsx

import {registerRoot} from 'remotion';
import {RemotionVideo} from './Video';

registerRoot(RemotionVideo);

在您的浏览器中,当您通过运行npm start运行应用程序时,您将看到一个视频播放器,其中可以单独播放不同的作品。

Remotin-HN.png

您可以在 Remotion 播放器中播放和暂停视频,并查看每个动画在时间轴中的位置。您还可以根据自己的喜好调整视频视图。

通过运行渲染和导出您的最终视频 -

npm run build

或者

yarn build

这将运行 package.json 中的底层命令 -

npx remotion render src/index.tsx HelloWorld out/video.mp4

瞧,你刚刚用 React 创建了一个视频。

结论

Remotion 是一个令人难以置信的工具,由Jonny Burger创建。我第一次听说这件事时,就让我大吃一惊。你绝对应该试一试。它也是一个开源项目。

访问remotion.dev和Jonny Burger 的 YouTube 频道以了解有关 Remotion 的更多信息。

感谢您阅读这篇文章。在那之前,要快乐并保持安全。

快乐编码🚀

Logo

ModelScope旨在打造下一代开源的模型即服务共享平台,为泛AI开发者提供灵活、易用、低成本的一站式模型服务产品,让模型应用更简单!

更多推荐