取消客戶端渲染
使用 AbortController API 取消進行中的客戶端渲染,以及偵測渲染是否被取消的方法。
取消客戶端渲染
警告 — 實驗性功能:此功能隨時可能出現錯誤和重大變更。請在 GitHub 上追蹤進度,並在 Discord 的
#web-renderer頻道中參與討論。
renderMediaOnWeb() 和 renderStillOnWeb() 均透過 AbortSignal API 支援取消操作。
使用 AbortController
建立一個 AbortController 並將其 signal 傳遞給渲染函式:
import {renderMediaOnWeb} from '@remotion/web-renderer';
const Component: React.FC = () => null;
const composition = {
component: Component,
durationInFrames: 100,
fps: 30,
width: 100,
height: 100,
id: 'my-composition',
};
const abortController = new AbortController();
// 10 秒後取消
setTimeout(() => abortController.abort(), 10000);
const {getBlob} = await renderMediaOnWeb({
signal: abortController.signal,
composition,
});偵測渲染是否被取消
當渲染被取消時,會拋出一個錯誤。若要區分使用者主動取消和實際錯誤,請檢查 signal 是否已中止:
import {renderMediaOnWeb} from '@remotion/web-renderer';
const abortController = new AbortController();
try {
const {getBlob} = await renderMediaOnWeb({
signal: abortController.signal,
composition,
});
// 取得 blob 並進行後續處理
const blob = await getBlob();
const url = URL.createObjectURL(blob);
// 下載或顯示影片
} catch (error) {
if (abortController.signal.aborted) {
// 渲染被使用者取消,優雅地處理
console.log('渲染已取消');
} else {
// 處理實際錯誤
throw error;
}
}在 React 元件中使用
在 React 元件中,通常需要在元件卸載時取消渲染,以避免記憶體洩漏:
import React, {useEffect, useRef, useState} from 'react';
import {renderMediaOnWeb} from '@remotion/web-renderer';
const RenderButton: React.FC = () => {
const [isRendering, setIsRendering] = useState(false);
const abortControllerRef = useRef<AbortController | null>(null);
const startRender = async () => {
// 如果有進行中的渲染,先取消它
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
const controller = new AbortController();
abortControllerRef.current = controller;
setIsRendering(true);
try {
const {getBlob} = await renderMediaOnWeb({
signal: controller.signal,
composition: {
component: MyVideoComponent,
durationInFrames: 300,
fps: 30,
width: 1920,
height: 1080,
id: 'my-video',
},
inputProps: {},
});
const blob = await getBlob();
// 處理 blob...
} catch (error) {
if (!controller.signal.aborted) {
console.error('渲染失敗:', error);
}
} finally {
setIsRendering(false);
}
};
const cancelRender = () => {
abortControllerRef.current?.abort();
setIsRendering(false);
};
// 元件卸載時取消進行中的渲染
useEffect(() => {
return () => {
abortControllerRef.current?.abort();
};
}, []);
return (
<div>
<button onClick={startRender} disabled={isRendering}>
{isRendering ? '渲染中...' : '開始渲染'}
</button>
{isRendering && (
<button onClick={cancelRender}>取消渲染</button>
)}
</div>
);
};相關資源
- MDN:AbortController — 標準 Web API 文件
- MDN:AbortSignal — Signal API 文件
renderMediaOnWeb()— 渲染影片的主要函式renderStillOnWeb()— 渲染靜態圖片的函式- 客戶端渲染概覽 — 功能介紹