staticFile() 函式
使用 staticFile() 將 public/ 資料夾中的檔案轉換為可在 Remotion 中載入的 URL,安全地引用靜態資源。
什麼是 staticFile()?
staticFile() 是 Remotion v2.5.7 引入的函式,它將你 public/ 資料夾中的檔案轉換成一個可在專案中載入的 URL。
import { Img, staticFile } from "remotion";
const myImage = staticFile(`/my-image.png`);
// ...
<Img src={myImage} />;如何使用
第一步:建立 public/ 資料夾
在你的影片專案根目錄建立一個 public/ 資料夾:
my-video/
├─ node_modules/
├─ public/
│ ├─ my-image.png
│ ├─ font.woff2
├─ src/
│ ├─ Root.tsx
│ ├─ index.ts
├─ package.json
重要:
public/資料夾應始終與包含remotion依賴的package.json放在同一個資料夾中,即使你的 Remotion 程式碼位於子目錄中也是如此。
第二步:取得資源的 URL 參照
import { staticFile } from "remotion";
const myImage = staticFile(`/my-image.png`);
// "/static-32e8nd/my-image.png"
const font = staticFile(`/font.woff2`);
// "/static-32e8nd/font.woff2"第三步:載入資源
你可以透過以下方式載入資源:
<Img>、<Audio>、<Video>、<OffthreadVideo>、<Html5Audio>、<Html5Video>標籤- Fetch API
FontFace()- 任何其他支援透過 URL 進行資料獲取的載入器
為什麼不能直接使用字串路徑?
如果你曾使用過 Create React App 或 Next.JS,可能習慣直接用字串參照資源:
<!-- 在其他框架中這樣做 -->
<img src="/my-image.png" />但 Remotion 選擇使用 staticFile() API,原因如下:
-
防止部署到子目錄時失效:若你的網站部署在
https://example.com/my-folder/,直接使用/my-image.png會導致路徑錯誤,而staticFile()會確保路徑正確。 -
避免與 Composition 名稱衝突:若你有一個名為
my-video的 Composition,它可能與http://localhost:3000/my-video的靜態資源路徑產生衝突。staticFile()使用特殊前綴(如/static-32e8nd/)來避免這種情況。 -
讓路徑跨框架相容:這使你的程式碼可以在 Remotion、Create React App、Next.JS 等不同框架中運作。
取得所有靜態檔案列表
使用 getStaticFiles() API 來取得 public/ 資料夾中所有可用檔案的列表:
import { getStaticFiles } from "remotion";
const files = getStaticFiles();
// 回傳所有 public/ 資料夾中的檔案列表處理含有特殊字元的檔名 v4.0.0
從 v4.0 起,staticFile() 會使用 encodeURIComponent 對檔名進行編碼。
重要:如果你之前自己進行過編碼,升級到 v4.0 後請確保不要再自行編碼,以避免雙重編碼。
v4.0 之前的行為
// v4.0 之前
staticFile("my-image#portrait.png");
// 輸出:"/my-image#portrait.png"若將此 URL 傳給接受 URL 的元件,# 之後的部分會被忽略,導致找不到檔案。
v4.0.0 之後的行為
// v4.0.0 之後
staticFile("my-image#portrait.png");
// 輸出:"/my-image%23portrait.png"現在圖片能正確載入。但你必須避免自行對檔名進行編碼,否則會造成雙重編碼:
// 錯誤做法:自行編碼後再傳入
staticFile(encodeURIComponent("my-image#portrait.png"));
// 輸出:"/my-image%2523portrait.png"(雙重編碼,會出錯)
// 正確做法:直接傳入原始檔名
staticFile("my-image#portrait.png");
// 輸出:"/my-image%23portrait.png"(正確)實際應用範例
載入圖片
import { AbsoluteFill, Img, staticFile } from "remotion";
export const MyComp: React.FC = () => {
return (
<AbsoluteFill>
<Img src={staticFile("background.png")} />
</AbsoluteFill>
);
};載入影片
import { AbsoluteFill, OffthreadVideo, staticFile } from "remotion";
export const MyComp: React.FC = () => {
return (
<AbsoluteFill>
<OffthreadVideo src={staticFile("clip.mp4")} />
</AbsoluteFill>
);
};載入自訂字型
import { staticFile } from "remotion";
import { useEffect } from "react";
export const useCustomFont = () => {
useEffect(() => {
const font = new FontFace(
"MyFont",
`url(${staticFile("my-font.woff2")})`
);
font.load().then((loadedFont) => {
document.fonts.add(loadedFont);
});
}, []);
};用 Fetch API 載入 JSON 資料
import { delayRender, continueRender, staticFile } from "remotion";
import { useState, useEffect } from "react";
export const MyComp: React.FC = () => {
const [data, setData] = useState(null);
const [handle] = useState(() => delayRender());
useEffect(() => {
fetch(staticFile("data.json"))
.then((res) => res.json())
.then((json) => {
setData(json);
continueRender(handle);
});
}, [handle]);
if (!data) return null;
return <div>{JSON.stringify(data)}</div>;
};相容性
| 環境 | 使用前綴 | 支援 |
|---|---|---|
| Chrome | / | 是 |
| Firefox | / | 是 |
| Safari | / | 是 |
| Node.js | / | 是 |
| Bun | / | 是 |
| Serverless Functions | / | 是 |
| 客戶端渲染 | / | 是 |
| 伺服器端渲染 | / | 是 |
| Player | / | 是 |
| Studio | / | 是 |