Giới thiệu
Video cho phép chúng ta thiết lập sự uy tín và tạo cảm giác cá nhân hơn cho thông điệp của mình. Nó giúp chúng ta kết nối với cảm xúc của khán giả. React là một thư viện JavaScript tuyệt vời để mô tả giao diện người dùng thay đổi theo thời gian. Để tạo nội dung video một cách lập trình với React.js, chúng ta sẽ sử dụng một công cụ tuyệt vời có tên là Remotion.
Hãy cùng khám phá cách chúng ta có thể đạt được điều này.
Github
Xem kho lưu trữ GitHub này để có mã nguồn đầy đủ.
Codesandbox
Bạn có thể xem dự án hoàn chỉnh trên Codesandbox.
Yêu cầu trước
Dưới đây là một số yêu cầu bạn cần đáp ứng để theo dõi bài viết này:
- Kiến thức cơ bản về JavaScript
- Kiến thức cơ bản về React.js
Thiết lập Dự án Mẫu
Trong thư mục bạn chọn, tạo một dự án remotion mới bằng cách sử dụng:
bashCopy codeyarn create video
Bạn có thể muốn chọn mẫu được đề xuất, nhưng cho mục đích của bài viết này, hãy chọn một mẫu trống. Chạy lệnh:
yarn start
Điều này sẽ khởi động máy chủ phát triển cục bộ của bạn. Bạn sẽ thấy một cửa sổ như sau:
Ở bên trái, chúng ta có một thanh bên hiển thị tất cả các composition cho dự án, cho phép bạn cô lập và kiểm tra từng cảnh trong video. Mỗi composition là một component có thể render. Composition được tạo thành từ các sequence, chỉ định cho video biết nên hiển thị nội dung trong các khung hình nào. Điểm vào của một dự án remotion là file index.tsx
, tại đây chúng ta gọi hàm registerRoot(RemotionVideo);
nằm trong Video.tsx
.
Một số showcases của remotion
https://www.remotion.dev/showcase
Bắt đầu
Mở file Video.tsx
. File này chứa component RemotionVideo
. Bạn có thể coi component này như toàn bộ video của mình.
export const RemotionVideo: React.FC = () => {
return (
<>
<Composition
id="Empty"
component={MyComposition}
durationInFrames={450}
fps={30}
width={1280}
height={720}
/>
</>
);
};
Một video về cơ bản được tạo thành từ một hoặc nhiều composition. Bên trong composition, chúng ta định nghĩa các thuộc tính video như:
durationInFrames
: số khung hình mà video sẽ cófps
: số khung hình mỗi giâywidth
vàheight
: kích thước video tính bằng pixel
Khi nói về khung hình, bạn có thể nghĩ về nó như một hình ảnh tĩnh tại một điểm cụ thể trong video.
id
xác định composition trong trình phát video và tham chiếu đến component chứa giao diện người dùng mà bạn muốn hiển thị. Các thuộc tính width
và height
được sử dụng để thay đổi độ phân giải của video, ví dụ: để thay đổi độ phân giải thành chế độ dọc:
width={1080}
height={1920}
Độ dài thực tế của video tính bằng giây dựa trên fps
:
durationInFrames / fps = length(s)
Điều này có nghĩa rằng trong demo này, video của chúng ta dài 15 giây:
450 / 30 = 15
Tùy chỉnh Video
Chúng ta sẽ tạo một component mới tên là Main
ngay bên dưới component RemotionVideo
:
const Main = () => {
return <h1>Welcome to Cloudinary!</h1>;
};
Để xem điều này trên trình duyệt, bạn cần thay đổi giá trị của id
từ id="Empty"
thành id="Main"
, và giá trị của component thành component={Main}
. Khi bạn thay đổi giá trị id
, bạn cũng cần thay đổi file package.json
:
jsonCopy code"build": "remotion render src/index.tsx Main out/video.mp4"
Khi mở trình phát video, bạn sẽ thấy video với dòng chữ Welcome to Cloudinary. Để chỉnh sửa CSS của video một cách lập trình, hãy sử dụng CSS inline:
const Main = () => {
return (
<div style={{ backgroundColor: 'white', flexGrow: 1 }}>
<h1
style={{
position: 'absolute',
top: '50%',
width: '100%',
textAlign: 'center',
fontSize: '5rem',
}}
>
Welcome to Cloudinary!
</h1>
</div>
);
};
Chúng ta có thể tạo ba component cho video này: Title
, SubTitle
và Image
, sau đó gọi chúng bên trong component Main
.
const Title = () => {
return (
<h1
style={{
position: 'absolute',
top: '50%',
width: '100%',
textAlign: 'center',
fontSize: '5rem',
}}
>
Welcome to Cloudinary!
</h1>
);
};
const SubTitle = () => {
return (
<h3
style={{
position: 'absolute',
top: '60%',
width: '100%',
textAlign: 'center',
fontSize: '3rem',
}}
>
Transform images and videos to load faster with no visual degradation, automatically generate image and video variants, and deliver high quality responsive experiences to increase conversions.
</h3>
);
};
Để thêm hình ảnh và render chúng, chúng ta cần sử dụng thẻ Img
được import từ Remotion:
import { Composition, Img } from 'remotion';
import cloudinary from './cloudinary.png';
Chúng ta có thể tạo component Image
:
const Image = () => {
return (
<Img
src={cloudinary}
alt="cloudinary"
style={{
display: 'block',
marginLeft: 'auto',
marginRight: 'auto',
width: '30%',
height: '50%',
}}
/>
);
};
const Main = () => {
return (
<div style={{ backgroundColor: 'white', flexGrow: 1 }}>
<Title />
<Image />
<SubTitle />
</div>
);
};
Hiện tại, mọi thứ chúng ta cần cho video đã được thiết lập, nhưng chúng ta cần thêm một số hiệu ứng để làm cho video trở nên thú vị và hấp dẫn hơn.
Animation
Để tạo nên toàn bộ đoạn video, chúng ta sẽ sử dụng các Sequence. Đây là những phần nhỏ riêng lẻ trong thời gian hữu hạn tạo nên toàn bộ video. Chúng ta chỉ định thời gian mà một component xuất hiện bằng cách sử dụng from={0}
(bắt đầu từ giây 0). Bạn cũng có thể chỉ định thời gian component biến mất bằng thuộc tính durationInFrames={60}
.
<div style={{ backgroundColor: 'white', flexGrow: 1 }}>
<Sequence from={0}>
<Image />
</Sequence>
<Sequence from={60}>
<Title />
</Sequence>
<Sequence from={120}>
<SubTitle />
</Sequence>
</div>
Thêm Âm Thanh Cho Video
Chúng ta có thể thêm âm thanh bằng cách sử dụng thẻ <Audio />
trong Remotion. Hãy thêm một component AudVoice
để render giọng nói:
import { Composition, Img, Audio } from 'remotion';
import voice from './voice.mp3';
// phần còn lại của code
const AudVoice = () => {
return <Audio src={voice} startFrom={0} endAt={30 * 15} />;
};
Remotion cung cấp nhiều hook khác nhau cho phép chúng ta lấy dữ liệu về video.
useVideoConfig()
cho phép chúng ta lấy dữ liệu vềfps
,durationInFrames
,width
vàheight
. Chúng ta có thể sử dụng nó để tính toán các giá trị cho việc animation các khung hình.useCurrentFrame()
cung cấp khung hình hiện tại và timeline. Những khung hình này sẽ được render lại cho mỗi thời điểm trong video.
Hiện tại, video của bạn đang hoạt động tốt, nhưng chúng ta cần sử dụng dữ liệu về video thay cho các số 0, 60 và 90. Import useVideoConfig
từ remotion:
const Main = () => {
const { fps, durationInFrames } = useVideoConfig();
return (
<div style={{ backgroundColor: 'white', flexGrow: 1 }}>
<Sequence from={fps * 0.3} durationInFrames={durationInFrames}>
<Image />
</Sequence>
<Sequence from={fps} durationInFrames={durationInFrames}>
<AudVoice />
</Sequence>
<Sequence from={fps} durationInFrames={durationInFrames}>
<Title />
</Sequence>
<Sequence from={fps * 2} durationInFrames={durationInFrames}>
<SubTitle />
</Sequence>
</div>
);
};
Hiệu Ứng Fade-In Cho SubTitle
Hãy làm cho animation của chúng ta hấp dẫn hơn với hiệu ứng fade-in. Chúng ta sẽ sử dụng hook useCurrentFrame()
như sau:
const SubTitle = () => {
const frame = useCurrentFrame();
const opacity = frame > 30 ? 1 : frame / 30;
return (
<h3
style={{
position: 'absolute',
top: '60%',
width: '100%',
textAlign: 'center',
fontSize: '3rem',
opacity,
}}
>
Transform images and videos to load faster with no visual degradation, automatically generate image and video variants, and deliver high quality responsive experiences to increase conversions.
</h3>
);
};
useCurrentFrame
trả về khung hình hiện tại, trong ngữ cảnh này là SubTitle
trong sequence.
Chúng ta muốn opacity
bằng 0 ở đầu, sau đó tăng dần lên 1. Nếu frame
lớn hơn 30, trả về opacity
là 1; ngược lại, opacity
sẽ là frame / 30
.
Hiệu Ứng Bounce Cho Image
const Image = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const translate = spring({ frame, fps, to: 100 });
return (
<Img
src={cloudinary}
alt="cloudinary"
style={{
display: 'block',
marginLeft: 'auto',
marginRight: 'auto',
width: '30%',
height: '50%',
transform: `translateY(${translate}px)`,
}}
/>
);
};
Hàm spring
làm cho component của chúng ta bật lên từ một điểm đến một điểm. Chúng ta lấy fps
từ hook như trên. Hàm này nhận vào frame
và fps
để biết tốc độ di chuyển, from
và to
để xác định phạm vi bạn muốn, với from
có giá trị mặc định là 0.
Build Dự Án
Để build dự án, chạy lệnh sau trên terminal:
yarn build
hoặc
npm run build
Điều này yêu cầu bạn cài đặt ffmpeg
. Terminal sẽ cung cấp hướng dẫn về cách cấu hình nó trên máy của bạn.
Khi hoàn tất, bạn sẽ tìm thấy video bên trong thư mục out
của dự án.
Nhấn vào liên kết này để xem video cuối cùng.
Kết luận
Thật tuyệt vời! Trong bài viết này, chúng ta đã tạo được một video dài 15 giây mà không cần sử dụng bất kỳ công cụ chỉnh sửa video nào, chỉ với React. Thật đáng kinh ngạc khi chúng ta có thể tạo video bằng React, phải không?