Remotion LabRemotion Lab
渲染輸出渲染產物(Artifacts)

輸出渲染產物(Artifacts)

使用 <Artifact> 元件在渲染影片時同時產生附帶檔案,例如字幕 .srt 檔案、章節文字、授權資訊等。

輸出渲染產物(Artifacts)

v4.0.176

有時你希望在渲染影片時產生額外的檔案。例如:

  • 一個 .srt 字幕檔案
  • 一個包含影片章節的 .txt 檔案
  • 影片中使用的資源的 CREDITS 檔案
  • 渲染的除錯資訊

你可以使用 <Artifact> 元件從你的影片中輸出任意檔案。

注意@remotion/cloudrun 目前不支援輸出產物。

範例

// MyComp.tsx
import React from 'react';
import { Artifact, useCurrentFrame } from 'remotion';
import { generateSubtitles } from './subtitles';
 
export const MyComp: React.FC = () => {
  const frame = useCurrentFrame();
 
  return (
    <>
      {frame === 0 ? (
        <Artifact filename="captions.srt" content={generateSubtitles()} />
      ) : null}
    </>
  );
};

產物的規則

  1. 資源只應在影片的單一幀進行渲染。 否則,資源將被多次輸出。
  2. 可以輸出多個資源,但它們的檔案名稱不得相同。
  3. 對於 content prop,可以傳入 string,或傳入 Uint8Array 作為二進位資料。 傳入 Uint8Array 不應被認為更快,因為它必須被序列化。

輸出縮圖 v4.0.290

你可以將目前幀的圖像資料作為產物輸出。

輸出第一幀作為縮圖

import { Artifact, useCurrentFrame } from 'remotion';
 
export const MyComp: React.FC = () => {
  const frame = useCurrentFrame();
 
  return (
    <>
      {frame === 0 ? (
        <Artifact content={Artifact.Thumbnail} filename="thumbnail.jpeg" />
      ) : null}
    </>
  );
};
  1. content prop 應設為 Artifact.Thumbnail
  2. imageFormat 設定決定圖像的格式。你傳入的副檔名是無意義的。
  3. 其他產物規則仍然適用。

接收產物

在 CLI 或 Studio 中

渲染影片時,產物會儲存到 out/[composition-id]/[filename]

使用 renderMedia()renderStill()renderFrames()

使用 onArtifact 回呼來接收產物。

// render.mjs
import { renderMedia, OnArtifact } from '@remotion/renderer';
 
const onArtifact: OnArtifact = (artifact) => {
  console.log(artifact.filename);  // string
  console.log(artifact.content);   // string | Uint8Array
  console.log(artifact.frame);     // number,輸出此產物的幀號
 
  // 範例動作:將產物寫入磁碟
  fs.writeFileSync(artifact.filename, artifact.content);
};
 
await renderMedia({
  composition,
  serveUrl,
  onArtifact,
  codec: 'h264',
  inputProps,
});

使用 renderMediaOnWeb()renderStillOnWeb()

使用 onArtifact 回呼在使用 renderMediaOnWeb() 渲染時接收產物。

使用 renderMediaOnWeb() 接收產物

const MyComp: React.FC = () => {
  const frame = useCurrentFrame();
  return (
    <>
      {frame === 0 && (
        <Artifact
          filename="metadata.json"
          content={JSON.stringify({ title: 'My Video' })}
        />
      )}
    </>
  );
};
 
const artifacts: EmittedArtifact[] = [];
 
await renderMediaOnWeb({
  composition: { ...composition, component: MyComp },
  onArtifact: (artifact) => {
    console.log(artifact.filename);  // string
    console.log(artifact.content);   // string | Uint8Array
    console.log(artifact.frame);     // number
    artifacts.push(artifact);
  },
});

相同的回呼也適用於 renderStillOnWeb()

使用 renderStillOnWeb() 接收產物

const MyComp: React.FC = () => {
  return (
    <Artifact
      filename="thumbnail.png"
      content={Artifact.Thumbnail}
    />
  );
};
 
const artifacts: EmittedArtifact[] = [];
 
await renderStillOnWeb({
  composition: { ...composition, component: MyComp },
  frame: 0,
  imageFormat: 'png',
  onArtifact: (artifact) => {
    artifacts.push(artifact);
  },
});

