投稿者「sasakima-nao」のアーカイブ

Fedora 24 ISO Download

Fedora 24 正式公開したようです @ JPN 6.22.2016 1:00。
今回も初日には Get Fedora からは iso を落とせません。

日本はユーザー数の関係からマジで後回しにされているのか。
いや、今回は DistroWatch.com からのリンクも無いんですけど。

Torrent Server for the Fedora Project
BitTorrent でなんとかなった。

transmission

Transmission を初めて使ったけど。
自身のダウンロードが完了したら「ピーン」って音が鳴り通知領域に通知が来るのね。
マジで何事かと、初めて使ったアプリなのに未来を感じた。

torrent_ok

遅番なので今から寝る、インストールとレビューは起きたら、もしくは明日。

JXA NSString

久々に Mac で JavaScript(JXA) を。
JavaScript 文字列と NSString の相互変換が今まで解らなかった。

OS?X 10.10 Release Notes

公式の解説にて $() だけで NSString に変換できるのは理解。
でも逆がドコにも書いていないんですけど。
散々探してやっと以下を見つける。

Home ? dtinth/JXA-Cookbook Wiki ? GitHub
Shell and CLI Interactions ? dtinth/JXA-Cookbook Wiki ? GitHub

んと、ObjC.unwrap で NSArray を JavaScript 形式に変換できるのか。
ならば NSString もイケるかな?と適当にやったら出来ちゃった。
ということで JXA, NSString 関連の覚書。

ObjC.import("Cocoa");

console.log("日本語も大丈夫");
$.NSLog("%@ %@", $("NSString"), $("はこうする"));

var jsStr = "変数も $() で変換できる\n";
var nsStr = $(jsStr);
$.NSLog("%@", nsStr);

nsStr = $("NS* から JavaScript 形式へは ObjC.unwrap()");
jsStr = ObjC.unwrap(nsStr);
console.log(jsStr);

var saveStr = "保存します\n";
saveStr += "戻り値が表示されるので変数に入れています\n";
var data = $(saveStr).dataUsingEncoding($.NSUTF8StringEncoding);
var res = data.writeToFileAtomically("output.txt", true);

if (res) {
    var terminal = Application("Terminal");
    var fm = $.NSFileManager.defaultManager;
    var cwd = fm.currentDirectoryPath;
    var nil = terminal.doScript("cat " + ObjC.unwrap(cwd) + "/output.txt");
}

jxa_nsstring

よし日本語もこれでバッチリ(死語)
Cookbook は他にも色々試したいコードが沢山あって素晴らしい。

しかし Cookbook も var とセミコロンを全部書いているんだね。
JXA では不要と言われても無いとキモいのは皆同じようである。

PyGObject SendMessage and PostMessage

GTK+ で PostMessage をやりたい。
ようするに関数を抜けてからシグナルの処理をしたい。
g_signal_emit では関数がそこで止まってしまう。

g_idle_add を使って似たようなことはできるんだけど。
Gedit for Windows part3 | PaePoi
やはり正攻法でやりたいジャン。

gdk_event_put という関数を見つけた。
この引数に GdkEvent を渡せばイケるかも。

Gjs で書いていたけど GdkEvent がどうやっても作れない。
手段を知らないだけか実装されていないのかは不明。
ということで久々に PyGObject でやってみる。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0') 
from gi.repository import Gtk, Gdk

