mpv @ Next File (Nautilus Sort)

しつこいようだけど mpv で次のファイルを再生させるスクリプト。
順番が Nautilus と同じでないのでイマイチ不便だなって。

だったらコレも作ってしまえ!
Gjs なり PyGObject なりでソートさせて出力するコマンドを。
mpv の拡張スクリプトでは無理なのでコマンドを自作する。
それを Lua で呼び出せばなんとかなるはず。

ついでに、いちいち拡張子を指定するのも面倒臭い。
てか Lua がショボいなら自作コマンドのほうで正規表現を使えばいい。
で、GNOME では動画ファイルの ContentType は以下のようになっている。

video/mp4
video/quicktime
video/x-matroska

ContentType なら先頭の video/ だけで動画ファイルを見分けできる。
ということでこんなスクリプトを書いてみた。

#!/usr/bin/gjs

if (ARGV.length == 0) {
    print('usage: nautilus_ls {DIRNAME}');
} else {
    const GLib = imports.gi.GLib;
    const Gio = imports.gi.Gio;
    const re = /^video\//;

    let files = [];
    let d = Gio.file_new_for_path(ARGV[0]);
    let ls = d.enumerate_children('standard::content-type', 0, null);
    for (;;) {
        let info = ls.next_file(null);
        if (info == null)
            break;
        let t = info.get_content_type();
        if (re.test(t))
            files.push(info.get_name());
    }
    files.sort((s1, s2)=> {
        let cmpstr1 = GLib.utf8_collate_key_for_filename(s1, -1);
        let cmpstr2 = GLib.utf8_collate_key_for_filename(s2, -1);
        if (cmpstr1 < cmpstr2)
            return -1;
        return 1;
    });
    print(files.join('\n'));
}

// ex: ft=js

Gjs での例。
nautilus_ls という拡張子無しファイル名でパスの通った場所に保存。
実行パーミッション追加でコマンドの出来上がり。
このコマンドを Lua で呼び出しする。

-- ~/.config/mpv/scripts/next_prev.lua

local utils = require 'mp.utils'

-- Ctrl+DOWN @ Next File Play
function on_nextfile()
    local hit = false
    local directory, fn = utils.split_path(mp.get_property('path'))
    if directory == '.' then
        directory = utils.getcwd()
    end
    local pfile = io.popen('nautilus_ls  "'..directory..'"')
    for filename in pfile:lines() do
        if hit then
            mp.commandv('loadfile', utils.join_path(directory, filename))
            if mp.get_property_bool('pause') then
                mp.set_property_bool('pause', false)
            end
            break
        end
        hit = filename == fn
    end
    pfile:close()
end
mp.add_key_binding('Ctrl+DOWN', 'nextfile_func', on_nextfile)

-- Ctrl+UP Previous File Play
function on_prevfile()
    local prevfn = ''
    local directory, fn = utils.split_path(mp.get_property('path'))
    if directory == '.' then
        directory = utils.getcwd()
    end
    local pfile = io.popen('nautilus_ls  "'..directory..'"')
    for filename in pfile:lines() do
        if filename == fn and prevfn ~= '' then
            mp.commandv('loadfile', utils.join_path(directory, prevfn))
            if mp.get_property_bool('pause') then
                mp.set_property_bool('pause', false)
            end
            break
        end
        prevfn = filename
    end
    pfile:close()
end
mp.add_key_binding('Ctrl+UP', 'prevfile_func', on_prevfile)

イケた!
GNOME 限定です、他の環境の人は参考程度に。

pic 2022.02.06

今日の五条川は雪です。
よし雪景色の写真を撮影してみよう。

でも雪は少ないし雪雲なので白黒な地味すぎる写真に。
なので Olympus Workspace でアートフィルターを掛けてみる。

snow01

ポップアート II を掛けてみた。
ほぼ白黒だったのがいい感じに色づいてくれた。
うん、原色に拘らなくてもいいんだよ。

snow02

