py-hyperestraier-python その2
posted by jun-g at 土, 07 4月 2007 00:11 JST
posted by jun-g at 土, 07 4月 2007 00:11 JST
posted by jun-g at 木, 05 4月 2007 23:55 JST
SWIG版のPython用HyperEstraierライブラリはノードAPIを含まないので、lirisさん作のPurePythonHyperEstraierライブラリを使(ってもら)うことにした。ソースを見るとSWIG版とインターフェースがそっくりだったので、移行は超簡単やった(らしい)。使っているうちに何箇所かバグを発見した(とのことな)ので、パッチを作ってlirisさんに送って取り込んでもらった。
微妙に伝聞調?なのは、実際にライブラリを使ったのとバグを発見したのは僕ではないから。人の手柄を横取り…したわけではないのであしからず…。
それから、FreeBSD用のportsを作ってsend-prしておいた。SWIG版のライブラリとport名がかぶってしまうので、PKGNAMESUFFIXに「-python」って付けてみた。commit待ち。
posted by jun-g at 火, 03 4月 2007 23:44 JST
DevCamp後に行った動画アップロードの作業手順を忘れないようにメモ。
まずはDVテープからPCへデータを吸い出す。PCとDVカメラをIEEE1394ケーブルで接続。アプリはgdvrecv (multimedia/gdvrecv)を使用する。吸い出したデータはrawDVフォーマットで保存され、80分テープで約15GB程度のファイルになる。
次にエンコード。アプリはtranscode (multimedia/transcode)を使用。エンコード形式は映像をxvid4、音声をmp3にした。エンコードに使用したコマンドラインオプションは以下の通り。
$ transcode transcode -a 0 -x dv -i [変換元DVファイル名] -g 720x480 -w 500,250,100 -b 128,0,0 -V -f 29.97 -y xvid4 -o [変換先ファイル名] -Z 640x480
エンコードにかかる時間はCore2Duo T7200 + 2GBメモリのマシンで動画実時間の倍ぐらい。出来上がるファイルは約300MB程度。内容によっては結構なブロックノイズが出ていたので、もしかしたら圧縮しすぎたかも。
最後はGoogleVideoにアップロード。GoogleVideoのサイトで配布されているDesktopUploaderのLinux用を使用する。といってもJavaで書かれているのでJDKさえインストールしておけばエミュレーションじゃなくてネイティブで動く。サイトから「GoogleVideoUploader.jar」をダウンロードしたら、
$ java -cp ./GoogleVideoUploader.jar com.google.uploader.Uploader
でアップローダー起動。後はアップローダー上でログインしてファイルを選択してアップロードを実行。アップロードが完了したら、サイト上で動画ファイルの説明等を入力してprocessing作業開始。そこから大体24時間程度経過してようやく公開、となる。
ちなみに一番の鬼門はアップロード作業やった。何度ログインしても拒否されたり、アップロード途中でHTTPのエラーが出て失敗したり、リストから消えたのに実はアップロードに失敗していたり、processingの結果、勝手に尺を短くされたり…。
posted by jun-g at 火, 03 4月 2007 02:16 JST
ここんとこずーっと悩んでて解決方法がわからんのでブログで晒してみる。
pythonでMochiKit.DOMのcreateDOMみたいのがあったら便利かなと思って下記のようなクラスを書いた。
class Tag:
"""A base class of HTML tag."""
name = None
inline = True
container = False
def __init__(self, *nodes, **attributes):
self.nodes = nodes
self.attributes = attributes
def __str__(self):
return self.serialize()
def serialize(self):
text = ""
for node in self.nodes:
if isinstance(node, Tag):
text += node.serialize()
if not node.inline:
text += "\n"
else:
text += node
tag = "<" + self.name
attrs = map("=".join, [(x[0], "\"%s\"" % (x[1])) for x in self.attributes.items()])
if len(attrs) > 0:
tag += " " + " ".join(attrs)
if text == "":
tag += " />"
if self.container:
tag += "\n"
else:
tag += ">"
if self.container:
tag += "\n"
tag += text + "</" + self.name + ">"
return tag
サニタイズとか全然してないけど、とりあえずなのであまり気にしない。こいつから各タグのサブクラスを作っておくと、
class DIV(Tag):
name = "div"
inline = False
container = True
class A(Tag):
name = "a"
inline = True
container = False
下記のように使える。
>>> a = A("DaemonFreaks.com", href="http://www.daemonfreaks.com/")
>>> div = DIV("僕のサイト: " , a, style="border: 1px solid #000000;")
>>> print div
<div style="border: 1px solid #000000;">
僕のサイト: <a href="http://www.daemonfreaks.com">DaemonFreaks.com</a>
</div>
でもって、タグを全部クラスとして定義するのもアレなので、クラスを動的に生成する関数を作った。
from new import classobj
def _get_class(name, inline, container):
name = name.lower()
cls = classobj(name.upper(),
{"name": name,
"inline": inline,
"container": container})
return cls
で、各タグの名前、inlineとcontainerの設定を用意しておけば準備完了。
# name: (inline, contaier)
TAGS = {
"html": (False, True),
"head": (False, True),
"body": (False, True),
(省略)
"div": (False, True),
"span": (True, False)
}
後は、import文が呼び出された際に、「import *」なら定義内容すべてのクラスを、タグが指定されたなら指定タグのクラスをグローバル空間に展開するようにしたい。つまり、モジュール「html」内にこれらのコードが書かれていたとして、
>>> from html import HEAD, BODY >>> dir() ['HEAD', 'BODY'] >>> from html import * >>> dir() ['HTML', 'HEAD', 'BODY', (省略), 'DIV', 'SPAN']
のように動作させたい。
しかし、同一モジュール内で__import__をオーバーロードしたりihookを使用してみたものの、どうも期待どおり動作しない。同一モジュール内にオーバーロードの処理を書くと、そのモジュールがimportされた後に__import__がオーバーロードされてしまう(当たり前か…)。なので、モジュール内で自分自身を再度インポートするように記述するとなんとなく上手く動いてるような感じにはなる。
importされるモジュール側でimportをhookして、指定されているクラス(orモジュール)名を取得する方法は無いものか…。
posted by jun-g at 月, 02 4月 2007 14:09 JST
メインのPCがようやく復旧した。NOTE PCの狭い画面とはこれでオサラバ。
やったこと。865PEのマザーボードを中古で買ってきて交換。OSの入ったHDDはそのまま使用。/homeはSATA120GB*2のRAID0アレイ上に新しく構築。でもってmake worldしてからアプリも全部入れ直した。あとはバックアップHDDから必要なファイルを取り出すのみ。
あと、最近shellをbashからzshに乗り換えたので、漢のzsh(MYCOM)を参考に.zshrcを編集した。プロンプトはbashで設定していたものと同じにしたかったので、
local LIGHTGREEN=$'%{\e[1;32m%}'
local GREEN=$'%{\e[0;32m%}'
local YELLOW=$'%{\e[1;33m%}'
local BROWN=$'%{\e[0;33m%}'
local LIGHTBLUE=$'%{\e[1;34m%}'
local BLUE=$'%{\e[0;34m%}'
local WHITE=$'%{\e[1;37m%}'
local DEFAULT=$'%{\e[1;m%}'
PROMPT=$LIGHTGREEN'['$GREEN'%*'$LIGHTGREEN']'$YELLOW'['$BROWN'%~'$YELLOW']
$BLUE'%n'$WHITE'@'$LIGHTBLUE'%m'
$WHITE%(!.#.$) '$DEFAULT
setopt PROMPT_SUBST
のようにした。これは
[12:00:00][/path/to/curdir] jun-g@hostname $
のように表示される。右プロンプトは馴染めないので使わない…。後は補完とエイリアスの設定をちらほらとしてとりあえず完了。