iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0
Modern Web

在Vibe Coding 時代一起來做沒有AI感的漂亮網站吧!系列 第 5

可惡好好的 Webm 檔 Safari 不吃,只好餵他不一樣的東西了

  • 分享至 

  • xImage
  •  

嗨咿,我是 illumi,昨天講到用 AE 輸出透明影片轉 WebM 放到網頁上,結果發現 Safari 完全不支援 WebM,甚至在 iPad / iPhone 的 Chrome 裡也會壞掉!

這下是不是整個互動動畫要全爆?別急,第二條路線:PNG / WebP Sequence


1. 為什麼要 PNG Sequence?

WebM 在 Chrome / Firefox / Edge 超香,檔案比 MP4 小一半以上,但 Safari → 直接擋

透明影片最慘,會整個背景黑掉,動畫就毀了。

可以用「逐格貼圖」的土炮解法,也就是 PNG Sequence

  • 每一幀輸出一張 PNG(含透明)。
  • 用 Canvas 或 WebGL 在瀏覽器逐格播放。
  • 不會閃爍,不會被 Safari 擋,還能保留透明背景。

2. AE 輸出 PNG Sequence

在 AE 裡:

用 ME 輸出

  1. 在 AE 上方選單 → Composition > Add to Media Encoder

https://ithelp.ithome.com.tw/upload/images/20250906/20178506bCSSvQ1fIf.png
畫面顯示:

  • 格式:PNG
  • 預設集:PNG 序列含 Alpha (符合來源)
  • 勾「轉存視訊」

這樣輸出就會變成逐格的 PNG 檔案序列。


用 AE 輸出

  1. 在 AE 上方選單 → Composition > Add to Render Queue

  2. AE 下方會出現 Render Queue 面板

  3. Output Module → 選 Format: PNG Sequence,再選 RGB + Alpha

  4. Composition > Add to Render Queue

  5. 在 Render Queue → Output Module 選單 → 改成 PNG Sequence

    (記得 Channels 要選 RGB + Alpha 才有透明背景!)

  6. 選擇輸出資料夾,按下渲染 → 就會得到一包圖片
    https://ithelp.ithome.com.tw/upload/images/20250906/201785065FWn5CRiEF.png


3. PNG 太大?批次轉 WebP!

PNG 有透明很好,但檔案通常超肥。這時候可以在終端機中,用 cwebp 批次轉檔:

cwebp(Google 官方 WebP 工具)

  • 安裝:
  • q 80 = 品質 80(0~100),可依需求調整。
  • 轉檔前記得先 cd 放圖檔的資料夾
mkdir webp_output
for f in *.png; do
  cwebp -q 80 "$f" -o "webp_output/${f%.png}.webp";
done

4. 在 React 播放 Sequence

來了!我們把這堆 Sequence 放到 public/sequence/資料夾名稱/
每個圖檔名稱叫frame01......(可自行更改)
再用一個小小的 React 元件讀進來,Canvas 播放就搞定:

import React, { useEffect, useRef, useState } from "react";

interface SequencePlayerProps {
  folder: string; // e.g. "monsterCurious69"
  frameCount: number; // 幀數,例如 60
  width?: number;
  height?: number;
  fps?: number; // 每秒幀數
}

const SequencePlayer: React.FC<SequencePlayerProps> = ({
  folder,
  frameCount,
  width = 600,
  height = 600,
  fps = 24,
}) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [images, setImages] = useState<HTMLImageElement[]>([]);
  const [loaded, setLoaded] = useState(0);

  useEffect(() => {
    const imgs: HTMLImageElement[] = [];
    let loadedCount = 0;

    for (let i = 0; i < frameCount; i++) {
      const img = new Image();
      img.src = `/sequence/${folder}/frame${i
        .toString()
        .padStart(2, "0")}.webp`;  // 這一行最重要 要放資料夾路徑和圖檔名都叫什麼,2表示圖檔後面的數字都有幾位數

      img.onload = () => {
        loadedCount++;
        setLoaded(loadedCount); // 更新進度
        if (loadedCount === frameCount) {
          setImages(imgs);
        }
      };
      imgs.push(img);
    }
  }, [folder, frameCount]);

  // 播放動畫
  useEffect(() => {
    if (images.length === 0) return;

    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    let frame = 0;
    const interval = 1000 / fps;
    let lastTime = performance.now();

    const render = (time: number) => {
      if (time - lastTime >= interval) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(images[frame], 0, 0, canvas.width, canvas.height);
        frame = (frame + 1) % images.length;
        lastTime = time;
      }
      requestAnimationFrame(render);
    };

    requestAnimationFrame(render);
  }, [images, fps]);

  return (
    <div className="flex justify-center items-center">
      <canvas
        ref={canvasRef}
        width={width}
        height={height}
        className=" bg-transparent"
      />
      {loaded < frameCount && (
        <p className="absolute text-sm text-gray-500">
          Loading... {loaded}/{frameCount}
        </p>
      )}
    </div>
  );
};

export default SequencePlayer;

呼叫的時候很簡單:

<SequencePlayer
  folder="資料夾名稱"
  frameCount={60}
  width={100}
  height={100}
  fps={24}
 />

  • WebM → 最小,但 Safari 不支援。
  • PNG / WebP Sequence → 最穩定,Safari 也能播。
  • React + Canvas → 控制播放、透明背景全都沒問題。

https://ithelp.ithome.com.tw/upload/images/20250906/20178506OF0uXbc3vf.png
(這是在Safari打開的:綠色背景為Webm,透明的為WebP Sequence)


上一篇
哪尼!在AE想輸出帶有影片的專案成lottie被擋?生命自會找到出路!
系列文
在Vibe Coding 時代一起來做沒有AI感的漂亮網站吧!5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言