1. ホーム
  2. python

Pythonから個々のフレームをファイルに保存せずにムービーを生成する

2023-09-13 06:58:32

質問

matplotlibのpythonスクリプトで生成したフレームから、h264またはdivxのムービーを作りたいと思っています。このムービーには約100kフレームがあります。

Web上の例[例1]では、私は各フレームをpngとして保存し、これらのファイル上でmencoderまたはffmpegを実行する方法のみを見ました。私の場合、各フレームを保存するのは非現実的です。matplotlibから生成されたプロットを取り、それを直接ffmpegにパイプし、中間ファイルを生成しない方法はありますか?

ffmpegのC-apiでプログラミングすることは、私にとって難しすぎます[eg. 2]。また、そうしないとムービーファイルが大きすぎて後続のステップに進めないため、x264 などの圧縮率の良いエンコーディングが必要です。だから、mencoder/ffmpeg/x264にこだわるのは素晴らしいことだと思います。

pipes [3]でできることはありますか?

[1] http://matplotlib.sourceforge.net/examples/animation/movie_demo.html

[2] x264 C API を使用して一連の画像を H264 にエンコードするにはどうすればよいですか?

[3] http://www.ffmpeg.org/ffmpeg-doc.html#SEC41

どのように解決するのですか?

この機能は、現在 (少なくとも 1.2.0 の時点、たぶん 1.1) matplotlib に組み込まれた MovieWriter クラスとそのサブクラスである animation モジュールのサブクラスを作成します。また ffmpeg をあらかじめインストールしておく必要があります。

import matplotlib.animation as animation
import numpy as np
from pylab import *


dpi = 100

def ani_frame():
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.set_aspect('equal')
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    im = ax.imshow(rand(300,300),cmap='gray',interpolation='nearest')
    im.set_clim([0,1])
    fig.set_size_inches([5,5])


    tight_layout()


    def update_img(n):
        tmp = rand(300,300)
        im.set_data(tmp)
        return im

    #legend(loc=0)
    ani = animation.FuncAnimation(fig,update_img,300,interval=30)
    writer = animation.writers['ffmpeg'](fps=30)

    ani.save('demo.mp4',writer=writer,dpi=dpi)
    return ani

のドキュメント animation