class EmitTest (Gtk.Window):
    """
        SendMessage, PostMessage
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        b1 = Gtk.Button(label="g_signal_emit")
        b2 = Gtk.Button(label="gdk_event_put")
        b1.connect("clicked", self.on_emit_clicked)
        b2.connect("clicked", self.on_put_clicked)
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
        vbox.pack_start(b1, False, False, 0)
        vbox.pack_start(b2, False, False, 0)
        self.add(vbox)
        self.show_all()

    def on_emit_clicked(self, button):
        ''' # output
            delete-event
            [g_signal_emit] Clicked
        '''
        self.emit("delete-event", None)
        print("[g_signal_emit] Clicked")

    def on_put_clicked(self, button):
        ''' # output
            [gdk_event_put] Clicked
            delete-event
        '''
        event = Gdk.Event.new(Gdk.EventType.DELETE)
        event.any.window = self.props.window
        event.put()
        print("[gdk_event_put] Clicked")

    def do_delete_event(self, event):
        print("delete-event")
        Gtk.main_quit()
        return True

EmitTest()
Gtk.main()

gdk_event_put ならハンドラを抜けた後に delete-event が発行される。
これなら PostMessage と同じように使えそうだ。
ただ本当は Gjs でやりたいんですけど。

Fedora 24 に入る Gjs なら同様に使えるのかな?
と楽しみにしていたら又一週間リリースが延びたようだ。
ま、いつものことか。

Video Cut Nautilus Script

デジカメ動画の編集に筆者は Avidemux を使っていた。
凝ったことはしないし残したい部分を切り張りできれば充分ということで。

しかし古い AMD から Skylake に環境を移したら何故か起動できなくなった。
未対応なのか?てか変に高機能にされると迷惑なだけなんだが。
しかたがないので代わりに ffmpeg コマンドを使う。

FFmpegで素早く正確に動画をカットする自分的ベストプラクティス – Qiita

うーん面倒だ。
やはりこういう編集作業は GUI でやったほうが楽に決まっている。

我が再生アプリに ffmpeg コマンドを送る機能の追加とか…
って同じことを考える人がいるもんだ。

Rosa Media Player 動画の切り取りやMP3の抽出が簡単にできる動画プレイヤー | Ubuntuアプリのいいところ

スクショを見ると編集は編集アプリで分けたほうがやはりよさそう。
そもそも再生が GStreamer で切り出しが ffmpeg って変なのでパス。
GStreamer でも当然編集はできるんだけど。

Fun with videomixer

GStreamer Editing Services 自体が PiTiVi の付属品でありまして。
だったら PiTiVi を使えばいいじゃん、ですよね。

ges

でも PiTiVi じゃ大袈裟なんだよなぁ。
Hello World に Visual Studio や Anjuta を使うくらいアホ臭い。

ということで。
Nautilus Script として使える超簡易な GUI カットアプリを作ってみた。

#!/usr/bin/gjs

// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-

const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const System = imports.system;

const NumEntry = new Lang.Class({
    Name: 'NumEntry',
    Extends: Gtk.Entry,

    _init: function() {
        this.parent({
            xalign: 1.0
        });
        let buf = this.get_buffer();
        buf.connect("inserted-text", Lang.bind(this, function(buf, position, chars, n_chars) {
            if (isNaN(chars))
                buf.delete_text(position, n_chars);
        }));
    }
});

const FFCut = new Lang.Class({
    Name: 'FFCut',
    Extends: Gtk.ApplicationWindow,

    _init: function(app, basename) {
        this.parent({
            application: app,
            title: basename
        });
        // Grid
        let texts = ["Start", ":", "Stop", ":"];
        let labels = [];
        this.entries = [];
        for (let i=0; i<4; i++) {
            labels[i] = new Gtk.Label({label: texts[i]});
            this.entries[i] = new NumEntry();
        }
        let grid = new Gtk.Grid();
        grid.attach(labels[0], 0, 0, 1, 1);
        grid.attach(labels[1], 2, 0, 1, 1);
        grid.attach(labels[2], 0, 1, 1, 1);
        grid.attach(labels[3], 2, 1, 1, 1);
        grid.attach(this.entries[0], 1, 0, 1, 1);
        grid.attach(this.entries[1], 3, 0, 1, 1);
        grid.attach(this.entries[2], 1, 1, 1, 1);
        grid.attach(this.entries[3], 3, 1, 1, 1);
        // Button
        let button = new Gtk.Button({label: "Cut"});
        button.connect("clicked", Lang.bind(this, function() {
            let ss1 = Number(this.entries[0].get_text()) * 60 + Number(this.entries[1].get_text());
            let ss2 = Number(this.entries[2].get_text()) * 60 + Number(this.entries[3].get_text()) - ss1;
            let cmd = "ffmpeg -ss " + ss1 + " -i " + this.title + " -t " + ss2 + " -vcodec copy -acodec copy out_" + this.title;
            GLib.spawn_command_line_async(cmd);
        }));
        // Pack
        let vbox = new Gtk.Box({
            orientation: Gtk.Orientation.VERTICAL,
            spacing: 5
        });
        vbox.pack_start(grid, true, true, 0);
        vbox.pack_start(button, true, true, 0);
        this.add(vbox);
        this.show_all();
    }
});

const FFApp = new Lang.Class({
    Name: 'FFApp',
    Extends: Gtk.Application,

    _init: function() {
        this.parent({
            application_id: 'org.sasakima.ffcut',
            flags: Gio.ApplicationFlags.HANDLES_OPEN
        });
    },
    vfunc_open: function(files, hint) {
        let basename = files[0].get_basename();
        let w = new FFCut(this, basename);
    },
    vfunc_activate: function() {
        print("Usage: ffcut FILENAME");
    }
});

let argv = [System.programInvocationName];
ARGV.forEach(function(element) {
    if (element.indexOf("//") == -1) {
        argv.push(decodeURIComponent(escape(element)));
    } else {
        argv.push(element);
    }
});
let application = new FFApp();
application.run(argv);

ffcut

コレに ffcut という名前で +x 属性を付けて
~/.local/share/nautilus/scripts に突っ込んで動画ファイルを送る。
切り出し開始と終了時間を入力して [Cut] ボタン。
すると [out_ファイル名] のカットされたファイルが同一ディレクトリに作られる。
~/bin に入れてコマンドでも多分使える。

Gjs は拡張子を付けないと Gedit で色分けしてくれないのでモードラインを入れた。
GNOME さん、そこは見分けてくださいよ。

もう少し改良の余地があるけど私的にはコレで充分だ。
気が向いたらもう少し弄ってアプリとして公開、しないと思うけど。

プログラミング初心者はこんなのから初めたらいいと思う。

Clutter Box and Scroll

Clutter をチマチマやっているけど絶対値配置はやはり古い!
やはり BoxLayout で配置したい、スクロール機能も欲しい。

色々試して驚いた。
なんと Clutter はスクロールバーに相当するものが無い!

どうしても使いたいなら自分で作れってことでしょうか。
いや違う、そもそも Button Widget 相当すら無いではないか。
スマートフォンではいらないよね、そういうこと。

古臭い考え方をバッサリ捨てないと今の Mac と GNOME は使えない。
つか昔風に戻るなんてありえない、パソコン離れは加速する一方だし。

もしかしてスマートフォンのようなスクロールを想定しているのかも。
だったらやったろうジャン!

#!/usr/bin/gjs

const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

const ListTest = new Lang.Class({
    Name: 'ListTest',
    Extends: Clutter.Stage,

    _init: function() {
        this.parent();
        let layout = new Clutter.BoxLayout({
            orientation: Clutter.Orientation.VERTICAL,
            spacing: 2
        });
        // ScrollActor
        this.scroll = new Clutter.ScrollActor({
            layout_manager: layout,
            scroll_mode: Clutter.ScrollMode.VERTICALLY,
            x_expand: true
        });
        // append
        for (let i=0; i<100; i++) {
            let m = new Clutter.Text({
                text: "TextLine: " + i,
                x_expand: true
            });
            m.set_background_color(Clutter.Color.new(255, 0, 0, 125));
            this.scroll.add_child(m);
        }
        // Scroll Action
        this.x_point = 0;
        this.y_point = 0;
        this.x_diff = 0;
        this.y_diff = 0;
        let gesture = new Clutter.GestureAction();
        gesture.connect("gesture-begin", Lang.bind(this, function(action, actor) {
            this.x_point = action.get_press_coords(0)[0] + this.x_diff;
            this.y_point = action.get_press_coords(0)[1] + this.y_diff;
            return true;
        }));
        gesture.connect("gesture-progress", Lang.bind(this, function(action, actor) {
            let x = action.get_motion_coords(0)[0];
            let y = action.get_motion_coords(0)[1];
            this.x_diff = this.x_point - x;
            this.y_diff = this.y_point - y
            let point = new Clutter.Point({
                x: this.x_diff,
                y: this.y_diff
            });
            this.scroll.scroll_to_point(point);
            return true;
        }));
        this.scroll.add_action(gesture);
        this.scroll.set_reactive(true);
        // this
        this.add_child(this.scroll);
        this.set_layout_manager(new Clutter.BoxLayout()); // Child Fill
        this.connect("hide", Clutter.main_quit);
        this.show_all();
    }
});

Clutter.init(null);
new ListTest();
Clutter.main();

scroll_actor

ClutterBoxLayout を使うことで GtkBox 相当のようだ。
これで fill, expand を利用したレイアウトができる。
しかし ClutterActor に割り当てなのか、GTK+ と随分違うなと。

子 Actor を親サイズに広げたい時は Child Fill の部分のように。
これだけで GtkWindow を使うのとと同じ感覚になる。

スクロールは上記で上手くいった。
スマートフォンみたいにマウスで掴んで動かした分だけスクロール。
やろうと思えば iPhone のような慣性やポヨンを入れることもできる。
でもあの動きは特許だったような…

このスクロールをパソコンで使うかというと疑問もあるけれど。
コマンドが優秀な Linux もタブレットの時代が、ってワカンネーけど。
GNOME プロジェクトはガッツリ備えているということでしょう。