Remotion LabRemotion Lab
影片<OffthreadVideo> 元件

<OffthreadVideo> 元件

使用 <OffthreadVideo> 元件在渲染時透過 FFmpeg 提取精確幀,解決預設 <Video> 元件的限制,獲得更好的影片渲染效能與精確度。

什麼是 <OffthreadVideo>

<OffthreadVideo> 是 Remotion v3.0.11 引入的元件,它與 <Html5Video/> 類似,都用於匯入和顯示影片,但有一個關鍵差異:在渲染時,它會使用 FFmpeg 在瀏覽器外部提取影片的精確幀,並以 <img> 標籤顯示。

這個元件是為了解決預設 <Html5Video> 元素的限制而設計的。詳細比較請參閱:影片標籤的比較

注意<OffthreadVideo> 不支援客戶端渲染(@remotion/web-renderer)。請改用 @remotion/media 中的 <Video>

基本範例

使用本地靜態檔案

import { AbsoluteFill, OffthreadVideo, staticFile } from "remotion";
 
export const MyVideo = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo src={staticFile("video.webm")} />
    </AbsoluteFill>
  );
};

使用遠端 URL

export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo src="https://remotion.media/BigBuckBunny.mp4" />
    </AbsoluteFill>
  );
};

Props 說明

src

影片的 URL。可以是遠端 URL 或使用 staticFile() 參照的本地檔案。

trimBefore? v4.0.319

從影片開頭(左側)裁剪掉一部分。

在以下範例中,我們假設 Composition 的 fps 為 30:

  • 傳入 trimBefore={60} 後,播放從頭開始,但影片的前 2 秒被裁掉。
  • 傳入 trimAfter={120} 後,影片 4 秒標記之後的內容都被裁掉。
  • 影片將播放從 00:02:0000:04:00 的範圍,共 2 秒。
export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo
        src={staticFile("video.webm")}
        trimBefore={60}
        trimAfter={120}
      />
    </AbsoluteFill>
  );
};

trimAfter? v4.0.319

從影片結尾(右側)裁剪掉一部分。詳細說明請參閱 trimBefore

startFrom?(已棄用)

此 prop 在 v4.0.319 中已重新命名為 trimBefore。舊版仍可使用,但不能與新 prop 同時使用。

endAt?(已棄用)

此 prop 在 v4.0.319 中已重新命名為 trimAfter。舊版仍可使用,但不能與新 prop 同時使用。

transparent? v4.0.0

若設為 true,幀將以 PNG 格式提取,啟用透明度支援,但也會降低渲染速度。若設為 false(預設),幀將以 BMP 格式提取,速度更快。

只有在確實需要透明度時才設為 true,否則會不必要地降低效能。

volume?

控制整個音軌的音量,或在每幀基礎上進行調整。請參閱使用音訊指南以了解如何使用。

靜態音量範例:

export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo volume={0.5} src={staticFile("video.webm")} />
    </AbsoluteFill>
  );
};

100 幀漸入音量範例:

export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo
        volume={(f) =>
          interpolate(f, [0, 100], [0, 1], {
            extrapolateLeft: "clamp",
            extrapolateRight: "clamp",
          })
        }
        src={staticFile("video.webm")}
      />
    </AbsoluteFill>
  );
};

預設支援 0 到 1 之間的音量值。在 iOS Safari 上,音量始終為 1。更多資訊請參閱音量限制

loopVolumeCurveBehavior? v4.0.142

控制在使用音量回調函式且 OffthreadVideo 被包裝在 <Loop> 中時回傳的幀數。可以是 "repeat"(預設,每次迭代從 0 開始)或 "extend"(持續增加幀數)。

style?

你可以傳入任何可套用到原生 HTML 元素的樣式。請注意,在渲染時 <OffthreadVideo> 會渲染成 <img> 標籤,但在預覽時則使用 <video> 標籤。

export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo
        src={staticFile("video.webm")}
        style={{ height: 720, width: 1280 }}
      />
    </AbsoluteFill>
  );
};

name? v4.0.71

一個名稱,將在 Remotion Studio 的時間軸中顯示為序列的標籤。此屬性純粹用於幫助你在時間軸中追蹤項目。

toneFrequency? v4.0.47

調整音訊的音高——只在渲染時套用。接受 0.012 之間的數值,其中 1 代表原始音高。小於 1 的值會降低音高,大於 1 的值會提高音高。

  • toneFrequency={0.5} 會將音高降低一半
  • toneFrequency={1.5} 會將音高提高 50%

onError?

處理影片播放錯誤。從 v3.3.89 起,如果你傳入 onError 回調,就不會拋出例外。

playbackRate? v2.2.0

控制影片的播放速度:

  • 1 是預設值,表示正常速度
  • 0.5 讓影片慢兩倍(播放時間加倍)
  • 2 讓影片快兩倍(播放時間減半)

在開發模式下,使用的是 HTMLMediaElement.playbackRate API,在極端值時會拋出錯誤。Google Chrome 目前在播放速率低於 0.0625 或高於 16 時會拋出例外。

兩倍速播放範例:

export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo playbackRate={2} src={staticFile("video.webm")} />
    </AbsoluteFill>
  );
};

注意:不支援反向播放影片。

muted?

加入 muted prop 可以靜音影片:

export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo muted src="https://remotion.media/BigBuckBunny.mp4" />
    </AbsoluteFill>
  );
};

