TrackMeのWebインターフェイスを日本語化、バグ修正

EMONSTER等のGPS内蔵WindowMobile端末向けにTrackMeというアプリケーションがあります。端末内でGPSログを保存することはもちろん、リアルタイムでサーバーに位置情報を送信することもできます。このサーバー用のPHPスクリプトも上記ページで公開されており、自前のサーバーで運用することもできます。自動リロードで常に端末の現在位置をGoogleMapsで表示するモードなどもあり、サイバーです。バックエンドにMySQLを利用しており、テーブル構成などをのぞけば、色々と応用が広がりそうです。

■日本語ランゲージ定義の追加

で、そのスクリプトによるWeb画面はマルチランゲージ対応されているのですが、残念ながら日本語の設定はありません。中を覗いてみたところ、定義ルーチンが独立していて簡単に追加できそうだったのでサクっと作業してみました。下記の2ファイルを更新すれば使えるようになると思います。

一応、開発者の人に送ってみるつもりですが、自前でパッチ当てしたい人向けに貼っておきます。

index.php (818行目辺りに赤字部分を追加)

$html .= "                        <select name=\"language\">\n";
$html .= "                            <option value=\"english\""; if($language == "english") { $html .= " SELECTED"; } $html .= ">English</option>\n";
$html .= "                            <option value=\"italian\""; if($language == "italian") { $html .= " SELECTED"; } $html .= ">Italian</option>\n"; //trackmeIT
$html .= "                            <option value=\"german\""; if($language == "german") { $html .= " SELECTED"; } $html .= ">German</option>\n";
$html .= "                            <option value=\"spanish\""; if($language == "spanish") { $html .= "SELECTED"; } $html .= ">Spanish</option>\n";
$html .= "                            <option value=\"french\""; if($language == "french") { $html .= "SELECTED"; } $html .= ">French</option>\n";
$html .= "                            <option value=\"dutch\""; if($language == "dutch") { $html .= "SELECTED"; } $html .= ">Dutch</option>\n";
$html .= "                            <option value=\"japanese\""; if($language == "japanese") { $html .= "SELECTED"; } $html .= ">Japanese</option>\n";
$html .= "                        </select>$display_language_text<br>\n";
$html .= "                        <select name=\"units\">\n";
$html .= "                            <option value=\"imperial\""; if($units == "imperial") { $html .= " SELECTED"; } $html .= ">Imperial</option>\n";
$html .= "                            <option value=\"metric\""; if($units == "metric") { $html .= " SELECTED"; } $html .= ">Metric</option>\n";
$html .= "                        </select> $display_units_text<br>\n";

language.php (356行目辺りに赤字部分を追加)

