🎬
ffmpegで生成したgifが無限ループしなくなる事象の原因と解決
少し特殊な条件下で発生しています。
この備忘録が同じ状況に陥って原因が分からない人に届けば幸いです。
発生した問題
「ffmpeg 無限ループ」などで検索してヒットした記事を元にコマンドを実行したgifデータをimgタグで出力すると無限ループすることはできました。
ffmpeg -i input.mov -loop 0 output.gif
TypeScript
import Image from 'next/image';
function App() {
return (
<div>
<h1>GIF表示テスト</h1>
<Image
src="/output.gif"
alt="GIF"
width={458}
height={572}
unoptimized={true} // GIFアニメーション保持のため
/>
</div>
);
}
export default App;
ただ、その後macのプレビューアプリを使って背景透過作業を行い、データを上書き保存すると、ループが機能しなくなリました。
原因
macのプレビューアプリは背景透過処理時に、GIFのループ情報(Netscape 2.0 Extension メタデータ)を削除してしまう可能性があります。
これは透過処理に限らず、プレビューアプリでの編集・保存全般で発生するかもしれないので、推測になってしまいますが、gifに独自のデータ加工を施す場合は注意が必要です。
解決方法
透過gifに再度ffmpeg -i input.mov -loop 0 output.gifコマンドを実行しても、透過部分を白く塗り潰した無透過gifが生成されます。
そこで、以下のコマンドを使用することで、背景透過を保持したまま無限ループ設定を付与できました。
output.gif: 背景透過・ループ❌
output2.gif: 背景透過・無限ループ
ffmpeg -i output.gif -vf "split[s0][s1];[s0]palettegen=reserve_transparent=1[p];[s1][p]paletteuse=alpha_threshold=128" -loop 0 output2.gif
このコマンドは:
-
split[s0][s1]: 入力を2つのストリームに分岐 -
palettegen=reserve_transparent=1: 透過対応のカラーパレットを生成 -
paletteuse=alpha_threshold=128: 透過を保持してパレットを適用 -
-loop 0: 無限ループ設定
元の透過GIFから直接、透過設定とループ設定を同時に適用することで、透過状態を保持したまま無限ループを設定したgifにすることができました。
Discussion