acceptableTimeShiftInSeconds? v3.2.42

在 Studio 或 Remotion Player 中,若影片與 Remotion 的內部時間相差太多(無論是因為影片載入或頁面太慢無法即時跟上),Remotion 會對影片進行 seek。預設情況下,若時間偏移超過 0.45 秒就會觸發 seek。使用此 prop 可以自訂閾值。

pauseWhenBuffering? v4.0.111

若設為 true 且影片正在載入,Player 將進入原生緩衝狀態。預設為 false,但在 Remotion 5.0 中將改為 true

toneMapped? v4.0.117

從 Remotion 4.0.117 起,在轉換為 RGB 時,Remotion 會調整不同色彩空間(如 HDR)影片的顏色,以抵消色偏。由於瀏覽器使用 sRGB 繪製,這對確保顏色正確顯示是必要的。

此行為預設為 true,可以透過將 toneMapped 設為 false 來停用。停用色調映射會加快渲染速度,但可能導致顏色較不鮮豔。

audioStreamIndex? v4.0.340

選擇要使用的音訊流,預設為 0

export const MyComposition = () => {
  return (
    <AbsoluteFill>
      <OffthreadVideo
        audioStreamIndex={1}
        src="https://remotion.media/multiple-audio-streams.mov"
      />
    </AbsoluteFill>
  );
};

注意:此 prop 只在渲染時有效。瀏覽器在不啟用實驗性旗標的情況下不支援選擇音訊軌道。請勿與音訊聲道混淆——一個影片可以有多個音訊流,每個流可以有多個聲道。多個音訊流可用於例如為影片加入多種語言。音訊流的索引從 0 開始。

showInTimeline? v4.0.122

若設為 false,在 Remotion Studio 的時間軸中不會顯示任何圖層。預設為 true

delayRenderTimeoutInMilliseconds? v4.0.150

自訂此元件進行的 delayRender() 呼叫的逾時時間。

delayRenderRetries? v4.0.178

自訂此元件進行的 delayRender() 呼叫的重試次數。

onAutoPlayError? v4.0.187

當影片因自動播放限制而無法播放時呼叫的回調函式。若不傳入回調,影片會被靜音並重試一次。此 prop 適用於你想自行處理錯誤的情況,例如暫停 Player。

onVideoFrame? v4.0.190

當從影片中提取幀時呼叫的回調函式,適用於影片操作。回調會接收一個 CanvasImageSource 物件:在預覽時是 HTMLVideoElement,在渲染時是 HTMLImageElement

crossOrigin? v4.0.190

對應 <video> 元素的 crossOrigin 屬性。可以是 "anonymous""use-credentials"undefined。若指定了 onVideoFrame,預設為 "anonymous",否則為 undefined

useWebAudioApi? v4.0.306

為影片標籤啟用 Web Audio API。

效能提示

  • 只有在確實需要透明度時才將 transparent 設為 true,否則會比非透明幀提取慢。
  • 如果不在意顏色精確度,可以將 toneMapped 設為 false 來節省色彩轉換的時間。

迴圈播放 OffthreadVideo

<Html5Video> 不同,OffthreadVideo 沒有實作 loop 屬性。若需要迴圈播放,請考慮使用其他影片標籤。

注意:影片結束時,預設會保持顯示影片的最後一幀,這與 <Html5Video> 的行為一致。

你可以使用以下 <LoopableOffthreadVideo> 元件,配合 Mediabunny 來確定迴圈播放的持續時間:

// src/LoopableOffthreadVideo.tsx
import React, { useEffect, useState } from "react";
import {
  cancelRender,
  continueRender,
  delayRender,
  Loop,
  OffthreadVideo,
  RemotionOffthreadVideoProps,
  useRemotionEnvironment,
  useVideoConfig,
  Html5Video,
} from "remotion";
import { getMediaMetadata } from "./get-media-metadata";
 
const LoopedOffthreadVideo: React.FC<
  Partial<RemotionOffthreadVideoProps>
> = (props) => {
  const [duration, setDuration] = useState<number | null>(null);
  const [handle] = useState(() => delayRender());
  const { fps } = useVideoConfig();
 
  useEffect(() => {
    getMediaMetadata(props.src)
      .then(({ durationInSeconds }) => {
        setDuration(durationInSeconds);
        continueRender(handle);
      })
      .catch((err) => {
        cancelRender(err);
      });
    return () => {
      continueRender(handle);
    };
  }, [handle, props.src]);
 
  if (duration === null) {
    return null;
  }
 
  return (
    <Loop durationInFrames={Math.floor(duration * fps)}>
      <OffthreadVideo {...props} />
    </Loop>
  );
};
 
export const LoopableOffthreadVideo: React.FC<
  Partial<RemotionOffthreadVideoProps> & { loop?: boolean }
> = ({ loop, ...props }) => {
  const env = useRemotionEnvironment();
 
  if (env.isRendering) {
    if (loop) {
      return <LoopedOffthreadVideo {...props} />;
    }
    return <OffthreadVideo {...props} />;
  }
 
  return <Html5Video loop={loop} {...props} />;
};

其他 Props

onErrorclassNamestyle 等 props 也受到支援,並會傳遞給底層的 HTML 元素。請記住,在渲染時這是一個 <img> 元素,在預覽時則是一個 <video> 元素。

相容性

環境支援
Chrome
Firefox
Safari
客戶端渲染
伺服器端渲染
Player
Studio

相關資源