ffmpegで動画から画像ファイルを一括抽出

コンピュータ

ダウンロード

  1. 左側のフレームの「download」をクリック
  2. Windowsの画像をクリック
  3. Windows Buildsをクリック
  4. Download Buildをクリック

インストール

ダウンロードしたファイル(ffmpeg-20190513-dcc9998-win64-static.zip)を適当なフォルダに展開する。
私はh:\toolsに「ffmpeg.exe」「ffplay.exe」「ffprobe.exe」を展開しました。

画像を抽出するコマンド及びオプション

コマンドプロンプト又はPoweShellで実行

h:\tools\ffmpeg.exe -i 抽出したい動画のパス -ss 抽出開始(秒) -t 抽出終了(秒) -r 秒間抽出枚数 -f image2 %03d.jpg

カレントフォルダに001.jpg,002.jpg,003.jpg…と連番で出力されます。%03d.jpgの前に出力先のフォルダを付加するとそのフォルダに連番で出力されます。

動画の長さ(時間)を確認する

動画を抽出するに当たり動画の長さを知る必要がありますので、以下のコマンドで調べます。
h:\tools\ffprobe.exe -i "動画のパス" -hide_banner -show_entries format=duration
結果

・・・省略・・・
[FORMAT]
duration=105.907000
[/FORMAT]

スクリプト

多数の動画ファイルをバッチ処理することを想定してPowerShellスクリプトにしてみました。
ffmpeg.exeffprobe.exeのパスは実行環境にあわせて変更してください。

# 
# ffmpegで動画から画像を抽出するスクリプト
# 
# 動画の開始から終了まで1秒間に1枚画像を抽出します。


param (
    $input_path, # 動画のパス
    $output_dir# 画像を出力するディレクトリ
)

$ErrorActionPreference = "stop"

$ffmpeg_exe = "h:\tools\ffmpeg.exe" # ffmpeg.exeのパス
$ffprobe_exe = "h:\tools\ffprobe.exe" # ffprobe.exeのパス

# 動画から画像を抽出
function Extract-Movie2Image
{
    param (
        $input_path, # 対象動画ファイル
        $output_dir, # 出力ディレクトリ
        $ss, # 抽出開始(秒)
        $t, # 抽出終了(秒)
        $r # 秒間抽出枚数
    )

    $opt = "-i `"${input_path}`" -ss ${ss} -t ${t} -r ${r} -f image2 ${output_dir}%03d.jpg"

    $out = New-TemporaryFile
    $err = New-TemporaryFile

    $proc = Start-Process -FilePath ${ffmpeg_exe} -ArgumentList $opt -Wait -PassThru -RedirectStandardOutput $out -RedirectStandardError $err -NoNewWindow


    switch ($proc.ExitCode) {
        0 {
            $true
        }
        default {
            $false
        }
    }
    rm $out
    rm $err
}

# 動画の長さ(秒)を取得
function Get-MovieLength
{
    param (
        $input_path
    )

    $opt = "-i `"${input_path}`" -hide_banner -show_entries format=duration"

    $out = New-TemporaryFile
    $err = New-TemporaryFile

    $proc = Start-Process -FilePath ${ffprobe_exe} -ArgumentList $opt -Wait -PassThru -RedirectStandardOutput $out -RedirectStandardError $err -NoNewWindow


    switch ($proc.ExitCode) {
        0 {
            (Get-Content $out) | % {
                if ($_ -match "duration=(\d+(\.\d+)?)") {
                    [int]$matches[1]
                } else {
                    $null
                }
            }
        }
        default {
            $null
        }
    }
    rm $out
    rm $err
}

$t = Get-MovieLength $input_path
Extract-Movie2Image $input_path $output_dir 0 $t 1

コメント