WebM binary

意表を突いて Y901x を更新しました。
PyGtk のままだよ、当然 GTK2 だよ、もう古いよ過去の異物だよ。
とはいえ Google Chrome なんかも GTK2 だったりするのだが。

とりあえず再生速度変更の方法を何故か見つけたのでやってみようと。
Basic tutorial 13: Playback speed – GStreamer SDK documentation – GStreamer SDK documentation

一番目引数に 1.0 をデフォルト値に上下した float 値を入れた seek_event を作る、それを playbin2 に投げただけでアッサリ。
ただ再生停止したりファイルを切り替えするとリセットされて困った。
GST_MESSAGE_STATE_CHANGED で都度投げる方法でなんとかした。
こんなんで大丈夫かな…

ボタンを付けたかったけどスペースが無いのよね。
VLC とかみたく小さくしたくてもできないウインドウでは嫌だもの。

それと気になっていたけど放置していたところをまとめて。
Linux アプリ作りは本当にイイなぁ。
どうせ自分しか使っていないだろうから好き勝手にできるし。

VLC と違って音程は過去の遺物である Y901 同様変化する。
つか私は変化したほうが自然だと思うんだけど。
ま、これで YouTube から拾ったけど早すぎてどうやっているのかが全然解らなかったバイクのスゴテク動画をスローでじっくり検証できるようになったぞと。
倍速側なんてオマケだ、どんな場合の時に使うかワカラン。

しかーし

YouTube は最近 Flash, MPEG-4 AVC から HTML5, WebM になったのね。
これはキャッシュからコピーするスクリプトを作り替えしなければ。
というわけで今まで使っていた Nautilus スクリプトを改造した。

のだが…

YouTube の動画はいつのまにかキャッシュに残らなくなっている。
検索してゲゲッ、最近拾ってなかったので気がつかなかった…
FLASH のままな Opera キャッシュでも拾えない、お手上げだ!
あきらめて拡張を使おう、個人製作のバイク動画くらい拾わせてくれよ。

使えないけどせっかくやったので Python 覚書。

ちなみに Fedora 17 でファイルの拡張子が無い場合は
/usr/share/magic (/usr/share/misc/magic へのリンク)
の指定で見分けている、一応拡張子優先であるが。

とにかく /usr/share/magic を Gedit で開いてみる。
「エンコードが不明!」とか出るけど無視して「強制的に編集する」ボタンをば。
Ctrl+F で webm と打ち込み検索する、強制編集状態でも探せるよ。

WebM って Matroska のサブセットなんだ、今頃知った。
てか日本ではネクラでキモチワルイ奴しか今まで縁がなかったでしょコレ。
ftypwebm なんて指定で MP4 じゃダメだったのかな?

Linux の場合リポジトリからまとめてコーダーとデコーダー(あえてコーデックとは書かない)を入れられるからあんまり気にしないのよね。
MOV, RM, WebM なんかも普通に Nautilus でサムネイルできるし。
私の知る限り GStreamer で再生できないのは WMV3 だけだ。

それはどうでもよくて。

0x4282 が含まれている否かで通常 Matroska と見分けているみたい。
ま、実質先頭バイナリ4つだけ見れば動画であることは解るわな。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

TEST_FILE = "test.webm"
WEBM = "\x1a\x45\xdf\xa3"

for a in WEBM:
    print ord(a),

print "\n-----"

o = open(TEST_FILE, "rb")
bin_array = o.read(4)
for a in bin_array:
    print ord(a),
o.close()

print "\n-----"

print bin_array == WEBM

この方法で拡張子が無くても先頭バイナリで判別が可能になる。
使い道は無かったけど、きっといつかは勉強して良かったになるはず!

実は Gio を使ったほうが簡単なんだけどね。
拡張子を取っ払ってこんなコードを試せば解るよ。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from gi.repository import Gio

# Create GLocalFile
# Remove File Extenshon
f = Gio.file_new_for_path("test")
# Create GFileInfo
info = f.query_info(
    Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
    Gio.FileQueryInfoFlags.NONE,
    None )

