メインコンテンツまでスキップ

mpv

ここではメディアプレイヤー mpv の設定についてまとめておきます.

mpv はクロスプラットフォームのメディアプレイヤーです.以前は MPC-BE を使っていました. MPC-BEは使いやすかったのですが、ちょっとしたカスタマイズがやりづらかったので、mpv に移行しました. ここでは、私がカスタマイズした内容を備忘録としてまとめておきます.環境は Windows です.

インストール

shinchiro/mpv-winbuild-cmake からバイナリをダウンロードして適当な場所に展開します. mpv.exe に対して必要に応じて関連付けします.

設定

mpv.exe ファイルがあるディレクトリの mpv ディレクトリに設定ファイルやスクリプトを追加します.

全体の設定

mpv/mpv.conf に設定します.

# 再生が終了しても閉じない
keep-open=yes

# プレイリストはループ
loop-playlist=inf

# 常にウィンドウを開く.音声再生など
force-window=yes

# Terminalで出力を抑える
quiet=yes

# OSD用のフォント
osd-font = "Sarasa Fixed J"
osd-font-size = 40

# スクリーンショット (<user> は自分のユーザー名)
screenshot-format=jpg
screenshot-template="%f-%P"
screenshot-directory="C:\Users\<user>\downloads"

# 字幕優先
slang=eng,en,ja

# 字幕ファイル検索
sub-auto=fuzzy

キーバインディング

mpv/input.conf に設定します.

WHEEL_UP        ignore
WHEEL_DOWN ignore
WHEEL_LEFT ignore
WHEEL_RIGHT ignore

RIGHT frame-step
LEFT frame-back-step

SHIFT+RIGHT no-osd seek 1 exact
SHIFT+LEFT no-osd seek -1 exact
SHIFT+DOWN no-osd seek 30 exact
SHIFT+UP no-osd seek -30 exact

F8 show-text "${playlist}"

Alt+j cycle secondary-sid
Alt+left add video-pan-x 0.05 # move the video right
Alt+right add video-pan-x -0.05 # move the video left
Alt+up add video-pan-y 0.05 # move the video down
Alt+down add video-pan-y -0.05 # move the video up
Alt+PGUP add video-zoom 0.1 # zoom in
Alt+PGDWN add video-zoom -0.1 # zoom out

ESC quit

[ cycle_values speed 1.25 1.5 2.0 3.0 4.0 1.0
] cycle_values speed 0.75 0.5 0.25 1.0
r cycle_values video-rotate 270 180 90 0
f cycle fullscreen

KP0 seek 0 absolute-percent
KP1 seek 10 absolute-percent
KP2 seek 20 absolute-percent
KP3 seek 30 absolute-percent
KP4 seek 40 absolute-percent
KP5 seek 50 absolute-percent
KP6 seek 60 absolute-percent
KP7 seek 70 absolute-percent
KP8 seek 80 absolute-percent
KP9 seek 90 absolute-percent

以下のようなキーバインディングになっています.

KeyAction
マウスホイール何もしない
LEFT, RIGHT1フレーム戻る、進む
Shift + LEFT, Shift + RIGHT1秒戻る、進む
Shift + UP, Shift + Down30秒戻る、進む
F8プレイリストを表示
Alt + J音声トラック切り替え
Alt + 十字キーパン
Alt + PGUP, Alt + PGDOWNズームイン、ズームアウト
ESCmpvを終了
[, ]再生速度の調整
r画面の回転
fフルスクリーン
KP0 .. KP9再生シーク位置.KP の後の数値は全体の割合.

字幕

字幕は開いたファイルと同じディレクトリに .srt ファイルや .vtt ファイルなどがあれば自動で読み込んでくれます. また、字幕ファイルのファイル名が、元動画のファイル名の末尾に en などの言語を含んでいるような場合、sub-autofuzzy を設定してファジー検索を有効にすると認識してくれるパターンが多くなります.

字幕は通常動画の上に重ねて表示されます.映画などではあまり気にならないのですが、アプリケーションの解説だったり、講義などでは字幕が邪魔になる場合があります. その場合は、画面下部に字幕用の領域を確保してそこに表示するようにしたいです.そのため、字幕用のプロファイルを作成します.これは、mpv/mpv.conf に追記します.

