ffmpegとPythonで動画を作る

f:id:nuakam:20171010094311j:plain

下の記事で音楽を作り始めたので、今回はpythonで動画を作りたい。

準備編 【準備編】pythonでメロディーを作りたい - エンジニア戦記
第1回 【その2】pythonでメロディーを作りたい - エンジニア戦記




目標

wav形式の音楽ファイルと適当な静止画で動画を作りたい。

環境

  • python3
  • windows10
  • anaconda

概要

せっかく音楽ファイルを作ったんだからこの調子で動画ファイルも作ってしまおう。
最初は音楽に静止画をぽんと乗っけただけのmp4ファイルから作っていく。
プログラミング言語だけで作成すると、バイナリデータを書き込んでいくものから、適当なモジュールを使うものまで多様な方法がある。
今回は簡単に動画を作れるCUIベースのffmepgというフリーソフトを使う。

windowsffmpegをインストールする

動画作成ソフト使うなら、movie makerなりウェブサービスを使うなりもっと手軽なやり方もあるんだろうけども…
ffmpegとはどういうものか軽く引用。


ffmpegは、フリーのソフトでありながら、

・動画や音声のコンバート(数多くの形式に対応している。)

・動画や音声の合成や抽出

コマンドラインインターフェース(CUI)のため、バッチ処理などで利用できる

などの特徴を備えており、動画や音声を加工する際に、非常に便利なツールです。

便利かどうかは人によるかもしれない。

インストール方法は以下のリンクで。
web.plus-idea.net



ちなみにlinux系にも問題なく入る。
この点は便利。


ファイル

作るファイル

  1. mymovie.py
  2. scr_mov.sh

準備しておくファイル

  1. 音楽ファイル(例はaa.wav)
  2. 画像ファイル (例はpic.jpg)

scr_mov.h

シェルスクリプト。わざわざスクリプトしなくてもいいののだけど、せっかくならエンター一本で行いたい。

ffmpeg.exe -loop 1 -framerate 2 -i $1 -i $2 -c:v libx264 -preset medium -tune stillimage -crf 18 -af "afade=t=out:st=71:d=4" -t $4 $3

環境変数を通していなければ絶対パスffmpegを指定する。
(筆者はなぜか環境変数が全部通らなくなったので絶対パス指定で行った。なんとかしたい。)



オプションがとても長い。
少し解説すると[loop 1]は画像1枚をループさせるということ。
[framerate]やその他はyoutube形式に沿ったmp4ファイルを作るためのオプション。
詳しくはマニュアルや識者の記事を。


$1~$4は以下のパイソンコードで指定するファイル名など。

mymovie.py

import subprocess
import wave

def MovieMake(wavefile,fname,times):
    subprocess.run(["sh","scr_mov.sh","pic.jpg","{0}".format(wavefile),"{0}".format(fname),"{0}".format(times)])

def LengthMusic(wavefile):
    wf = wave.open("{0}".format(wavefile) , "r" )
    times = int(wf.getnframes()) / wf.getframerate()
    return times

times = LengthMusic(aa.wav)
MovieMake(aa.wav,bb.mpe,times)

特に注視するものもない気がする。


import subprocess

シェルスクリプトを実行するためのモジュールをインポート。

def MovieMake(wavefile,fname,times):
    subprocess.run(["sh","scr_mov.sh","pic.jpg","{0}".format(wavefile),"{0}".format(fname),"{0}".format(times)])

第一引数でbashを指定。(実はwindowsbash入れてた。)
第二引数でシェルスクリプトを指定。第三で画像を。第四でwavファイル。第五で出力するmp4ファイル名を。

第六引数がちょっと問題でffmpegでマニュアルのまま動画を作ると、最後に無音の動画が数分間流れる。
無音を避けるため、音楽ファイルの再生時間をLengthMusic(wavefile)で取得し、ここで渡す。




python mymovie.py で動画完成!