A Day in the Life

オリンパスのカメラ用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 をまずは叩かないと何も表示されない。
  • 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
撮影機材α7C/ZEISS Batis 2/40 CF