[subt]
profile-cond=get('current-tracks/sub/title') ~= nil
video-zoom=-0.3
video-align-y=-1
sub-use-margins=yes
sub-scale-by-window=yes
sub-pos=100
sub-margin-x=10
sub-margin-y=30
sub-align-x=left
secondary-sub-pos=87
sub-font="Roboto"
sub-font-size=28
sub-ass-line-spacing=5

profile-condで字幕があれば、自動でこのプロファイルが適用されます. このプロファイルを適用すると次のように表示されます.

subtitle
図 1: Ceres Fauna Ch. hololive-EN : 【MINECRAFT】 Yes, I'm still working on this big ol tree

これは、字幕2行分の領域を確保しています.また、左側に寄せていますが、中央表示なら sub-align-xcenter を指定します.あと、字幕領域を確保するために元の動画を縮小しています.他はお好みで設定.

動画の長さを常に表示

標準では再生時間と残りの時間が表示されます.残りの時間ではなく、動画の長さを常に表示するには mpv/script-opts/osc.conf に設定を追加します.ファイルがなければ作成します.

mpv/script-opts/osc.conf
timetotal=yes

コンソールフォント

画面に表示されるコンソールのフォントは mpv/script-opts/console.conf で設定します.

mpv/script-opts/console.conf
font = "Sarasa Fixed J"
font-size = 24

プレイリストに複数のファイルがあればループ再生させない

設定でプレイリストをループ再生に設定していますが、これは1つのファイルを開いたときにループ再生させるためです.もし、プレイリストに複数のファイルが登録されている場合はループ再生しないようにしたいので、字幕と同じようにプロファイルを作成します.

[noloop]
profile-desc=cond:get("playlist-count", 1) >= 2
loop-file=no

音楽も mpv で聴く場合はこの設定は向いていないかもしれません.私は音楽の場合 foobar2000 で聴いていますので、このような設定になっています.

スクリプト

mpv は Lua や JavaScript で手軽にカスタマイズできます. 私が使っているのは以下のスクリプトです.

ScriptDescription
multiloopループポイントをいくつも設定できる
nextfile再生中のファイルがあるディレクトリから次の(または前の)ファイルを再生する
appendURLクリップボードにあるURLをプレイリストに追加
cheatsheet画面に標準のキーバインディングを表示
screenshot-mosaicMPC-HC にあるような一定間隔のフレームを1つの画像に連結した画像の作成.

このうち、multiloop は独自に機能を増やしたり、保存ファイルを lua から json に変更したりしています.また、screenshot-mosaic も出力する情報や背景色などをカスタマイズしています.他に multiloop をベースにチャプターを作成、保存する chapter というスクリプトも独自に作成しています.

これらのスクリプトは mpv/scripts に入れます.また、必要に応じて mpv/script-opts にファイルを作成します.これは、スクリプトから参照する変数などが定義されています.

chapter スクリプト

ここでは、chapter スクリプトの作成について、少し解説しておきます.

まず、json を扱う場合は json.lua を使います.これを mpv/lua ディレクトリに入れます.mpv/lua ディレクトリがなければ作成します.また、もっと手軽にjsonを扱うためにヘルパーライブラリ mpv/lua/jsonutil.lua を作成します.

mpv/lua/jsonutil.lua
local json = require("json")
local jsonutil = { _version = "0.0.1" }

function jsonutil.file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end

function jsonutil.write_file(path,text)
local file, e = io.open(path, "w");
if not file then
return error(e);
end
file:write(text);
file:close()
end

function jsonutil.save_json(path,data)
jsonutil.write_file(path, json.encode(data))
end

function jsonutil.load_json(path)
local f=io.open(path,"r")
if f~=nil then
local data = f:read("*a")
f:close()
return json.decode(data)
end
return nil
end

return jsonutil

これを使った chapter スクリプトは次のようになります:

mpv/script/chapter.lua
local mp = require("mp")
local assdraw = require("mp.assdraw")
local mpopts = require("mp.options")
local jsonutil = require("jsonutil")

local options = {
keybind = "N",
message_duration = 1
}

local chapters = {}
local ab = {}
looping = false

local message
message = function(text, duration)
local ass = mp.get_property_osd("osd-ass-cc/0")
ass = ass .. text
return mp.osd_message(ass, duration or options.message_duration)
end

