え~、今日のお題は「未来時計」です。PCでテレビの録画をしているとPCの時計(結構狂う)あわせが気になります。わたしはメインの録画ソフトはWindows XP MCEのメディアセンターを元にしています。っていうか、メディアセンターの録画開始を別のプロセスで監視して、録画開始を検出したら、Hauppauge HD-PVRで録画開始(チューナーの制御はメディアセンター任せ)という、「ドン臭いこと」をしています。
メディアセンターでは、単独の録画に関して、数分前に録画開始、数分後に停止というような設定ができるのですが、ある録画の終了と次の録画の開始が同じ、つまり2つの録画が連続している場合には、あとの録画の3秒くらい前にチューナーの制御と録画の切り替えをします。結果としてHD-PVRでの録画は頭が1~2秒程度切れてしまうことがあります。気にしなければいいのですが、ちょっとねぇ・・・多くの録画用ソフトも本質的には同じ問題があると思うのですが、皆さんどうしてるのでしょう?
インターネットを利用したPCの時計あわせとしては、NTPとかあって、「桜時計」とかが有名でしたし、net time コマンドでも時計合わせできますが、正確な時刻にPCの時計を合わせてしまいます。こんなページもありますね。
わたしがやりたいのは、要は、「PCの時計を本来の時間より30秒程度進めておく」ことです。何年も前に考えたことがあるのですが、
案(1)
NTPのクライアントなりサーバーソフトを、いじってウソの時間をPCに設定する→linuxならntpdのソースコードもあるけどWindowsでは・・・NTPってUDP使ってるらしいし、soketを使ったプログラミングなんてわかんないし、で挫折
案(2)
録画ソフトがシステムの時刻を参照する際のWindowsへのシステムコールをトラップして、ウソ(30秒くらい先の)の時間を返す。リバースエンジニアリングのページに非常に参考になることが書かれていますが、あまりに面倒くさそうで挫折。
でも、よく考えたら、秒単位での正確さを求めなければ、「ネットワーク内の別のPCにログインして、time /Tとかdate +%H:%M:%Sを実行して、返ってきた時刻に30秒足して、PCの時計をセットすりゃいい」と気づきました。TeraTermのマクロとかつかえばなんとかなりそう!なんて、思って、ツールの名前も「未来時計」に決定です(うぉ~っ、なんかやる気でてきたぞっ)。
Teratermのマクロと小一時間格闘した結果を最後に張っておきます。これでWindowsからUbuntuにログインして時刻を取得、30秒WindowsのPCの時計を進めてセットできます。予約録画に悪影響しないように、ハンパな時間にセットすることを念頭に毎時17分にセットするようにしています。
でも、もう一度インターネットをしらべてみたら、adrasteiaが見つかりました。これでやりたいことはできてますね。 orz
;
; FutureClock for Teraterm macro
;
; (c) 2008-09 BO
show 0 ; *** minimize window
HostName='xxxx'
Username='xxxxxxx'
Password='xxxxxxxxx'
sprintf '%s@%s:' Username HostName
Prompt=inputstr
timeout=5
while 1
; *** making up params for 'connect' command
connectParam=HostName
strconcat connectParam ':22 /2 /ssh /KR=UTF8 /KT=UTF8 /auth=password '
strconcat connectParam ' /user='
strconcat connectParam Username
strconcat connectParam ' /passwd='
strconcat connectParam Password
strconcat connectParam ' /V /timeout=5'
; *** open Tera Term and connect to the host
connect connectParam
if result=2 then
wait Prompt
sendln 'date +%H:%M:%S'
recvln
waitregex '([0-9]*):([0-9]*):([0-9]*)'
str2int hh groupmatchstr1
str2int mm groupmatchstr2
str2int ss groupmatchstr3
sendln 'exit'
if mm=17 then
ss=ss+30
if ss>=60 then
mm=mm+ss/60
ss=ss%60
endif
if mm>=60 then
hh=hh+mm/60
mm=mm%60
endif
sprintf "%d:%d:%d" hh mm ss
; messagebox inputstr 'new time'
settime inputstr
interval=60*60
else
interval=(17-mm)*60-ss
if interval<=0 interval=interval+60*60
endif
else
interval=60*60
endif
pause interval
endwhile