玩式草子─ソフトウェアとたわむれる日々

第44回Nexus 7とMTP[その1]

前回紹介したように、SANEが対応しているスキャナを使えば、Linux環境でも書籍のスキャニングは簡単に行えます。加えて、最近のデスクトップ環境では、tarやzipでまとめた書庫ファイルを透過的に扱うことができるので、スキャンした画像データが何百ファイルになっても、1つの書庫ファイルにまとめたまま閲覧することができます。これらの機能のおかげで、自炊作業もずいぶん簡単になり、次第に自製の電子書籍データもたまってきました。

そうなると外出時やベッドに寝っころがっている時など、PC以外の環境でも電子書籍を読みたくなります。そこで電子書籍用の端末を探してみることにしました。

前回も触れましたが、昨年はAmazon Kindleや楽天Koboなど、安価で高性能な電子書籍用端末が多数発売され、何度目かの電子書籍ブームとなっていました。これらの専用端末は、それぞれの発売元が展開する電子書店と密接に結合され、そこで購入した電子書籍を利用するには便利そうな機能があれこれ用意されているものの、電子書店が販売する電子書籍に不満を持っていて、自炊で書籍の電子化を進めている人間にとっては、特定の電子書店と結合しているような機能はむしろ邪魔になりそうです。そこで汎用的なタブレットPCとしてGoogleが発売している、Nexus 7を試してみることにしました。

図1 Nexus 7の外観
図1 Nexus 7の外観

Nexus 7は、Googleが開発している7インチ画面のタブレットPCで、画面解像度は1280x800、NVIDIAのTegra3というARM系のCPUを使い、メモリは1GB、OSはAndroidの最新版(購入時は4.1で現在は更新されて4.2.2)が入っています。性能的にはAmazon Kindle fire HDとほぼ同等ながら値段は少し高め、でも、開発元であるGoogle謹製なので、常にAndroidの最新版が利用できる、という機種です。

Nexus 7を自炊データ用のブックリーダとして使うためには、まず自炊したデータをNexus 7側に持ち込む必要があります。Nexus 7を動かしているAndroidは、Linuxカーネルを中心としたOSではあるものの、モバイル機器用に特化した作りになっているため、使いなれたLinux環境のようにFTPやNFSでデータを持ちこむことはできそうにありません。そこであれこれ試行錯誤してみることになりました。

Google Drive経由のデータ転送

Nexus 7のネットワーク機能はWi-Fi接続に限られます。一応手元では、ノートPC用に無線LAN環境も構築していましたし、Google Playショップで注文して、Googleで使っているユーザアカウントがあらかじめ設定されて届いたので、特に何も設定しなくてもGoogle Chromeを使ったり、Gmailにアクセスできました。

しかし、Nexus 7を動かしているAndroid上には、ftpやscpといったLinux環境で使いなれたコマンドはありませんし、NFSやSambaを使ってファイルシステムを共有するような機能も無さそうです。さて、どうしたものか、と調べてみると、Nexus 7にはGoogle Driveにアクセスする機能が用意されていて、この機能を使えばLinux環境から自炊データを送れそうです。

図2 Google Driveと同期
図2 Google Driveと同期

データをNexus 7に持ち込めれば、Android用に開発されている電子書籍用アプリを使って自炊データを読むことができます。Google Playを眺めると、無料で使える電子書籍用アプリも多数登録されており、今回は、それらの中から"ComittoN"というアプリを使ってみることにしました。

"ComittoN"に限らず、たいていの電子書籍用アプリは、ZipやRARといったWindows環境で広く利用されている書庫形式に対応しており、書庫を自動的に展開して収められた複数の画像データを表示することができます。

図3 ComittoNの書庫データ表示機能
図3 ComittoNの書庫データ表示機能

残念ながらAndroid用のアプリの多くはUNIX系で主流のtar形式には対応していないものの、Windowsで広く使われているzip/unzipはOSSなコードも公開されており、機能をまとめた共有ライブラリも存在するので、UNIX/Linux環境でも不便なく利用できます。そのため、前回紹介したように、スキャンした自炊データを書庫化するのにzipコマンドを用いたのでした。

Google Driveはオンラインでファイルを共有するためのネットワークストレージシステムではあるものの、オフラインで利用するというオプションを指定すれば、Nexus 7側にファイルをダウンロードすることも可能です。この機能を使えば、無線LANの届かない寝室のベッドに寝転がりながらでも自炊データを読むことができそうです。

MTP経由でのデータ転送

とりあえずNexus 7を自炊データ用の電子書籍端末にすることはできたものの、Google Driveを介したデータ共有には限界が見えていました。

