オリンパスのカメラ用APIライブラリを作った
オリンパスのカメラ用のWiFi経由で操作できるAPI ライブラリ(Ruby用)を作った。カメラごとのAPIを自動で作成し、カメラのシャッターが押せたり、画像ファイルをダウンロードしたり、電源が切れたりする。また、このライブラリを利用して画像をダウンロードする cli インターフェイスのolympus-camera-dlというものも作った(というかこれが作りたくて、APIライブラリは副産物)。
こんな感じで使える。
$ olympus-camera-dl --delete --power-off /home/pi/photos/E-M1MarkII/
Connected: E-M1MarkII
11 images found
[1/11] DOWNLOAD: /DCIM/101OLYMP/PB202134.JPG
[1/11] WRITE: /home/pi/photos/E-M1MarkII/PB202134.JPG (4,517,267 byte)
[1/11] DELETED: /DCIM/101OLYMP/PB202134.JPG on camera
[2/11] DOWNLOAD: /DCIM/101OLYMP/PB202135.JPG
[2/11] WRITE: /home/pi/photos/E-M1MarkII/PB202135.JPG (4,380,822 byte)
[2/11] DELETED: /DCIM/101OLYMP/PB202135.JPG on camera
...
[11/11] DOWNLOAD: /DCIM/101OLYMP/PB202144.JPG
[11/11] WRITE: /home/pi/photos/E-M1MarkII/PB202144.JPG (4,466,991 byte)
[11/11] DELETED: /DCIM/101OLYMP/PB202144.JPG on camera
Power off
オリンパスのカメラ用のAPI
USB経由で叩く場合、カメラAPI抽象化ライブラリであるlibgphoto2を使うと大抵の操作はできるのだけど、WiFi経由で利用がしたかった。オリンパスのカメラのWiFiアクセスポイントモードで起動し、そのアクセスポイントにアクセスすると、http://192.168.0.10/
という IP 決め打ちでカメラが建てている httpd にアクセスができ、そこのエンドポイントを叩くことで操作ができる。
以前のカメラでは http://192.168.0.10/DCIM
という URL にアクセスすると、HTMLを返す簡易画像ビュワーを表示でき、この HTML をスクレイピングすることで画像の取得が可能だった。たとえば、olympus-photosync というツールでは、/DCIM
を叩いて画像のダウンロードを行っている。
しかしながら、例えば E-M1 mark III などの最近のカメラでは /DCIM
にアクセスしても画像ビュワーが表示されなくなった。これはスマートフォンのアプリ経由で使ってね、ということでレガシーなインターフェイスが無くなるのはしょうがない。
オープンプラットフォームカメラ通信仕様書
他に叩けそうなAPIは無いのかと調べてみると、どうやらオープンプラットフォームカメラ通信仕様書 [english]なるPDFがあった(オリンパスのサイトからはリンクが見つけられなかった…)。これはディスコンになってしまった、意欲的なカメラ OLYMPUS AIR A01が出た時に作られたようだ。そういえば2010年台は大手企業がこれからはオープンプラットフォーム・オープンイノベーションや!と言っていた時期があったね…。
ただこの通信仕様書は、ちゃんと実装されてるのは OLYMPUS AIR だけと思われ、ほかのカメラは API の形式が微妙に違ったり、APIが増えたり減ったりしている。
get_commandlist.cgi から API を作る
じゃあオリンパスが出している、カメラ操作ができるスマートフォンアプリは何を元に叩いているのかと調べると、そのカメラで叩ける API 一覧が出力されている http://192.168.0.10/get_commandlist.cgi
を元にしているようだ(get_commandlist.cgi のレスポンス例)。ただもちろん、カメラごとにこの get_commandlist.cgi の出力は違う。例えば、ファイル削除API の exec_erase.cgi
は PEN-F には無いが、E-M1-2/E-M1-3 には存在する。
そのため、get_commandlist.cgi の結果から ruby のメソッドを define_singleton_method で作るようにしている。また response も XML だったり text だったりするので、そのへんもよしなにしている(text/xml
でレスポンスが返ってくるのに空BODYだったりするので、あんまり当てにならない)。
なおE-M1-2/3で利用できそうなget_camprop.cgi
を叩くと500になってしまい、問題ないAPIの叩き方がいまだに解らない…。
よく使いそうな cgi の path
単に cgi を叩けば良いので、わざわざこのライブラリを使わなくても curl などでも簡単 API を叩くことができる。
-
/get_imglist.cgi?DIR={path}
- いわゆる ls。ただ
?DIR=/
ではエラーになり、?DIR=/DCIM
と画像格納 path/DCIM
をまずは叩かないと何も表示されない。
- いわゆる ls。ただ
-
path そのまんま
-
オリジナル画像をダウンロード
-
-
/set_playtargetslot.cgi?targetslot={N}
- ターゲットにするSDカードスロットを変更
-
/exec_erase.cgi?DIR={path}
- いわゆる rm
-
/exec_pwoff.cgi
- 電源を切る
その他:撮影して WiFi に繋いで即アップロードはとても便利
jpeg の撮って出しは自動で Google Photos にアップロードされるようにしているのだけど、とても便利。
家においてある Raspiberry PI は各種カメラのアクセスポイントにつながったらスクリプトを自動実行をするようにしているので、写真を撮ったら カメラの WiFi ボタンをタッチするだけでほおっておけばアップロードされるので便利に使ってる(参照: ftp・ftps でアップロードしたファイルを Google Photos にアップロードする)。
# !/bin/bash
/sbin/iwgetid > /dev/null || exit 1
DOWNLOAD_DIR="/home/pi/ftp_uploads/photos/"`ruby -r 'olympus-camera' -e 'print OlympusCamera.new.get_caminfo["model"][0]'`
/usr/local/bin/rlock /tmp/olympus-dl.lock -- /usr/local/bin/olympus-camera-dl -c 2 --delete --power-off $DOWNLOAD_DIR