Remotion LabRemotion Lab
Player避免 Player 閃爍問題

避免 Player 閃爍問題

了解為什麼 Remotion Player 會出現閃爍現象,以及多種不同程度的解決策略。

避免 <Player> 的閃爍問題

請考慮以下標記:

MyComponent.tsx
import { AbsoluteFill, Sequence, OffthreadVideo } from 'remotion';
 
const MyComponent: React.FC = () => {
  return (
    <AbsoluteFill>
      <Sequence from={0} durationInFrames={120}>
        <OffthreadVideo src="https://example.com/video1.mp4" />
      </Sequence>
      <Sequence from={120} durationInFrames={120}>
        <OffthreadVideo src="https://example.com/video2.mp4" />
      </Sequence>
    </AbsoluteFill>
  );
};

由於 Remotion 只感知當前幀,來源為 video2.mp4 的影片只會在它開始出現在場景中時才開始載入。這可能在 Player 中導致某些幀為空白的效果,因為影片的載入通常不會立即完成。

這是 Remotion 的設計取捨,但可以透過不同程度的方式來應對。

解決策略

策略一:忽略

此效果只發生在 Remotion Studio 和 Remotion Player 中,不會出現在渲染後的影片中。如果你只需要逐幀完美的渲染影片,不需要採取額外步驟。

策略二:在媒體緩衝時暫停 <Player>

建議做法:此功能將在 Remotion 5.0 成為預設行為。

你可能希望暫時暫停 <Player> 以允許資源載入,並在資源準備好可以播放後恢復。

你可以透過將 pauseWhenBuffering prop 新增至 <Html5Audio><Html5Video><OffthreadVideo><Img> 標籤來實現。了解更多關於 buffer 狀態的資訊

import { OffthreadVideo, Sequence, staticFile } from 'remotion';
 
const MyComp: React.FC = () => {
  return (
    <Sequence from={120} durationInFrames={120}>
      <OffthreadVideo
        src={staticFile('video2.mp4')}
        pauseWhenBuffering
      />
    </Sequence>
  );
};

注意pauseWhenBuffering prop 在 @remotion/media<Video><Audio> 中預設為啟用。

策略三:預掛載影片

建議做法:這是最有效的解決方案。

你可以比序列開始顯示的時間提前幾幀掛載它,使其有時間在使用者看到之前載入,這有助於避免閃爍。

詳情請參閱預掛載(Premounting)

import { Sequence, OffthreadVideo, staticFile } from 'remotion';
 
const MyComp: React.FC = () => {
  return (
    // 提前 60 幀預掛載
    <Sequence from={120} durationInFrames={120} premountFor={60}>
      <OffthreadVideo src={staticFile('video2.mp4')} />
    </Sequence>
  );
};

策略四:預載入以避免網路請求

建議做法:這有助於減少網路載入時間。

你可以向瀏覽器發出預載入影片和其他資源的信號,讓嵌入元素出現在影片中時,可以省去網路請求的時間。

詳情請參閱預載入(Preloading)

注意:你向瀏覽器發出的信號可能會被忽略,例如裝置啟用了省流量或省電模式時。這對行動裝置尤為值得注意。

策略五:預取(Prefetch)為 Blob URL 以更積極地避免網路請求

不建議:記憶體密集,且只有在 Player 掛載前完成預取才有用,且常被誤用。

透過預取(prefetch)資源,它將被下載並快取至記憶體中。與預載入不同,你強制瀏覽器下載資源,但只有在資源完全下載後才能使用。

完全下載後,媒體標籤中的 URL 將被替換為 Blob URL。你必須確保不在播放途中替換 URL,否則播放可能會變差。

只有在媒體元素掛載之前完成預取才有意義。

注意:即使是預載入的資源或預取的資源,也需要掛載至 DOM 並由瀏覽器解碼,這可能需要短暫的時間。

策略六:預取為 Base64 以避免網路請求和本地 HTTP 伺服器

不建議:與預取有相同缺點,但還有額外的效能損耗,特別是對於大型資源。

在 Safari 中,策略五中描述的預取不夠充分,因為 Blob URL 會被儲存到磁碟,即使資源已預儲,仍可能發生輕微延遲。

另外,prefetch() 函式允許以 Base64 格式將資源取回並儲存在記憶體中,不需要透過 HTTP 從磁碟載入 Blob URL。

import { prefetch } from 'remotion';
 
// 以 Base64 格式預取資源
const { free } = prefetch('https://example.com/video2.mp4', {
  method: 'base64',
});
 
// 不再需要時釋放記憶體
// free();

策略比較

策略效果推薦程度備註
忽略適用於只需渲染影片只影響預覽
緩衝時暫停強烈推薦將成為 v5.0 預設行為
預掛載強烈推薦最有效的解決方案
預載入推薦減少網路請求時間
Blob 預取不推薦記憶體密集,容易誤用
Base64 預取不推薦效能損耗大

另請參閱