LoginSignup
8
8

More than 3 years have passed since last update.

Pythonで複数枚の静止画を動画化する

Last updated at Posted at 2020-07-18

概要

「同じ場所から毎日撮っている写真」などをつなぎ合わせて、スライドショーっぽい動画にする方法を紹介。PythonのライブラリMoviePyを使用する。

動作確認環境

  • Python3.6(Python2系での動作は未確認)
  • OS : Ubuntu 18.04
    • Pythonがインストール可能であれば、他のOSでも問題なく動くはず

事前準備

  • Pythonのインストール(説明は割愛)
  • 下記コマンドでMoviePyをインストール
$ pip install moviepy
  • [参考]MoviePyのインストール方法が書かれたサイト

  • スライドショーにする静止画像を用意

    • inputディレクトリ配下に、スライドショーでつなげたい順番にインデックスをつけて静止画像(拡張子は.png,.jpgなど)を配置
    • 以下はその一例だが、Pythonのソース内でファイル名で昇順ソートした際にスライドショーでつなげたい順番に並ぶのであれば、以下の名前規則に従わなくてもOK。
input
├── IMG_0000.jpg
├── IMG_0001.jpg
├── IMG_0002.jpg
├── ...

ソース全体

  • 以下のソースをpython create_slideshow.pyで実行すると、静止画を0.5秒間隔でつなげた動画像output.mp4が出来上がる。
create_slideshow.py
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-

import glob
from moviepy.editor import *

if __name__ == '__main__':

    # inputディレクトリ以下の拡張子が.jpgのファイル名リストを一括取得
    file_list = glob.glob(r'input/*.jpg')
    # ファイル名リストを昇順にソート
    file_list.sort()

    # スライドショーを作る元となる静止画情報を格納する処理
    clips = [] 
    for m in file_list:
        clip = ImageClip(m).set_duration('00:00:00.50')
        clip = clip.resize(newsize=(640,480))
        clips.append(clip)

    # スライドショーの動画像を作成する処理
    concat_clip = concatenate_videoclips(clips, method="compose")
    concat_clip.write_videofile(r"output.mp4", 
                                fps=24,
                                write_logfile=True,
                                )

解説

スライドショーを作る元となる静止画情報を格納する処理

    clips = [] 
    for m in file_list:
        clip = ImageClip(m).set_duration('00:00:00.50')
        clip = clip.resize(newsize=(640,480))
        clips.append(clip)
  • ImageClip(m).set_duration('00:00:00.50')
    • 各画像の表示時間を設定。数値入力も可能で、その場合の単位は「秒」になる模様
  • clip.resize(newsize=(640,480))
    • 動画像(clip)のサイズを変更。一般的に静止画の画像サイズは動画像よりも大きく、そのまま処理するとドデカい動画像が出来てしまうので、予めここでサイズ変更していた方がよさそう。
    • ちなみに筆者が試した画像のサイズは4032×3024で、リサイズせずに変換をかけたらマシンのリソース不足で処理がハングアップした…

スライドショーの動画像を作成する処理

    concat_clip = concatenate_videoclips(clips, method="compose")
    concat_clip.write_videofile(r"output.mp4", 
                                fps=24,
                                write_logfile=True,
                                )
  • concatenate_videoclips(clips, method="compose")
    • 動画像リスト(clips)をつなぎ合わせて一つの動画像にする処理。
    • 引数methodchainまたはcomposeを選択可能。ドキュメントを見ると、つなぐ前の動画像のサイズが異なる場合はcomposeを使う方がよさそう。今回の場合は、予め動画像のサイズを640x480にしていて同じサイズになっているので、method="chain"にしても動くことを確認済。
  • concat_clip.write_videofile(r"output.mp4",…
    • 動画像をファイル出力
    • write_logfile=Trueにすると、出力ファイルを作成するログがoutput.mp4.logという名前で下記のように出力され、裏でffmpegが動いていることを確認できる。
output.mp4.log
ffmpeg version 4.2.2-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, rawvideo, from 'pipe:':
  Duration: N/A, start: 0.000000, bitrate: 176947 kb/s
    Stream #0:0: Video: rawvideo (RGB[24] / 0x18424752), rgb24, 640x480, 176947 kb/s, 24 tbr, 24 tbn, 24 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
[libx264 @ 0x6856ac0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x6856ac0] profile High, level 3.0, 4:2:0, 8-bit
[libx264 @ 0x6856ac0] 264 - core 159 r2991 1771b55 - H.264/MPEG-4 AVC codec - Copyleft 2003-2019 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=24 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output.mp4':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 640x480, q=-1--1, 24 fps, 12288 tbn, 24 tbc
    Metadata:
      encoder         : Lavc58.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame=   85 fps=0.0 q=28.0 size=       0kB time=00:00:01.33 bitrate=   0.3kbits/s speed=2.58x    
frame=  148 fps=145 q=28.0 size=     512kB time=00:00:03.95 bitrate=1059.7kbits/s speed=3.89x    
frame=  205 fps=130 q=28.0 size=     768kB time=00:00:06.33 bitrate= 993.4kbits/s speed=   4x
...
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8