print info.get_content_type() == "video/webm"

実は Python コードを書くのも久々だったり。
とにかく半年以上間が開いたけどアプリの更新。
年金を貰える歳まで絶対に生き残ってやる!

Google Map and My Tracks

なんか Google Map で GPS 軌跡情報を表示できると今頃知った。
バイク関連の Blog ではよく Google Earth のスクリーンショットでツーリングルートを表示とかやっているけど Web でできるならコッチのほうが便利だ。
バイク Blog に鞍替えする気は無いけど何かやりたいぞ。

というのも Earth を Fedora 17 にインストールしたが起動できん!
日本語では古い情報しか見つからず役に立たない、メリケンで検索!

E-Wadda’s Blog: How to install Google Earth on Fedora 17 64-bit

redhat-lsb って何?

redhat-lsb

ディストリビューション間での互換パッケージセットって嫌な予感しかない。
試しで yum コマンドを打ってみたら古いバージョンらしきパッケージがズラッと。
やっぱりそうなるよな、現行のパッケージと住み分けられんのか。

ヤメた、Google Earth は必要ならばミニノートの Windows 7 で使おう。
一応 Fedora 用の rpm は存在するよと、私は削除したけど。
Google Earth

そういえば以前は Windows アプリを Linux で使うとか WindowsForm でクロスプラットホームとか頭がおかしいブログ主がイッパイいたけどさすがに減ったな。
デスクトップはフル HD で Linux、んでミニノートの Windows を持つのが最強。
大型バイクと原付二種の二台持ちみたいなもんだ。

********************

ということで実験。
昨日近からず遠からずな約 100Km 離れた油坂峠まで行ってきた。

行きは川沿いののどかな景色と風を堪能しつつモバイル Google Map と GPS を便りにブラブラ寄り道しながら。
やっぱりバイクとスマートフォンの組み合わせは最強だ。

しかし車間距離を多めにとってノンビリ走っていると面白いように抜かれる。
いや、早くないので有名な CBR250R とはいえ流石にアンタの軽よりは早いんだが…
とか少し思ったりするけど笑っていられるのは多分歳のせい。

峠を攻め…なんて危険なコトはせず、慎重にマージンをたっぷりつけて。
つかココって思っていたより道が荒くて狭かったし。

帰りに My Tracks アプリで記録開始。
トンネルでどうなるか見たいので峠を避けバイパス側を通ることにする。
結構混んでいたけど約二時間ノンストップで家まで Go!
住居を晒してもしょーがないからゴールは免許を取った江南自動車学校前に。

記録データを My Tracks から KML で書き出し。
SD カード経由でパソコンにコピー。
このスマホ(SO-02D)は内部ストレージが /mnt/sdcard で SD カードが /mnt/usbdisk って最初戸惑ったわい。

Windows の Google Earth に KML を読み込んでみたのが上記。
あんなにウネウネしているのにこう見ると意外にまっすぐなんだな。
航空写真もいいけどマップみたく「地図」表示にできないのかな。
拡大するとトンネルはやはりショートカットされとる、なるほど。

さて Fedora 上の Google Chrome で Google Map を開く。
「マイプレイス」→「地図を作成」→「インポート」
とリンクを辿りローカルの KML ファイルを指定。
見事 Map に書き出されっっっっっって、アレ?

四分割されちゃった、三十分区切りってことなのか?

航空写真にして拡大すると、こりゃ記録間隔が細かすぎだということか。
google map kml 分割 なんてワードで検索したらワラワラ出てくるし。
KML の XML を直接読むと約一秒毎で記録しとるみたい、無駄すぎ。

今度は My Tracks の時間間隔や距離間隔設定を少し広げて試してみよう。
近距離なら細かいほうがいいけど長距離ツーなら大雑把で充分だし。
Google Earth を使うなら別に問題無いとはいえ時代はクラウドだよ NE!

Gedit C lang