function drawMenu()
local window_w, window_h = mp.get_osd_size()
local ass = assdraw.ass_new()
ass:new_event()
ass:append(" \\N\\N")
ass:append("{\\b1}Chapter{\\b0}\\N")
ass:append("{\\b1}1{\\b0} set chapter\\N")
ass:append("{\\b1}s{\\b0} save chapters to file\\N")
ass:append("{\\b1}a{\\b0} show chapters\\N")
ass:append("{\\b1}n/b{\\b0} next/prev chapters\\N")
ass:append("{\\b1}ESC{\\b0} hide\\N")
mp.set_osd_ass(window_w, window_h, ass.text)
end

function clearMenu()
local window_w, window_h = mp.get_osd_size()
mp.set_osd_ass(window_w, window_h, "")
mp.osd_message("", 0)
end

function setChapterTime()
local start_time = mp.get_property_number("time-pos")
clearMenu()
table.insert(chapters, {start_time, ""})
message("chapter set")
end

function savePositions()
if #chapters == 0 then
message("nothing to save")
else
local fn = mp.get_property("filename/no-ext")
jsonutil.save_json(fn .. "-chapter.json", chapters)
message("saved to file")
end
end

function showPositions()
clearMenu()
if #chapters == 0 then
message("No chapters")
else
local buf = ""
for i=1, #chapters do
buf = buf .. string.format("[%d] %s (%.3f)\n", i, chapters[i][2], chapters[i][1])
end
message(buf)
end
end

function nextPosition()
clearMenu()
if p_count ~= #chapters then
p_count = p_count + 1
else
p_count = 1
end
message(string.format("[%d] %s (%.3f)", p_count, chapters[p_count][2], chapters[p_count][1]))
mp.set_property_native("time-pos", chapters[p_count][1])
end

function prevPosition()
clearMenu()
if p_count > 1 then
p_count = p_count - 1
else
p_count = #chapters
end
message(string.format("[%d] %s (%.3f)", p_count, chapters[p_count][2], chapters[p_count][1]))
mp.set_property_native("time-pos", chapters[p_count][1])
end

p_count = 1

function main()
mp.add_forced_key_binding("1", "1", setChapterTime)
mp.add_forced_key_binding("s", "s", savePositions)
mp.add_forced_key_binding("a", "a", showPositions)
mp.add_forced_key_binding("n", "n", nextPosition)
mp.add_forced_key_binding("b", "b", prevPosition)
mp.add_forced_key_binding("ESC", "ESC", clearMenu)

local fn = mp.get_property("path"):match("(.+)%..+$") .. "-chapter.json"
if jsonutil.file_exists(fn) == true then
chapters = jsonutil.load_json(fn)
end

drawMenu()
end

mp.add_key_binding(options.keybind, "display-chapters", main)

ベースは multiloop なので、いくつかのメソッド名とかはそのままになっていますが、まあ問題ないでしょう.

構成

最終的な構成は次のようになっています:

mpv.exe
mpv/
mpv.conf
input.conf
font.conf
scripts/
appendURL.lua
chapter.lua
mpv-cheatsheet-v0.30.0.2.js
multiloop.lua
nextfile.lua
screenshot-mosaic.js
script-opts/
console.conf
osc.conf
screenshot-mosaic.conf
lua/
json.lua
jsonutil.lua

Anker Eufy ネットワークカメラを使って録画する

カメラを使って監視したい場合、Anker Eufy ネットワークカメラは普通にSDカードや外部クラウドに保存できたり、ブラウザでも閲覧できます.それ以外の方法でPCからカメラを通して閲覧し、録画できると便利です.これは非公式なやり方なので取扱いには注意です.

まず、カメラの映像をPCで見る場合は以下が参考になります:

mpv も rtsp プロトコルで閲覧することが可能です.その場合 rtsp://<user>:<pass>/<ip>/live0 というURLになります.これを使ってローカルにライブ映像を保存できます.たとえば、h.264形式で保存する場合

mpv.exe rtsp://<user>:<pass>/<ip>/live0 --stream-record=<output> --ovc=libx264 --ovcopts=crf=23

となります.それぞれ、<user>, <pass>, <ip>, <output> は書き換えてください. 保存するときの解像度変更は --vf=scale などいろいろ試しましたが、結局できませんでした.

以上です.

最終更新