(↑ 他の言語定義が並んでいる部分 Italian Language Data)
       $speed_metric_unit_balloon_text      = "km/h";
       $distance_metric_unit_balloon_text   = "chilometri";
       $height_metric_unit_balloon_text     = "metri"; 
     }
   elseif($language == "japanese")
    {
        $title_text                          = "TrackMe Display";
        $trip_button_text                    = "軌跡表示";
        $location_button_text                = "リアルタイム更新ON";
        $location_button_text_off            = "リアルタイム更新OFF";
        $filter_button_text                  = "更新";
        $filter_none_text                    = "全て表示";
        $filter_photo_comment_text           = "写真、コメント付きポイントのみ";
        $filter_photo_text                   = "写真付きポイントのみ";
        $filter_comment_text                 = "コメント付きポイントのみ";
 
       $filter_last_20                      = "最新20ポイントのみ";
        $filter_daterange                    = "日時範囲指定";
        $footer_text                         = "軌跡データ生成:";
        $incomplete_install_text             = "インストールが正しく終了しませんでした。ファイルinstall.php、database.sqlはまだTrackMeフォルダに存在します。これらを削除するまで地図表示は有効になりません。";
        $no_data_text                        = "DB内の1つ以上のTrackMe テーブルにデータがありませんY。Windows MobileデバイスでTrackMeアプリケーションを実行し、軌跡データを生成する必要があります。";
        $database_fail_text                  = "DBとの接続が切断され、表示が中断されました。";
        $trip_none_text                      = "なし";
        $trip_any_text                       = "全て";
        $display_options_title_text          = "表示オプション";
        $display_header_text                     = "ヘッダーを表示";
        $display_showbearing_text                = "方向矢印を表示";
        $display_crosshair_text              = "中心の十字マークを表示";
        $display_clickcenter_text            = "クリックした位置を中心にする";
        $display_overview_text               = "ミニマップを表示";
        $display_language_text               = "表示言語を選択";
        $display_units_text                  = "表示単位を選択";
        $display_button_text                 = "設定を保存"; 
        $startdate_text                                          = "開始:"; 
        $enddate_text                                            = "終了:"; 
        $trip_title                                                      = "Trip:"; 
        $filter_title                                            = "フィルタ:"; 
        $date_title                                                      = "日付:";
        $tripsummary_title                                       = "Trip 概要";
        $tripstatus_title                                        = "現在位置";
        $summary_time                                            = "トータル時間:";
        $summary_photos                                          = "写真数:";
        $summary_comments                                        = "コメント数:";
        // Public Display Information
        $user_button_text                    = "ユーザ切替";
        $showconfig_button_text                          = "設定";
&#
160;       $showconfig_button_text_off                      = "設定";
        // Private Display Information
        $page_private                                        = "ページの表示にはユーザ名とパスワードのよる認証が必要です。";//trackmeIT
        $trip_data                                                   = "ユーザ名:"; //trackmeIT
        $login_text                          = "ユーザ名";
        $password_text                       = "パスワード";
        $login_button_text                   = "ログイン"; 

        // Balloon Fields Information
        $user_balloon_text                   = "ユーザ";
        $trip_balloon_text                   = "Trip";
        $time_balloon_text                   = "時間";
        $speed_balloon_text                  = "速度";
        $altitude_balloon_text               = "高度";
        $total_time_balloon_text             = "累積時間";
        $avg_speed_balloon_text              = "平均速度";
        $total_distance_balloon_text         = "移動距離";
        $point_balloon_text                  = "ポイント";
        $comment_balloon_text                = "コメント";
        $speed_imperial_unit_balloon_text    = "mph";
        $distance_imperial_unit_balloon_text = "miles";
        $height_imperial_unit_balloon_text   = "feet";
        $speed_metric_unit_balloon_text      = "km/h";
        $distance_metric_unit_balloon_text   = "km";
        $height_metric_unit_balloon_text     = "m";
    }
    else
    {

(↓ 以降、デフォルトの英語表記のデータ Defaults English Data)

 

■ユーザ選択がリセットするバグの修正

リアルタイム表示のON/OFFをすると、ユーザ選択がリセットされてしま現象が出たので、場当たり的対応してみました。

index.php (305行目辺りの赤字部分を追加)

$html .= "                      function livetrack()\n";
$html .= "                      {\n";
$html .= "                              if(document.getElementById(\"last_location\").value == \"$location_button_text\")\n";
$html .= "                              {\n";
$html .= "                                      location=\"index.php?ID=$ID&last_location=yes\";\n";
//$html .= "                                            document.getElementById(\"last_location\").value = \"$location_button_text_off\";\n";
$html .= "                              }\n";
$html .= "                              else\n";
$html .= "                              {\n";
$html .= "                                      location=\"index.php?ID=$ID\";\n";
//$html .= "                                            document.getElementById(\"last_location\").value = \"$location_button_text\";\n";
$html .= "         &
#160;                    }\n";
$html .= "                      }\n";

CyberNavi用定額通信ユニットWS022IN到着

WS022IN

5月下旬予定から延びましたが、WILLCOMのCyberNavi専用定額データ通信ユニットWS022INが到着しました。

ウィルコムプラザに入荷日がわかったら連絡もらう約束してたのに音沙汰なし。2chで既に注文した人がいると聞き、ググったらWILLCOM STOREの注文ページを発見。二日で届きました。

\500~\1,500の従量プランが良いか\1,000の固定プランにするか基準が不明確で決めかねていたんですが、注文サイトに「月8時間程度までなら従量がお得」という目安が提示されていたので、迷わず定額。経理上楽な年額一括払いにしました。

端末価格も当初噂されていた\6,000程度から、期間限定割引で\3,980(事務手数料別)と割安感がある値段でゲット。SmartLoopを使っていて感じるメリットからすればコストパフォーマンスは良いと思います。

開封してみて驚いたのは、各所に出ていた写真から想像していたよりも随分小さい筐体だった点。ほとんどWSIMを基準にしているようなサイズですね。左上は比較用の去年もらったSmartLoopロゴ入りUSBメモリ。ちなみにWSIMのセット方法を記した説明書きは無し。機械が苦手な人は悩むかも知れません。実際には先端の黒いパーツを引っ張ると開くようになっています。

自宅駐車場では受信OK。実はこれを見越して今月から携帯電話の方のパケットパックを外してホワイトプランに変更してたんですが結局月の半分はそっちでパケット通信してしまいました。パケ代いくらになったかなぁ。ともあれ、これでそれを気にせずSmartLoopを最大更新頻度設定で使いまくれます。

ただ、新型ではアルバムジャケットを登録できない関係でCDからのダイレクト録音を使わなくなったので、CDDBのための接続は不要になってしまい、本当にSmartLook専用って感じですね。

実家のお風呂に防水ワンセグテレビ設置

実家の父親が半身浴かなにかをすると決意したらしく、風呂場でテレビを観られるようにしたい、と行ってきました。

で、7インチクラス/ワンセグで4万程度、10~12インチクラス/12セグで15万~20万コース、という見積もりを出したところ、前者でという返事。

購入したのはLogitecのLTV-1S700WPです。特徴としては、

  • 7インチ
  • ロッドアンテナの他に延長ケーブル付き小型アンテナ付属
  • バッテリーで3時間駆動
  • 壁掛け用ホルダー同梱

といったもの。他の家電メーカーの製品が3.5インチや4インチクラスなのを考えるとコストパフォーマンスは高め。実は同じ中身と思われるEVERGREENの機種だと更に\5,000ほど安いんですが、風呂場に黒モノはあわない気がして、Logitecの方を選びました。

実際つけてみたところ、ロッドアンテナは論外でしたが、ケーブル付きアンテナを窓の外に出してやったら意外とまともに受信しました。ダメだったらEXEMODEのリピータータイプのブースターを買おうと思ってましたが悩ましいところです。バッテリーを充電しに風呂場から脱衣所などに持って出る度にアンテナ線を付け外しすることを思えば、脱衣所にブースターを設置してロッドアンテナ受信する方が使い勝手は良いでしょう。ただ、脱衣所と隣接するダイニングにアンテナ線は来ておらず、リビングからとか2Fの部屋から外壁づたいにアンテナ線自体を引っ張ってこないとならず結構大がかり。また、ウチの家族のことだから、ブースターの電源とか入れっぱなしにするだろうしなぁ(消費電力スペックは約0.15A(DC12V)と蛍光灯以下ですが)。当面はブースターという選択肢は黙っておくかw。

7インチという画面サイズはワンセグの解像度からしたらやや大きすぎで、アラも目立ちますが、ケータイなどと比べ視聴距離は離れるし、眼鏡外してたりするので、やはり大きいに越したことはないかなという印象です。

実家に火災報知器取り付け

kasai

既存住宅も含めての寝室、階段への火災警報機取り付け義務化の猶予期限は自治体でまちまちですが、実家の愛知県田原市の場合、今年の5月31日までに差し迫っていたので、連休の帰省時に取り付けしてきました。

今回チョイスしたSH4400Pも含め、現在の主流はリチウム電池で10年稼働を謳う電源配線不要タイプ。ベースをネジ2本で固定し、本体に電池をセットしてはめ込むだけ、と場所決めの時間を除けば2、3分といったところです。実家は両親の二人暮らしですが、たまに妹が子供連れて泊まったり、こうしてσ(^^)が帰省したりするので、結局寝室は4カ所、そして階段と台所(台所は田原市の条例による義務)と6カ所も取り付けることになりました(ちなみに台所は煙感知タイプではなく、熱感知タイプをチョイス)。

苦労したのは取り付け自体よりも位置決め。物理的な煙(空気の不透明度)をイメージセンサーで感知するので、もし火災が発生した場合に煙が直接かぶりやすいところでなければなりません。例えば、暖房器具や仏壇、サーバーなどの火種になりやすいもの(たいてい壁際)の真上がヨサゲなんですが、壁からは数十cm離さなければならなかっったり、エアコンの吹き出し口からも遠ざけなければいけなかったり。また複数の火種がある部屋では真ん中辺りにつけたくなるんですが、そこには普通既に照明器具がいたりします(ペンダント型の照明器具の場合も煙避けになってしまうので離さなければならない)。実際、取り付け作業よりも場所決めに悩む時間の方が長かったですね。特に階段は、階下の火災で2階から逃げ遅れないようにすることが目的なので、煙の動きを慎重に脳内シミュレーションしつつ検討しました。

動作チェックと誤報解除用の紐スイッチもついてるんですが、表面のボタンで同様のことができるので、とりあえず裏面にぐるぐる巻きにして隠しておきました。家族から誤報が多いとクレームが来たら別途考えます。

また、SH4400Pはブザーではなく音声で「火事です」とか「電池切れです」と知らせるので、「どっかで音が鳴ってるけどなんだ?」なんてことにならなそうで良いかなと思いました。デザインとサイズはもうひと頑張り期待したいところです。

ちなみに自宅の横浜市は平成23年とまだかなり余裕があります。ウチは既に押し入れの中までついてたはずですが、いずれにせよ消防庁の広報不足は否めませんね。実際、σ(^^)もつい最近ヨドバシの特設コーナーを見るまで知りませんでした。現在は罰則規定もないですし、知らんぷりを決め込む人もいそう。法律というのは罰則を恐れて従うものではそもそもないワケですし、未然に火災が防げるかも知れないという意味では、火災保険でカバーするからいいや、という話でもない。工事費いらずでDYI数分で取り付けできるので、是非積極的に設置を進めて欲しいですね。

HTTPベースの動画ライブラリ、実家から検証

少し前のエントリで実現して、TeraStation上のDivX動画ライブラリを、Apache経由で公開する実験ですが、実家から検証してみました。

結論から言ってラクショーでした。光->光なら問題ありませんね。今までのVPN+SMBであれこれ苦労してたのがおポンチでした。SMBは応答速度が低いと極端にパフォーマンスが落ちるプロトコルであることを最近知りました。

■ADSL + 無線LAN + PS3でも割とイケる

あと、妹のアパートに貸し出してあるPS3/40GB(たまに帰省した時に使う様に折半で購入)でも試しました。妹宅はADSLでしかもLANは11gの無線ですが、予想外に健闘。1ファイル最後まで完走させたワケじゃないですが、試した限りでは1280x720pのファイルでも大丈夫そうでした。ただ逆に720×400でも途切れまくるのもあったり。ウチは品質保持エンコだから、瞬間レートが跳ね上がるようなのはツライのかも知れません。ただ、PS3のブラウザからファイルを選んですぐ再生できるし、BASIC認証のパスワードもちゃんと保存できるので、この方式用のVOD端末としてはかなり重宝すると思います。これでレジューム再生ができればいうことないんですけどね。

■PC上からもストリーミング再生したい(1) Opera + VLC編

こうなってくると、PS3だけでなくPCブラウザ上からもストリーミング再生したくなります。で、色々試行錯誤した結果、Opera + VLCという方法を発見しました。VLCは「URLで開く」メニューがある動画プレーヤーのうちで、唯一マトモに再生できました。DivXデコーダーも内蔵しているので、ネットカフェなどで使うにも便利。パスワード保存はできませんが、BASIC認証には対応しています。

で、Operaの方でMIMEタイプがvideo/x-msvideoなストリームに対して、VLCを使うよう設定します。この時、唯一Operaだけが、URLのまま渡すことが可能なようで、IEやFireFoxだと、一度ローカルに保存してからVLCで開く、という動作にしかなりませんでした。

ともあれ、Opera + VLCで正しく設定すれば、Operaで一覧を表示して、目的の動画をクリックしたら自動でVLCが起動して(IDとパスワードを改めて入力しなきゃいけないけど)ストリーミング再生開始、という流れを実現できました。

ただ、VLCにはタイムスライダーがないので、途中を飛ばして観られないのが難点です。あと、(1)、(2)共通の問題ですが、2GBを超えるファイルは扱えないようです。まぁ、そんなサイズをストリーミングすんな、って話ですな。

■PC上からもストリーミング再生したい(2) DivX Web Player編

DivXのストリーミングといえば、普通にDivX Web Playerプラグインがあります。実は当然これも最初に試しました。Apache側で.aviの拡張子に対して、video/divxというMIMEタイプを定義しておけば、各ブラウザでDivX Web Playerが起動するようになります。ただ、これだけではダメなようで、当初断念して、(1)の方法に流れていました。

で、改めて調べたところ、DivX Web Playerによるストリーミング再生には、単にAタグによるリンクではなく、OBJECTタグによるページ上への埋め込みが必要なようでした。具体的には、

<object classid="clsid:67DABFBF-D0AB-41fa-9C46-CC0F21721616" codebase="http://go.divx.com/plugin/DivXBrowserPlugin.cab">
    <param name="src" value="http://(ユーザ名):(パスワード)@(ファイルのパス).avi" />
    <param name="bannerEnabled" value="false" />
    <param name="minVersion" value="1.0.0" />
<embed type="video/divx" src="http://(ユーザ名):(パスワード)@(ファイルのパス).avi" width="640" height="372" pluginspage="http://go.divx.com/plugin/download/" bannerEnabled="false">
</embed>
</object>

って感じ。DivX LABSのDivX Web Player Code Generatorでサンプルソースを生成してもらえます。動画の縦ピクセル数に20を足すのがポイントのようです(コントローラーの分)。DivX Web Player自体はBASIC認証ダイアログを持ってナサゲなので、パスの部分にユーザ名とパスワードを埋め込んでみました。

で、Aタグしか生成してくれないApacheのインデックスリストではダメだということがわかりました。ということは本来はフォルダ中のファイル名一覧を取得して、上記HTMLを個別生成するPHPスクリプトでも自作しなければ、ということになるんですが、そこまでは気力がわかなかったので、手抜き対処。具体的には、ファイルインデックス画面のフッター部分にHTMLを挿入するApacheのReadmeNameディレクティブを使って極簡単なPHPによるHTMLフォームをインクルードし、ブラウザ上で目的動画ファイルのリンクをコピペして再生ページに投げます。で、再生ページもやはりPHPで受け取った動画のURIを使って、上記のDivX Web Player用HTMLを生成するだけです。

画面例

動画のサイズも取得する術がないので、とりあえず手動で指定しています。まさに超手抜き(^^;)。

補足:ffmpeg-phpを使って、phpから動画ファイルのサイズを取得できました。

更に補足:フォームを使わずとも、JavaScriptを使って実現できました。>URL書き換え

でもまぁ、自分と家族などごく身近な人間しか使わないのでこれでOK。基本はダウンロードかPS3利用推奨ってことで。

とりあえず、上記の手順でブラウザ上のストリーミング再生ができるようになりました。本来は.aviではなく.divxでないとダメっぽいですが、一応観れてます。DivX Web Player自体、タイムスライダーもあるし、どこまでDLできてるかバーでわかるし、ブラウザから切り離したり、全画面再生もできるしと、VLCよりは使い勝手が良いです。