プログラミングへの意欲がすっかり無くなってきた君達(俺のこと…
ここいらで基本の基本をやり直ししたいところだ。

ということで gcc による C 言語コンパイルの基本を。
コンパイラやヘッダ類は導入済みという前提で。

Gedit を利用します。
プラグインの「コードスニペット」を有効にします。
プラグインの「外部ツール」を有効にします。

Manage External Tools… を開き以下を登録します。

#!/bin/sh
gcc $GEDIT_CURRENT_DOCUMENT_NAME

準備はコレだけです。

test.c という名前で空のファイルを作成し Gedit で開きます。
Inc と打ち込んでキーボードの Tab キーを叩きます、i だけ大文字。

上記のようなテキストが流し込まれたはず。
inc と i を小文字にすると自作ヘッダ用のダブルコーテーションになる。
Delphi(pascal) 屋の人は「それインクリメントじゃないの?」と勘違いしない。

後はお約束の stdio と打ち込み Tab キーで下方にカーソルが移動する。
スタンダード In/Out ヘッダと通ぶらずとも「スタジオえっち」で誰にでも通…(以下略
これで printf 関数が使えるようになる。

Enter キーで一段下げて main と打ち込み再び Tab キー。
main 関数が流し込まれ関数内にカーソルが移動するので printf() を書く。

コンパイルは最初に作成した外部ツールを実行するだけ。
Gedit は実はこんなに凄い!

、、、、、、、、、、

では Gedit の宣伝なので分割コンパイル方法も少し。
extern 宣言を使う方法もあるけど事実上ヘッダを利用する人しかいない。

cbr.h cbr.c という2つのファイルを同一ディレクトリに作成。

cbr.h

#include <stdio.h>

void
print_cbr(void);

stdio.h をインクルードし、関数プロトタイプのみを書く。

cbr.c

#include "cbr.h"

void
print_cbr(void)
{
    printf("でも CBR250R 買ってしまったし...\n");
}

cbr.h をインクルードし、プロトタイプの実体を作成する。

test.c も書き換え。

#include "cbr.h"

int
main (int argc, char *argv[])
{
    printf("新型 Ninja250 カッケェ!\n");
    print_cbr();
    return 0;
}

stdio.h は cbr.h で宣言されているので書く必要は無い。
プロトタイプがヘッダで宣言されているので print_cbr 関数が使える。

先ほどの外部ツールは残念ながら使えない。
$GEDIT_DOCUMENTS_PATH を使えば複数ファイルのリンクもできるけど *.c のみを全部開いている状態をビルド時に作る必要があるので逆に面倒くさい。
普通に Makefile を作って Ctrl+F8 のほうがいい。

Makefile

ninja: test.c cbr.c
	gcc -o ninja test.c cbr.c

cbr.tar.gz

以上 Gedit はこんなに凄い、ってだからぁ…
すっかり月一更新臭くなっているこのブログ、なんとかせねば。

ApplicationMenu

プログラミング関係は次回!
と書いてから一ヶ月も放置してしまった…

とはいえ何もやっていなかったわけではなく
GNOME 3.4 リリースノート
の「アプリケーションメニュー」を PyGI でやろうと四苦八苦していた。

なんか Linux も Windows もメニューバーを無くそうと試行錯誤しているね。
そりゃまあキーボードとマウスからタッチパネルに絶賛変革中だからだろうけど。
Windows がリボンを作った時はナンジャコリャだったけど先を見ていたと今なら解る。

C のサンプルコードは公式の以下にあるのだが
GtkApplication
GtkApplicationWindow
GActionMap

GtkActionEntry はシーケンス(つまりリスト)でよかったが
GActionEntry は上手く行かなかった。
こんな感じでイケると思ったけどシーケンスでは Gio.ActionEntry ではないと例外になる。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from gi.repository import Gtk, Gio

menu_xml = """
<interface>
    <menu id='app-menu'>
        <section>
            <item>
                <attribute name='label' translatable='yes'>_MessageBox</attribute>
                <attribute name='action'>app.messagebox</attribute>
                <attribute name='accel'>&lt;Primary&gt;m</attribute>
            </item>
            <item>
                <attribute name='label' translatable='yes'>_Quit</attribute>
                <attribute name='action'>app.quit</attribute>
                <attribute name='accel'>&lt;Primary&gt;q</attribute>
            </item>
        </section>
    </menu>
</interface>"""

class Win(Gtk.ApplicationWindow):
    def __init__(self, app):
        Gtk.Window.__init__(self)
        self.set_application(app)
        self.show_all()

def on_messagebox(action, parameter, user_data):
    dlg = Gtk.MessageDialog(
            None,
            Gtk.DialogFlags.MODAL,
            Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK,
            "text")
    r = dlg.run()  
    dlg.destroy()
    return r

def on_quit(action, parameter, user_data):
    user_data.quit()

class App(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self,
            application_id="apps.test.appmenu",
            flags=Gio.ApplicationFlags.FLAGS_NONE)
        self.connect("startup", self.on_startup)
        self.connect("activate", self.on_activate)

    def on_startup(self, data=None):
        try:
            # GActionEntry [] a Gio.ActionEntry
            aes = [ ("messagebox", on_messagebox, None, None, None),
                    ("quit", on_quit, None, None, None) ]
            ###
            self.add_action_entries(aes, len(aes), self)
            #=> Expected Gio.ActionEntry, but got StructMeta
            ###
            builder = Gtk.Builder()
            builder.add_from_string(menu_xml)
            menubar = builder.get_object("app-menu")
            self.set_app_menu(menubar)
        except Exception, e:
            print e
            self.quit()

    def on_activate(self, data=None):
        w = Win(app)

if __name__ == "__main__":
    app = App()
    app.run(None)

全部 const 指定だしスタック上のデータでないと駄目なのかな?
それだとヒープ上にしか変数を作れない動的言語はお手上げになるんだけど。

海外を探しても PyGI のコードはほとんど見つからない。
現状ではみんな試行錯誤して様子見しているかブン投げているかだろうな。
はたしてこの動的バインディングは熟成して普及するのであろうか?

ええい、今回もとりあえず C 言語でコンパイルだけやってみるか。

Fedora は初期状態では gcc すら入っていない。
gcc, gtk3-devel, gtk3-devel-docs でとりあえず環境は揃う。
ついでに anjuta を導入、vala なんかもオマケで入る。
これらについては気が向いたら何か書く。

c_appmenu.tar.gz

うん、C ならやはり普通にアプリケーションメニューは使える。
それなら DLL にすれば、って動的言語な意味ネェ…
C が一部でも必要ならソースコードのみで配れる C で全部作ったほうが楽。
Python と DLL では最低 x86, x86_64 用の2つを配るはめになるわけで。

ということで当面は C 言語とお付き合いになりそうです。
難しくはないんだけど、ただただ面倒くさいのが難点。

org.gnome.shell.overrides

GNOME Shell について今頃知った。
gsettings コマンドを使ってもいいけど dconf-editor のほうが簡単。

org.gnome.shell.overrides

を開いて

attach-modal-dialogs
を false にすると「情報」等のモーダルダイアログがタイトルバーからニョキッと出るのが普通のダイアログになる。

button-layout
:minimize,maximize,close と書けば Windows と同じボタン配列に。
コロン ‘:’ より左に書けば Ubuntu のような左寄せにもできる。

dinamic-workspaces
を false にすると動的ではない昔ながらな4つのワークスペースに。

edge-tiling
を false にするとタイトルバーを掴んで画面上部に持っていくと最大化するあのムカつく動作を行わず GNOME2 同様なスナップになる。

workspaces-only-on-primary
は多分マルチモニタでなければ関係ない。

デフォルトに戻したい場合は右下ボタンで一発。
いやいや、やはりタイトルバーを掴んでの移動はスナップのほうが使いやすい。