Google Driveの場合、オフラインでデータを利用できるといっても、あくまでGoogle Driveでのファイル共有を前提にしているので、Google Driveから削除してしまうと、オフラインで利用可能にしておいたファイルも、次に同期した際には消えてしまいます。一方、Google Driveの無料で使える容量は5GB程度なので、自炊データの本格的なファイルサーバに使うには物足りません。そこでWi-Fiネットワーク経由ではなく、Nexus 7にとっては充電用でもあるUSB経由でデータをやりとりする方法を調べてみました。

以前から使っている単機能のMP3プレイヤーは、USB経由で接続すればフラッシュメモリや外付けHDDと同じようにマス・ストレージクラスと認識され、ファイルシステムをマウントしてLinuxから自由に操作することができました。しかしながら、Nexus 7の場合は、USBケーブルで接続してもHDDパーティションが見えるようにはならず、dmesgにはこんなメッセージが残されるだけでした。

usb 10-1.4: new high-speed USB device number 4 using xhci_hcd
usb 10-1.4: New USB device found, idVendor=18d1, idProduct=4e41
usb 10-1.4: New USB device strings: Mfr=2, Product=3, SerialNumber=4
usb 10-1.4: Product: Nexus 7
usb 10-1.4: Manufacturer: asus
usb 10-1.4: SerialNumber: 015d2578c73c040c
usb 10-1.4: ep 0x81 - rounding interval to 32768 microframes, ep desc says 0 microframes
usb 10-1.4: ep 0x2 - rounding interval to 32768 microframes, ep desc says 0 microframes

さて、これはどうしたものか……、と調べてみると、最近の高機能なUSBメディアプレイヤーは、自律的なコンピュータとして働くようになっていて、外部機器との通信にはMTP(Media Transfrer Protocol)と呼ばれる専用のプロトコルを利用するようになっているそうです。

確かに、自律的にデータを管理する機能を持つデバイスの場合、マス・ストレージクラスとしてパーティションそのものを外部に見せてしまうと、自身が管理しているデータを外部から上書きされたりして、データ管理に齟齬が生じる可能性があります。MTPはそのようなトラブルを防ぐために開発されたプロトコルで、Nexus 7もUSB経由のデータ通信にはMTPを使っています。

もともとMTPはWindowsの世界で開発されたプロトコルで、Windows Media PlayerやインターネットエクスプローラにはMTPデバイスを操作する機能が用意されているそうです。一方、Unix/Linux向けにはMTPを使うためのライブラリ(libmtp)が開発されており、このライブラリを使うアプリケーションも開発されています。今回はそれらのうちgmtpというGTKベースのソフトウェアを試してみました。

紹介によると、gmtpはもともとSolaris 10の環境で開発されたソフトウェアなものの、特にSolarisの機能に依存する部分はなく、libmtpとGTKが利用できる環境ならば利用可能なようです。Plamo-5.0の環境ではlibmtpもGTKも揃っているので、さっそくgmtpをビルドして試してみました。

gmtpを起動後、"Connect"ボタンを押すと、MTP経由の通信に時間がかかるのか、ずいぶん待たされるものの、Nexus 7側のストレージ情報が表示されました。

図4 MTP経由で見えるNexus 7のストレージ情報
図4 MTP経由で見えるNexus 7のストレージ情報

これを使えばMTP経由でファイルが送り込めるかな、と、gmtpを操作してファイルをアップロードしようとしたところ、英数字だけのファイル名は問題なかったものの、日本語を使ったファイル名は文字が化けてしまい、正しく転送できませんでした。

図5 日本語のファイル名は文字化けする
図5 日本語のファイル名は文字化けする

たいてい、この手のトラブルの原因は想定している文字コードの違いなので、文字コードをUTF-8にしたシンボリックリンクを張って試してみると、今度は問題なく転送できました。

図6 UTF-8なら日本語も使える
図6 UTF-8なら日本語も使える

昔々、MacOSがappletalkしかしゃべれなかったころ、CAP(Columbia Appletalk Package)とsambaを使ってMacとWindows間でファイル共有する際、CAPで使っている独自の文字コード(CAPエンコーディング)をWindowsは理解できないので、一つのファイルに文字コードが異なるシンボリックリンクを張って、OSごとの文字コードの違いを仲介する、という手法がよく用いられていました。それと同じことをしているなぁ、と思いつつ、転送したいEUC-JPなファイル名に対してUTF-8なシンボリックリンク名を張ることで、gmtp経由でNexus 7にデータを送りこむことが可能になりました。

gmtpのクィックハック

とりあえずUTF-8なシンボリックリンクを介するとMTP経由でファイルを送れるようにはなったものの、転送したいファイルそれぞれに一々シンボリックリンクを張るのも面倒です。そこで、gmtpをイジってみることにしました。