ドラマチックトーンを掛けてみた。
舞っている雪が一番強調されたのがこのフィルターだった。
RAW そのままだと全然見えなかったんだよね。

写真を原色から弄って何が楽しいんだ?
そう思っていた頃が筆者にもありました。
色々試していたら恐ろしいくらい時間がたっていました。

OM SYSTEM の Youtube でプロがアートフィルターを勧めていたのよ。
プロが言うならやってみようって感じで。
RAW で撮影すれば現像アプリでフィルターを撮影後に適用できるのね。
てかカメラ側のフィルター機能ってぶっちゃけ使わないよね。

hiyodori

今日はヒヨドリしかまともに撮れませんでした。
でも巨大写真もあるよ。
0206hiyo.jpg (5184x3888px) 6.2MB

editorconfig Gedit 41

「秀丸エディタ」が10年以上ぶりのメジャーバージョンアップ ?v9.00が正式版に – 窓の杜

Windows は会社でしか使わなくなって何年もたつので今頃知ったけど。
editorconfig って何だろう、モードラインよりイイのか?

チーム開発に効く環境構築術 | 第1回 EditorConfigのススメ | CodeGrid

モードラインじゃダメなのか?って感じだな。
あぁ VSCode というゴミクソエディタがモードラインを使えないからか。

EditorConfig

対応エディタって、よく見たら全部単なるプラグインじゃん。
Gedit のプラグインもあるのでチビッと試してみるか。

GitHub – editorconfig/editorconfig-gedit: EditorConfig plugin for Gedit

Gedit 41 だけど Gedit 3 用で動くだろう。
でもいきなり Installation が間違っています。

editorconfig.plugin
editorconfig_gedit3.py
editorconfig_plugin

editorconfig-core-py の中にある editorconfig
ディレクトリのコピーが必要でした。

editconfig

それと以下を書き換えする必要がありました。

editorconfig.plugin にて Loader=python3 に書き換え。
Loader=python のままでは Python2 を呼び出そうとする。

editorconfig_plugin/gedit3.py にて。
document.get_location は Gedit 40 から使えなくなっています。

#location = document.get_location()
location = document.get_file().get_location()

後は設定で有効にして .editorconfig を書いて。
筆者は Tab 設定を Python ガイドラインな半角スペース 4 つにしているので。

root = true

[*]
indent_style = tab
indent_size = 8

おぉ反映されるようになりました。
たださ。

// ex: noet ts=8

モードラインなら最終行にコレ書くだけでまったく同じことができるんだよね。
Gedit なら最初からプラグイン入っているし Atom にもプラグインあるし。

いや筆者はモードラインも拡張子が無いスクリプトに ft 指定するだけなんだが。
ただ Gedit も Atom もファイル判別が優秀すぎて滅多に必要が無いんだなこれが。

てかコレ別ファイルに記述なのでファイルタイプ指定ができないし。
拡張子が必ずある Windows 専用ですね。

pic 2022.01.30

今日のごじょ、、、、、ではなく久々の木曽川。
とにかく晴れそうになかったのでせめて違う場所にでもと。

monme

E-M5 ちゃん、こんなふうにしか使っていなくてごめんよ。
春になったらイッパイ使ってあげるから、多分。

sime

シメ、そうだココは冬にコイツが来るんだ。
地鳴きがけっこうやかましいということを今更知った。

haitaka

ハイタカ、だと思う。
何の鳥なのかわからずコッチを向いてくれるのをじっと待ったぜ。

tsunami

ツグミ、ココでは簡単に見つかりますね。
しかし見事に背景が真っ白な雲ばかりだなって。

shirohara

シロハラ、ツグミとはセットみたいなもの。
この鳥ってあまり人を恐れないというか普通に無視しますよね。

他にシジュウカラやコゲラやジョウビタキ等も撮影できました。
しかしココは今年の冬も鴨狙いのカメラマンばかりだなって。
フルサイズ換算 800mm でも米粒サイズでしか撮れない遠さなのに。

mpv @ Lua to Javascript