使用 Remotion Lambda CLI

使用 npx remotion lambda rendernpx remotion lambda still 時,產物會儲存到 S3 存儲桶中,鍵為 renders/[render-id]/artifacts/[filename]。它們將被記錄到主控台,你可以點擊它們來下載。--privacy 選項也適用於產物。

使用 renderMediaOnLambda()

使用 renderMediaOnLambda() 時,產物會儲存到 S3 存儲桶中,鍵為 renders/[render-id]/artifacts/[filename]。你可以從 getRenderProgress() 獲取目前已接收資源的清單。

// progress.ts
import { getRenderProgress } from '@remotion/lambda/client';
 
const renderProgress = await getRenderProgress({
  renderId: 'hi',
  functionName: 'hi',
  bucketName: 'hi',
  region: 'eu-central-1',
});
 
for (const artifact of renderProgress.artifacts) {
  console.log(artifact.filename);    // "hello-world.txt"
  console.log(artifact.sizeInBytes); // 12
  console.log(artifact.s3Url);       // "https://s3.eu-central-1.amazonaws.com/remotion-lambda-abcdef/renders/abcdef/artifacts/hello-world.txt"
  console.log(artifact.s3Key);       // "renders/abcdef/artifacts/hello-world.txt"
}

使用 renderStillOnLambda()

使用 renderStillOnLambda() 時,產物會儲存到 S3 存儲桶中,鍵為 renders/[render-id]/artifacts/[filename]。你可以從 renderStillOnLambda()artifacts 欄位獲取已接收資源的清單。

// still.ts
import { renderStillOnLambda } from '@remotion/lambda/client';
 
const stillResponse = await renderStillOnLambda({
  functionName,
  region,
  serveUrl,
  composition,
  inputProps,
  imageFormat,
  privacy,
});
 
for (const artifact of stillResponse.artifacts) {
  console.log(artifact.filename);    // "hello-world.txt"
  console.log(artifact.sizeInBytes); // 12
  console.log(artifact.s3Url);       // "https://s3.eu-central-1.amazonaws.com/remotion-lambda-abcdef/renders/abcdef/artifacts/hello-world.txt"
  console.log(artifact.s3Key);       // "renders/abcdef/artifacts/hello-world.txt"
}

使用 Cloud Run

在 Cloud Run Alpha 中,輸出產物不受支援,會拋出錯誤。我們計劃在未來修訂 Cloud Run 以使用與 Lambda 相同的執行環境,屆時將帶來此功能。

實際應用範例

產生字幕檔案

// SubtitleComposition.tsx
import React from 'react';
import { Artifact, useCurrentFrame, useVideoConfig } from 'remotion';
 
const generateSRT = (fps: number, totalFrames: number): string => {
  // 產生 SRT 字幕內容的邏輯
  return `1
00:00:00,000 --> 00:00:03,000
歡迎使用 Remotion!
 
2
00:00:03,000 --> 00:00:06,000
這是自動產生的字幕。
`;
};
 
export const SubtitleComp: React.FC = () => {
  const frame = useCurrentFrame();
  const { fps, durationInFrames } = useVideoConfig();
 
  return (
    <>
      {frame === 0 && (
        <Artifact
          filename="subtitles.srt"
          content={generateSRT(fps, durationInFrames)}
        />
      )}
      {/* 影片內容 */}
    </>
  );
};

產生章節資訊

// ChapterComposition.tsx
import React from 'react';
import { Artifact, useCurrentFrame } from 'remotion';
 
const chapters = [
  { time: '00:00:00', title: '簡介' },
  { time: '00:01:30', title: '主要內容' },
  { time: '00:05:00', title: '總結' },
];
 
const generateChapters = (): string => {
  return chapters.map((ch) => `${ch.time} ${ch.title}`).join('\n');
};
 
export const ChapterComp: React.FC = () => {
  const frame = useCurrentFrame();
 
  return (
    <>
      {frame === 0 && (
        <Artifact
          filename="chapters.txt"
          content={generateChapters()}
        />
      )}
      {/* 影片內容 */}
    </>
  );
};

另請參閱