gmtpが利用しているGTKツールキットでは、内部処理用の文字コードはUTF-8になっています。一方、ファイルシステム上の文字コードは、Plamo Linuxが守株しているEUC-JPのように、環境ごとにさまざまな種類がありえます。そこでGTKツールキットでは、ファイル名を操作する際、一度 g_filename_to_utf8() という関数を通して、ロケールで定義されている文字コードからUTF-8に変換した上でその後の処理を行うことになっています。

ところが最近主流になっているロケールがUTF-8の環境では、g_filename_to_utf8()を通して文字コードを変換しなくても問題は生じないため、この作業をサボってUTF-8以外の環境ではエラーになるソフトウェアが散見されます。

そのような視点からgmtpのソースコードを調べてみると、src/mtp.c の中に該当するようなコードが見つかりました。

たとえば、void fileAdd()という関数の中には、

658   filename_stripped = basename(filename);
659   displayProgressBar(_("File Upload"));
660   setProgressFilename(g_strdup(filename_stripped));

というコードがありました。このコードは、アップロードの進捗状況を示すプログレスバーの表示のようですが、指定されたファイル名(filename_stripped)の文字コードを変換することなく、直接 g_strdup()してsetProgressFilename()に渡してしまっています。そこで、display_filename という変数を用意して、一度ファイル名をg_filename_to_utf8()を通してから使うようにしてみました。

658   GError *terror = NULL;
659   gchar *display_filename;
660   filename_stripped = basename(filename);
661   display_filename = g_filename_to_utf8(filename_stripped, -1, NULL, NULL, &terror);
662   displayProgressBar(_("File Upload"));
663   setProgressFilename(display_filename);

似たような処理をしている部分がもう数ヵ所あったので、それらも同様の方法で直してみたところ、EUC-JPなファイル名のままでも直接転送できるようになりました。

図7 EUC-JPでも通るようになった
図7 EUC-JPでも通るようになった

紙幅の都合で修正箇所の詳細は紹介しませんが、Plamo Linux用にビルドしたパッケージをFTPサイトに置いているので、興味ある人は試してみてください。

このパッケージは64ビット版になっているものの、usr/share/doc/gMTP/以下に含まれているパッチファイルとビルドスクリプトを利用すれば32ビット版のパッケージも容易に作成できるでしょう。ただし、このパッチはファイル名だけを直す場当たり的な修正なので、途中のディレクトリ名に日本語があると、ファイルは転送できるもののエラーメッセージが出るようです。

Nexus 7でどこでも語学レッスン

以前にもこの連載で紹介したように、現在、NHKラジオは「らじる☆らじる」という名称でインターネットでも同時放送されており、少し工夫すればその内容を録音することができます。

その録音用スクリプトを組んだころから、ラジオ第二の語学講座に関する興味が出てきて、いくつかの番組を録音しては、外出時等に携帯プレイヤーで聞いていました。

語学は耳から、というのはよく聞くものの、アルファベットもよく知らない新しい言語を学ぶ際にはテキストが無いと不便です。そのため語学講座のテキストも思いついた時に買ってはいたものの、携帯プレイヤーとテキストを同時に用意するのは面倒で、なかなか読み進めるには至りませんでした。

そこで思いついたのがNexus 7を使った「どこでも語学レッスン」です。語学講座のテキストを自炊して電子化し、録音したMP3ファイルとともにNexus 7に持ち込んでおけば、気が向いた時に「Playミュージック」で講座を再生しながら、自炊したテキストを学ぶことができます。

図8 番組を再生しながらテキストを表示
図8 番組を再生しながらテキストを表示

NHKラジオ第二の語学講座は、月400円程度のテキスト代だけでさまざまな語学を学べる魅力はあるものの、決まった時間に聞き続けることが難しかったり、自分のペースで進めることができなかったりでなかなか長続きがしませんでした。

しかし、タイマー録音できるようになった「らじる☆らじる」の音声データと自炊したテキストデータをNexus 7に持ちこむことで、⁠いつでも、どこでも、自分のペースで」学べる、理想的な学習環境が実現できました。

もっとも最近では、講座内容を収録したCDと共に電子化されたテキストも公式に発売されているので、それらを使えば同等の環境はもっと簡単に構築できたかもしれません。しかし、多少不便で手間がかかっても、好きなようにデータを扱うことができる自作システムの方を好むのは、⁠貧乏性」というよりも「OSS支持者の性(さが⁠⁠」ということにしておきましょう(苦笑⁠⁠。

おすすめ記事

記事・ニュース一覧