Power Automate Desktopで「フォルダ内のMP4→JPEG」バッチファイル生成

フォルダ内のMP4ファイルをリストアップし、ffmpegで1枚/秒の静止画を作成させるためのバッチファイルを[Power Automate Desktop](https://powerautomate.microsoft.com/ja-jp/desktop/)で生成します。
モチベーションはこんな感じ。

* セミナーやハンズオンの動画からドキュメントを起こすことがある
* 必要な個所のスクリーンショットをいちいち取得するのは意外と手間（スクショ操作→取得範囲指定→リサイズ）
* あらかじめ1枚/秒とかの静止画を生成し、まとめてリサイズ等をしておきたい
* [ffmpegでできる](http://www.ffmpeg.org/ffmpeg.html#Video-and-Audio-file-format-conversion)のは分かってるけど、毎回やり方をググってしまうし、CLIでのファイル名やフォルダ名の指定が手間

# フローのスクリプト

```Robin
/# 指定されたフォルダ内のmp4ファイルから画像（1枚/秒）を生成するバッチファイルを作成します。
作成者：塚本牧生 <tsukamoto at gmail.com>
作成日：2021/12/24#/
# 対象フォルダの取得
Folder.GetSpecialFolder SpecialFolder: Folder.SpecialFolder.MyPictures SpecialFolderPath=> SpecialFolderPath
Display.SelectFolder Description: $'''処理対象の動画があるフォルダを指定してください。''' InitialDirectory: SpecialFolderPath IsTopMost: True SelectedFolder=> SelectedFolder ButtonPressed=> ButtonPressed
IF ButtonPressed <> $'''OK''' THEN
    EXIT Code: 0
END
# 対象ファイル群の取得
Folder.GetFiles Folder: SelectedFolder FileFilter: $'''*.mp4''' IncludeSubfolders: False FailOnAccessDenied: True SortBy1: Folder.SortBy.NoSort SortDescending1: False SortBy2: Folder.SortBy.NoSort SortDescending2: False SortBy3: Folder.SortBy.NoSort SortDescending3: False Files=> Files
# 対象ファイルの処理
SET BatchText TO $'''chcp 65001
REM ffmpegにより動画（MP4）から静止画（JPEG）を生成します。

cd \"%SelectedFolder%\"
'''
LOOP FOREACH File IN Files
    SET ImageFolder TO $'''%File.Directory%\\%File.NameWithoutExtension%'''
    IF (Folder.IfFolderExists.DoesNotExist Path: ImageFolder) THEN
        Text.AppendLine Text: BatchText LineToAppend: $'''mkdir \".\\%File.NameWithoutExtension%\"''' Result=> BatchText
    END
    Text.AppendLine Text: BatchText LineToAppend: $'''ffmpeg -i \".\\%File.Name%\" -r 1 \".\\%File.NameWithoutExtension%\\%%%%08d.jpg\"''' Result=> BatchText
END
File.WriteText File: $'''%SelectedFolder%.bat''' TextToWrite: BatchText AppendNewLine: False IfFileExists: File.IfFileExists.Overwrite Encoding: File.FileEncoding.UTF8NoBOM
Display.InputDialog Title: $'''サムネイル生成バッチ''' Message: $'''以下のバッチファイルが作成されました。''' DefaultValue: $'''%SelectedFolder%.bat''' InputType: Display.InputType.SingleLine IsTopMost: False
```

# 実行方法

以下のようにして、実行できます。

1. Power Automate Desktopを起動。
2. 「新しいフロー」を選択し、任意の名前（例えば `mp4_to_image` ）を指定。
3. エディターが開いたら、上のスクリプトをコピーし、エディタ領域で貼り付け。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/1fed6c62-99d4-3a37-6fa4-788db09be091.png)
4. 「保存」してからエディターを閉じる。
5. 「自分のフロー」に追加されているので、実行。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/3d7e0ddd-5d3e-eb24-53ff-74e465f241db.png)

生成されたバッチファイルを実行すると、動画ファイルのある場所にファイルのベース名（拡張子のない名前）のフォルダが作成され、その中に1枚/秒の静止画が生成されます。

# メモ

## ffmpegによる静止画出力

ffmpegによる静止画出力は、[ドキュメント](http://www.ffmpeg.org/ffmpeg.html#Video-and-Audio-file-format-conversion)によれば以下のようにすればできる。

```
ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
```

`-s WxH` はサイズ指定、 `-f image2` は拡張子を見てよしなにしてくれてる感じで、元サイズのままでよければ以下でもできた（のでこれを採用している）。 `-r` は1秒あたりに出力する静止画ファイル数で、これは指定しておかないとすごい枚数が出力されてしまう。

```
ffmpeg -i foo.avi -r 1 foo-%03d.jpeg
```

## バッチファイルの文字コード

バッチファイルは文字コード周りにちょっと注意が必要。Power AUtomate Desktopやメモ帳で扱える文字コード範囲内では、以下のようにする。

* 文字コードはUTF-8（バイトオーダーマークなし）にする。
* バッチファイルの先頭行に `chcp 65001` を書いておく。

1点目は、テキストをファイルに書込む際に文字コード「UTF-8（バイトオーダーマークなし）」を選択することで対応している（最後の `File.IfFileExists.Overwrite Encoding: File.FileEncoding.UTF8NoBOM` 部分）。

# 参考

* [Power Automate Desktop](https://powerautomate.microsoft.com/ja-jp/desktop/)
* [アクションの参照 - Power Automate | Microsoft Docs](https://docs.microsoft.com/ja-jp/power-automate/desktop-flows/actions-reference)
* [ffmpeg Documentation](http://www.ffmpeg.org/ffmpeg.html#Video-and-Audio-file-format-conversion)
* [ffmpeg で動画をjpeg画像に切り出し。連続サムネイルをつくる - それマグで！](https://takuya-1st.hatenablog.jp/entry/20110706/1309900617)
* [文字コードをバッチ内で指定 - UTF-8のバッチファイルが文字化けする時の対処3選 – なゆたり](https://nayutari.com/batch-utf8#%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E3%83%90%E3%83%83%E3%83%81%E5%86%85%E3%81%A7%E6%8C%87%E5%AE%9A)