Remotion LabRemotion Lab
建構應用Mediabunny

Mediabunny

Mediabunny 是 Remotion 生態系的媒體處理函式庫,提供純 WebAssembly 實作的影音解碼、幀提取與媒體資訊查詢功能。

Mediabunny

Mediabunny 是 Remotion 生態系中的媒體處理函式庫。它以 WebAssembly(WASM)為核心,讓你能夠在瀏覽器或 Node.js 環境中直接處理影音媒體,無需依賴原生的 FFmpeg 執行檔。

主要功能

  • 幀提取 — 從影片的任意時間點取得單一幀的圖像資料
  • 媒體資訊查詢 — 取得影片的時長、解析度、fps、編碼格式等詮釋資料
  • 音訊解碼 — 解碼音訊串流以進行後續處理
  • 跨環境支援 — 在瀏覽器(含 Web Worker)與 Node.js 中均可使用
  • 純 WASM 實作 — 不依賴原生可執行檔,部署更為簡便

安裝

# npm
npm install @remotion/media-utils
 
# pnpm
pnpm add @remotion/media-utils
 
# yarn
yarn add @remotion/media-utils

Mediabunny 的功能透過 @remotion/media-utils 套件對外提供。

取得影片資訊

使用 getVideoMetadata() 查詢影片的基本屬性:

import { getVideoMetadata } from '@remotion/media-utils';
 
const metadata = await getVideoMetadata('https://example.com/video.mp4');
 
console.log(metadata.durationInSeconds); // 影片時長(秒)
console.log(metadata.width);             // 影片寬度(像素)
console.log(metadata.height);            // 影片高度(像素)
console.log(metadata.fps);               // 每秒幀數

取得音訊波形資料

getAudioData() 可以解碼音訊並回傳原始樣本資料,適合用於波形視覺化:

import { getAudioData } from '@remotion/media-utils';
 
const audioData = await getAudioData('https://example.com/audio.mp3');
 
console.log(audioData.durationInSeconds);  // 音訊時長
console.log(audioData.sampleRate);         // 取樣率(Hz)
console.log(audioData.numberOfChannels);   // 聲道數
console.log(audioData.channelWaveforms);   // 各聲道的波形資料陣列

音訊視覺化範例

結合 getAudioData()visualizeAudio() 建立即時音訊視覺化效果:

import { getAudioData, visualizeAudio } from '@remotion/media-utils';
import { useEffect, useState } from 'react';
import { useCurrentFrame, useVideoConfig, Audio, staticFile } from 'remotion';
 
export const AudioVisualizer: React.FC = () => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const [audioData, setAudioData] = useState(null);
 
  useEffect(() => {
    getAudioData(staticFile('audio.mp3')).then(setAudioData);
  }, []);
 
  if (!audioData) return null;
 
  const visualization = visualizeAudio({
    fps,
    frame,
    audioData,
    numberOfSamples: 256,
  });
 
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 2 }}>
      {visualization.map((value, index) => (
        <div
          key={index}
          style={{
            width: 4,
            height: `${value * 300}px`,
            backgroundColor: '#6366f1',
          }}
        />
      ))}
      <Audio src={staticFile('audio.mp3')} />
    </div>
  );
};

在 Remotion 渲染中使用

若需要在渲染期間等待媒體資料載入,請搭配 delayRendercontinueRender

import { getVideoMetadata } from '@remotion/media-utils';
import { delayRender, continueRender } from 'remotion';
import { useState, useEffect } from 'react';
 
export const MyComp: React.FC = () => {
  const [handle] = useState(() => delayRender('載入影片資訊'));
  const [duration, setDuration] = useState<number | null>(null);
 
  useEffect(() => {
    getVideoMetadata('https://example.com/video.mp4')
      .then((meta) => {
        setDuration(meta.durationInSeconds);
        continueRender(handle);
      })
      .catch(() => continueRender(handle));
  }, [handle]);
 
  if (duration === null) return null;
 
  return <div>影片時長:{duration.toFixed(2)} 秒</div>;
};

與 OffthreadVideo 搭配使用

在需要精確幀提取的場景中,Mediabunny 是 <OffthreadVideo> 的底層技術之一。若你直接使用 <OffthreadVideo>,Remotion 內部已自動處理幀提取,通常不需要手動呼叫 Mediabunny API。

import { OffthreadVideo, staticFile } from 'remotion';
 
export const MyComp: React.FC = () => {
  return (
    <OffthreadVideo
      src={staticFile('background.mp4')}
      style={{ width: '100%' }}
    />
  );
};

注意事項

  • 媒體檔案必須支援 HTTP Range 請求(可 seek),否則部分功能無法正常運作。詳見不可 seek 的媒體
  • 在瀏覽器環境中,跨域媒體資源需正確設定 CORS 標頭。
  • WASM 模組首次載入需要一些時間,建議在元件掛載時盡早初始化。
  • Node.js 環境中使用時,需確認執行環境支援 WebAssembly。

相關資源