Mpv で動画にチャプターを作成する

mpv の操作をショートカット化したくて調べたので残します。

動画再生ソフトによってはチャプタが設定できるものもあるようなので、mpv にも同様に機能がないか調べましたが、見つけられませんでした。ただ、mpv 自体にチャプタ移動自体はありそうで、独自スクリプトもできるようだったので、多分できるだろうと思いました。

## 環境
* Windows です。
* mpv 自体も自分でビルドしたものではなく、別のソフトウェアに同梱されていたもので、特にインストーラなどを動かしていないので、環境変数などの設定はされていません。
  * 普通に mpv.net をインストールするとおそらくいろんなメニュー設定も出るようになると思われますが、そんなものは出てこないです。素の mpv.exe だけが存在しています。

## スクリプトをもらってくる
[User Scripts · mpv-player/mpv Wiki · GitHub](https://github.com/mpv-player/mpv/wiki/User-Scripts) で chapter で検索をかけると、[chapter-make-read](https://github.com/dyphire/mpv-scripts/blob/main/chapter-make-read.lua) というスクリプトがあるのでもらってきます。

もらってきたスクリプトは `C:\Users\<USERNAME>\AppData\Roaming\mpv\scripts` に置きます（デフォルトの設定のままならば）。mpv の起動時に読み込まれます。

## ショートカットキー自体を変更する

スクリプトの中身を読むと (Lua で書かれています。私はよくわかりません。）、キーバインドを設定して動かして使うように書かれています。

```
-- This script also supports manually load/refresh,marks,edits,remove and creates external chapter files, usage:
-- Note: It can also be used to export the existing chapter information of the playback file.
-- add bindings to input.conf:
-- key script-message-to chapter_make_read load_chapter
-- key script-message-to chapter_make_read create_chapter
-- key script-message-to chapter_make_read edit_chapter
-- key script-message-to chapter_make_read remove_chapter
-- key script-message-to chapter_make_read write_chapter chp
-- key script-message-to chapter_make_read write_chapter ogm
```

ということで、`input.conf`を作ります。 [こちら（mvp.net 6.0.4.0 日本語化｜きゅう）](https://note.com/jolly_mango538/n/nfa26deb56be5)を参照させてもらうと、だいたい構造がわかります。詳細も[ここ](https://mpv.io/manual/stable/#input-conf) にありますが、深堀りしません。

とりあえず `input.conf` ファイルを作成して、中にショートカット設定を書きます。

* 先程のスクリプト中の指示にしたがって、`key` を実際のキーバインドに置き換えたものを作ります。
  * 普段、mpv でショートカットを使わないので、どのキーを上書きしても困ることはないので、数字キーにしてます。
  * ちなみに Shift と組み合わせる場合は `Shift+1` `Shift+a` のように `Shift+` と、Ctrl と組み合わせる場合は `Ctrl+` と書くようです。

```
1 script-message-to chapter_make_read load_chapter
2 script-message-to chapter_make_read create_chapter
3 script-message-to chapter_make_read edit_chapter
4 script-message-to chapter_make_read remove_chapter
5 script-message-to chapter_make_read write_chapter chp
6 script-message-to chapter_make_read write_chapter ogm
```

作ったファイルは、mpv.exe と同階層に置きました。mpv の説明書きを見ると、Windows では `%AppData%/mpv` の下に置くような気がしますが、自分の環境では読み込んでくれませんでした。input.conf ファイルの説明を見る限りは、mpv.exe と同階層でも良いが優先順位は低くなる、ということのようです。

ここまでで、実際に動かしてみると、`2` create_chapter でチャプタが作成され、`5` でチャプタ書き出し（動画ファイルと同階層に、`ファイル名.chp` が出来上がる）、閉じたあとに再度動画ファイルを再生するとチャプタが残っている（読み込まれている）ことが確認できました。

## 設定変更
### チャプタ作成タイミングでの一時停止回避
チャプタを作成したタイミングで、動画が一時停止になりましたが、スクリプトファイル上部のローカル変数（辞書） o の中にある

```
pause_on_input = true
```

を false に変更すると、一時停止がかからなくなります。

### 作成したチャプタの自動保存
作成したチャプタはデフォルトでは `write_chapter` を実行しないと出力されません。自動で保存するために

```Lua
autosave = false
```

を true に変更すると、スクリプト読み込みに「ファイル保存での write_chapter の実行」がかかります。~~ただし、チャプタを作成しなくてもファイルが作成されるようになります。~~

デフォルトの自動保存設定は、強制的にファイルを上書き（作成）するモードのため、チャプタがなくてもされる設定になっています。これを回避するには、

```Lua:chapter-make-read.lua
if o.autosave then
    mp.add_hook("on_unload", 50, function() write_chapter("chp", true) end)
end
```

`write_chapter` の２つ目の引数（force_write) を `false` に変更します。

### チャプタファイルの保存先を固定する

再生するファイルと同階層にチャプタファイルを保存すると、動画ファイルといっしょにチャプタファイルを移動する必要が出ます。なので、保存先を固定（グローバルに）したいです。

スクリプト中には
```Lua:chapter-make-read.lua
global-chapters = false,
```
という行があり、ここの切り替えでうまくいく「はず」なのですが、自分の環境ではうまくいきませんでした。`mp.command_native({ "expand-path", o.global_chapters_dir })` あたりでのパス変換がうまく言っていないのでしょうか。

そのため、
```Lua:chapter-make-read.lua
global_chapters_dir = mp.command_native({ "expand-path", o.global_chapters_dir })
```

で指定されている `global_chapters_dir` を直接パス指定します。なお、バックスラッシュは多くの言語同様エスケープ文字として認識されるので `\\`で区切ります。

これで、スクリプトの直接書き換えですが、固定されるようになります。

Mpv 独自のコマンドやパスの変換の挙動を、もう少し理解したいですね。

おわり