mpv を Lua で拡張するのが楽しい皆様。
こんなトコを見つけました。

GitHub – samhippo/mpv-scripts

参考になります、いやコピペでそのまま使ってもいいんだけど。
Windows 限定のコードが所々あるので macOS や Fedora の人は注意です。

そういえばこの人は複数拡張子のマッチをどうやっているんだろう?

mpv-scripts/next-file.lua at master ? samhippo/mpv-scripts ? GitHub

拡張子文字列で連想配列を作り値を全部 true に。

lua_nil

存在しなければエラーではなく nil になる、なるほど。
酷い手段だけど Lua 自体が色々とショボいからしかたがないか。

いやまて、この方法でディレクトリ内を列挙できるんだよな。
ls コマンドが不要なら正規表現が強力な Javascript を使うという手が。
とりあえず mp.utils を Javascript ではどう呼び出すか試す。

// ~/.config/mpv/scripts/test.js

function on_test() {
    //let dir = mp.utils.split_path(mp.get_property('path')); // ES5...
    var dir = mp.utils.split_path(mp.get_property('path'));
    mp.osd_message('Playng File: ' + dir[1]);
}
mp.add_key_binding('Ctrl+3', 'test_func', on_test);

なんだ、ドットで普通に使えるヤン。
しかし let 宣言でエラー、まさか今更 ECMAScript 5…

mpv.io

mpv.io にも書いていた、for-of とかも当然使えないな。
ES5 でも正規表現は同じはずだ、使ってみる。
以前書いたディレクトリ内で次のファイルを js で丸ごと書き換え。

// ~/.config/mpv/scripts/next_prev.js

var re = /\.(mov|m4v|mp4)$/i;

// Ctrl+DOWN でディレクトリ内の次ファイルを再生
function on_nextfile() {
    var dir = mp.utils.split_path(mp.get_property('path'));
    // カレントディレクトリだとドットになるので
    if (dir[0] == '.') dir[0] = mp.utils.getcwd();
    // ls
    var ls = mp.utils.readdir(dir[0], 'files');
    ls.sort();
    if (mp.last_error() == '') {
        // for-of が使いたい...
        var len = ls.length;
        var ex = false;
        for (var i=0; i<len; i++) {
            var f = ls[i];
            if (re.test(f) && ex) {
                mp.commandv('loadfile', mp.utils.join_path(dir[0], f));
                if (mp.get_property_bool('pause'))
                    mp.set_property_bool('pause', false);
                break;
            }
            ex = f == dir[1];
        }
    }
}
mp.add_key_binding('Ctrl+DOWN', 'nextfile_func', on_nextfile);

// Ctrl+UP でディレクトリ内の手前ファイルを再生
function on_prevfile() {
    var prevfn = '';
    var dir = mp.utils.split_path(mp.get_property('path'));
    if (dir[0] == '.') dir[0] = mp.utils.getcwd();
    var ls = mp.utils.readdir(dir[0], 'files');
    ls.sort();
    if (mp.last_error() == '') {
        var len = ls.length;
        var ex = false;
        for (var i=0; i<len; i++) {
            var f = ls[i];
            if (re.test(f)) {
                if (dir[1] == f && prevfn != '') {
                    mp.commandv('loadfile', mp.utils.join_path(dir[0], prevfn));
                    if (mp.get_property_bool('pause'))
                        mp.set_property_bool('pause', false);
                    break;
                }
                prevfn = f;
            }
        }
    }
}
mp.add_key_binding('Ctrl+UP', 'prevfile_func', on_prevfile);

動くジャン。
ただ ls と違ってソートしないとよくワカラン順番になるみたい。

loadfile は半角スペース付きでもダブルクォートで囲む必要は無かったのね。
というか URI にする必要すら無かった、とほほ。

とにかくコレで完璧な拡張子判別ができるようになった。
慣れた言語はやっぱり楽だね、言語仕様を調べる必要が無いし。
自由に改造して使ってください、Windows でも多分動くと思う。