Player 資源預載入
了解如何為 Remotion Player 預載入影片、音訊和圖片資源,使用 @remotion/preload API 和 prefetch() 函式確保媒體在需要時立即可用。
Player 資源預載入
預設情況下,影片、音訊或圖片等資源只會在進入影片畫面時才開始載入。使用 Remotion Player 時,你可能希望提前預載入這些資源,以便在它們進入影片時能立即播放。
目前支援兩種預載入方式:
- 使用
@remotion/preloadAPI 向瀏覽器發出載入信號 - 使用
prefetch()提前抓取資源並在本機播放
使用 @remotion/preload 預載入影片
透過預載入,會在頁面上放置一個 <link type='preload'> 標籤,通知瀏覽器可以開始載入該媒體。
- 影片使用
preloadVideo()API - 音訊使用
preloadAudio() - 圖片使用
preloadImage()
建議在元件外部或 useEffect() 內部執行預載入:
import { preloadAudio, preloadVideo } from '@remotion/preload';
const unpreloadVideo = preloadVideo('https://example.com/video.mp4');
const unpreloadAudio = preloadAudio(
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'
);
// 之後可選擇清理預載入
unpreloadVideo();
unpreloadAudio();在元件中使用預載入
import { useEffect } from 'react';
import { preloadVideo, preloadAudio } from '@remotion/preload';
import { Player } from '@remotion/player';
import { MyVideo } from './remotion/MyVideo';
export const App: React.FC = () => {
useEffect(() => {
const unpreloadVideo = preloadVideo('https://example.com/hero-video.mp4');
const unpreloadAudio = preloadAudio('https://example.com/background-music.mp3');
return () => {
unpreloadVideo();
unpreloadAudio();
};
}, []);
return (
<Player
component={MyVideo}
durationInFrames={300}
compositionWidth={1920}
compositionHeight={1080}
fps={30}
controls
/>
);
};使用 prefetch() 進行預先抓取
此功能自 v3.2.23 起可用
透過預先抓取,完整的媒體檔案會被下載並使用 URL.createObjectURL() 轉換為 Blob URL。
如果你將原始 URL 傳入 <Audio>、<Video>、<OffthreadVideo>、<Html5Audio>、<Html5Video> 或 <Img> 標籤,且該資源已被預先抓取,這些元件將改用 Blob URL 播放。
import { prefetch } from 'remotion';
const { free, waitUntilDone } = prefetch('https://example.com/video.mp4');
waitUntilDone().then(() => {
console.log('影片已完成載入');
});
// 如果要取消預先抓取並釋放記憶體,呼叫 free():
free();在 React 元件中使用 prefetch()
import { useEffect, useState } from 'react';
import { prefetch } from 'remotion';
import { Player } from '@remotion/player';
import { MyVideo } from './remotion/MyVideo';
export const App: React.FC = () => {
const [isReady, setIsReady] = useState(false);
useEffect(() => {
const { free, waitUntilDone } = prefetch('https://example.com/video.mp4');
waitUntilDone().then(() => {
setIsReady(true);
});
return () => {
free();
};
}, []);
return (
<div>
{!isReady && <p>預先載入中...</p>}
<Player
component={MyVideo}
durationInFrames={300}
compositionWidth={1920}
compositionHeight={1080}
fps={30}
controls
/>
</div>
);
};@remotion/preload 與 prefetch() 的比較
prefetch() 是確保媒體在需要時準備就緒的更可靠方式,但需要完整下載資源才能使用。
如果資源較大,@remotion/preload 更為合適,因為你不必等待完整下載。
| 比較項目 | preloadAudio() / preloadVideo() | prefetch() |
|---|---|---|
| 適用對象 | 所有音訊和影片 API、圖片與字型 | <Audio>、<Video>、<Html5Audio>、<Html5Video>、<Img>、<OffthreadVideo> |
| 機制 | 插入 <link type='preload'> 標籤 | 抓取資源並轉換為 URL blob 或 Base64 URL |
| 準備就緒條件 | 資源部分載入後即可播放 | 必須完整抓取資源 |
| 可靠性 | 不保證,只是向瀏覽器發出信號 | 保證準備就緒,可追蹤載入進度 |
| 回呼 | 無法判斷是否已準備就緒 | Promise resolve 時即代表準備就緒 |
| 套件 | @remotion/preload | remotion |
| HTTP 重新導向 | 若使用 resolveRedirect(),資源必須支援 CORS | 自動處理 |
| CORS | 若使用 resolveRedirect(),資源必須支援 CORS | 資源必須支援 CORS |
| 可用版本 | v3.0.14 | v3.2.23 |
選擇建議
- 大型媒體檔案:使用
@remotion/preload,不需要等待完整下載 - 需要確保準備就緒:使用
prefetch(),可追蹤載入進度並在 Promise resolve 後確認 - 需要處理 HTTP 重新導向:使用
prefetch(),它會自動處理
預載入 GIF
你可以使用 preloadGif() 預載入並預先解析 GIF:
import { preloadGif } from '@remotion/preload';
// 預載入 GIF
const unpreload = preloadGif('https://example.com/animation.gif');
// 需要時清理
unpreload();使用 resolveRedirect() 處理 HTTP 重新導向
若要使用 @remotion/preload 預載入會進行 HTTP 重新導向的資源,你必須先解析重新導向後的 URL:
import { resolveRedirect, preloadVideo } from '@remotion/preload';
import { useEffect } from 'react';
export const App: React.FC = () => {
useEffect(() => {
let cancel = false;
let unpreload = () => {};
resolveRedirect('https://example.com/redirecting-video.mp4')
.then((finalUrl) => {
if (cancel) return;
unpreload = preloadVideo(finalUrl);
})
.catch(() => {
// 可能因 CORS 而失敗,此時無法預載入
if (!cancel) {
unpreload = preloadVideo('https://example.com/redirecting-video.mp4');
}
});
return () => {
cancel = true;
unpreload();
};
}, []);
return null;
};