THETA関連APIのまとめ(2022年11月更新版)

## 1. はじめに
THETAを使った開発をしてみようという人のために、開発の仕方をまとめてみた。手軽に試せるようにコマンドなどでの使用例を記載した。公式の仕様はgithubの[ricohapi/awesome-theta](https://github.com/ricohapi/awesome-theta)でまとめられている。
* RICOH THETA Xについて追記 (2022/10/07)
* api.ricohサイトが閉鎖されたため、リンクを修正(2022/10/27)

### 動作環境
記事中では以下の環境を中心に動作確認した。

* macOS Catalina (10.15.7)
* RICOH THETA V, Firmware ver.3.50.1

## 2. THETAシリーズと対応API/機能

モデルによって対応しているAPI/機能が異なっており、[ここ](https://github.com/ricohapi/theta-api-specs/tree/main/ricoh-theta-api)に詳細が記載されている。

| 発売年 | モデル名 | Web API | USB API | BLE API | UVC対応 | [Plugin対応](https://github.com/ricohapi/theta-api-specs/tree/main/ricoh-theta-plugin/) | 
|:-----:|:-------:|:-------:|:-------:|:-------:|:---------:|:---------:|
| 2013 | RICOH THETA | [v1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v1.0/) | - | - | - | - | 
| 2014 | RICOH THETA m15 | [v1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v1.0/) | - | - | - | - |
| 2015 | RICOH THETA S | [v2](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.0/)/[v2.1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/) | [MTP v1.1](https://github.com/ricohapi/theta-api-specs/tree/main/theta-usb-api) | - | HD/2K | - |
| 2016 | RICOH THETA SC | [v2](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.0/)/[v2.1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/) | [MTP v1.1](https://github.com/ricohapi/theta-api-specs/tree/main/theta-usb-api) | - | - | - |
| 2017 | RICOH THETA V | [v2.1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/) | [MTP v1.1](https://github.com/ricohapi/theta-api-specs/tree/main/theta-usb-api) | [GATT](https://github.com/ricohapi/theta-api-specs/tree/main/theta-bluetooth-api/) | 2K/4K | [Android API](https://github.com/ricohapi/theta-api-specs/blob/main/ricoh-theta-plugin/api.md) |
| 2019 | RICOH THETA Z1 | [v2.1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/) | [MTP v1.1](https://github.com/ricohapi/theta-api-specs/tree/main/theta-usb-api) | [GATT](https://github.com/ricohapi/theta-api-specs/tree/main/theta-bluetooth-api) | 2K/4K | [Android API](https://github.com/ricohapi/theta-api-specs/blob/main/ricoh-theta-plugin/api.md) |
| 2019 | RICOH THETA SC2 | △ | △ | - | - | - |
| 2022 | RICOH THETA X | [v2.1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/) | [MTP v1.1](https://github.com/ricohapi/theta-api-specs/tree/main/theta-usb-api) | [GATT](https://github.com/ricohapi/theta-api-specs/tree/main/theta-bluetooth-api) | 2K/4K（天頂補正） | [Android API](https://github.com/ricohapi/theta-api-specs/blob/main/ricoh-theta-plugin/api.md) |

* THETA V/Z1のBLE (Bluetooth Low Energy)はデフォルトでは無効。WLANのAPモードで接続後、WebAPIから有効化できる（後述）。
* THETA SC2はWebAPI/USBAPIに公式には対応していないが、概ね利用できる。

# 3. 各種API/機能
## 3-1. Web API
Googleの[Open Spherical Camera(OSC)](https://developers.google.com/streetview/open-spherical-camera)で定義されたコマンドの他に、THETA用の拡張コマンドが多数定義されている。元々THETAは画面を持たず、スマホからの操作が想定されていたため、ほぼすべての操作をWebAPIを介して行うことができる。
### WebAPIのバージョン
WebAPIは初代のTHETAから対応しているが、モデルによってプロトコルが異なる。現状はOSC ver.2がベースのWebAPI v2.1が利用されている。THETA S/SCのWebAPI v2.0はデフォルトがOSC ver.1ベースのため、[camera.startSession](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.0/commands/camera.start_session.md)が必要となる。THETA V/Z1(/SC2)ではOSC ver.2がデフォルトとなり、OSC ver.2ではステートレスになったため、camera.startSessionは不要になった。THETA S/SCではv2.1にも対応しており、[client_version](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/options/client_version.md)をセットすることでv2.1に切り替えられるが、切断するとデフォルトのv2に戻る。

| WebAPIバージョン | ベースプロトコル |
|:-:|:-:|
| [v1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v1.0/) | PTP-IPベース |
| [v2](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.0/) | OSC ver.1ベース |
| [v2.1](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/) | OSC ver.2ベース |

### CLモード
THETA V/Z1ではCLモードが利用できる。CLモードは無線LANルータに接続する無線LAN接続のモード（PCやスマホのWi-Fi接続と同じ）である。デフォルトの無線LAN接続設定はAPモード（1:1接続するモード）となっており、スマホアプリもしくはWebAPI([_network_type](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/options/_network_type.md))で切り替えることでCLモードが利用できる。CLモードではダイジェスト認証が必須となり、BLE設定などいくつかのWebAPIの利用が制限されている。

### WebAPI v2.1 (OSC ver.2)での撮影
WebAPI v2.1ベースのTHETA V以降であれば、次の一行で撮影できるため、簡単にAPIを試すことができる。THETAYL00123456の部分を自身のカメラのシリアル番号に変更すれば良い。CLモードではダイジェスト認証が利用されるため、`--digest`でCLモード接続のためのIDとパスワードを設定する。IDとパスワードはRICOH THETAスマホアプリで設定できる。（[参考](https://qiita.com/mktshhr/items/17f9208bf35505926dec)）

```zsh:terminal
% curl -X POST http://THETAYL00123456.local./osc/commands/execute --data '{"name":"camera.takePicture"}' -H 'content-type: application/json' --digest -u THETAYL00123456:00123456
```


## 3-2. USB API
[USB Media Transfer Protocol (MTP) v.1.1](https://www.usb.org/document-library/media-transfer-protocol-v11-spec-and-mtp-v11-adopters-agreement)をベースに、[THETA用に機能拡張したUSB API](https://github.com/ricohapi/theta-api-specs/tree/main/theta-usb-api)を利用できる。

### USB API(MTP v1.1)での撮影
ここではgphoto2をインストールして一般的なMTPの機能を使って撮影してみる。

```zsh:terminal
% brew install gphoto2
```

* 接続確認

THETAを静止画モードにした状態でUSBでMacと繋げる。

```zsh:terminal
% gphoto2 --auto-detect
Model                          Port
----------------------------------------------------------
USB PTP Class Camera           usb:020,010
% gphoto2 --summary
Camera summary:
Manufacturer: Ricoh Company, Ltd.
Model: RICOH THETA V
...
```

* 静止画撮影

```zsh:terminal
% gphoto2 --capture-image
New file is in location /store_00020001/DCIM/100RICOH/R0010680.JPG on the camera
```

* ファイルのダウンロード

```zsh:terminal
% gphoto2 --get-file /store_00020001/DCIM/100RICOH/R0010680.JPG
Saving file as R0010680.JPG
```

* 撮影＋ダウンロード+削除（一括実行）

```zsh:terminal
% gphoto2 --capture-image-and-download --filename ./test.jpg
New file is in location /store_00020001/DCIM/100RICOH/R0010681.JPG on the camera
Saving file as ./test.jpg
Deleting file /store_00020001/DCIM/100RICOH/R0010681.JPG on the camera
```

* バッテリレベル取得

```zsh:terminal
% gphoto2 --get-config=batterylevel
Label: Battery Level
Readonly: 1
Type: TEXT
Current: 100%
END
```

## 3-3. BLE API
Bluetooth Low Energy用の[BLE API](https://github.com/ricohapi/theta-api-specs/tree/main/theta-bluetooth-api)は、[Bluetooth SIGのGATT](https://www.bluetooth.com/ja-jp/specifications/gatt/)をベースにTHETA用に独自にサービス定義されたAPIである。[GATT](https://www.bluetooth.com/ja-jp/specifications/gatt/)はBluetooth LEの基本となるデータ転送の方法を定義したプロファイルであり、サービスと属性(Characteristic)で構成される。この属性（状態やコマンド）の値を読み書きするのが基本となる。
THETAはBLEのPeripheral（Advertiseする側）として動作し、BLE接続するアプリを作る際はCentral（Scanする側）のソフトを作ることになる。

### 提供サービス
THETAで定義されているサービスは以下の通り。全てのサービスと属性は[こちら](https://github.com/ricohapi/theta-api-specs/tree/main/theta-bluetooth-api/characteristics_list.md)に記載されている。 


| サービス名 | UUID | 機能 |
|:-:|:-:|:-:|
| Camera Information | 9A5ED1C5-74CC-4C50-B5B6-66A48E7CCFF1 | ファームウエアバージョンなど、カメラ情報の取得 |
| Camera Status Command | 8AF982B1-F1FF-4D49-83F0-A56DB4C431A7 | バッテリ情報など、カメラのステータス取得 |
| Camera Control Command | 32886D39-BA23-425C-BCAE-9C1DB0066922 | 音量などの、カメラの設定情報の取得 |
| Shooting Status Command | 9AD04FDF-E62B-43E4-8593-7631FCD29874 | 撮影時エラーなど、カメラの撮影状態の取得 |
| Shooting Control Command | 1D0F3602-8DFB-4340-9045-513040DAD991 | カメラの撮影処理 |
| Shooting Control Command v2 | 38EF1533-B0CC-4722-B6B6-8B23C27ECE5C | 絞り設定などZ1やVのFirm ver.3以降で追加されたカメラの撮影処理  |
| GPS Control Command | 84A0DD62-E8AA-4D0F-91DB-819B6724C69E | カメラに位置情報を設定する |
| WLAN Control Command | F37F568F-9071-445D-A938-5441F2E82399 | カメラのWi-Fi設定 |
| Bluetooth Control Command | 0F291746-0C80-4726-87A7-3C501FD3B4B6 | カメラのBluetooth設定 |

### BLEでの接続
BLEを有効にするにはAPモードで接続した上で、WebAPIを利用して準備する必要がある。APモードでWi-Fi接続（THETAとPCを1:1でWi-Fi接続）し、以下の手順でBLEを有効にする。

1. BLE用パスワードの登録

Web APIの[camera._setBluetoothDevice](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/commands/camera._set_bluetooth_device.md)で自分のパスワードを設定する。ここではuuidgenコマンドで生成した文字列("50BC9100-F957-4EC2-BBDF-196D6561A7BF")を設定する。

```zsh:terminal
% uuidgen
50BC9100-F957-4EC2-BBDF-196D6561A7BF

% curl -X POST 192.168.1.1/osc/commands/execute --data '{"name":"camera._setBluetoothDevice","parameters":{"uuid":"50BC9100-F957-4EC2-BBDF-196D6561A7BF"}}' -H 'content-type: application/json'

{"name":"camera._setBluetoothDevice","results":{"deviceName":"00129704"},"state":"done"}
```

* 2. [_bluetoothPower](https://github.com/ricohapi/theta-api-specs/blob/main/theta-web-api-v2.1/options/_bluetooth_power.md)をONする

```zsh:terminal
% curl -X POST 192.168.1.1/osc/commands/execute --data '{"name":"camera.setOptions","parameters":{"options":{"_bluetoothPower":"ON"}}}' -H 'content-type: application/json'
{"name":"camera.setOptions","state":"done"}
```

* 3. BLEで接続

BLEでの接続確認を行うため、AppleのBluetooth Explorerや、iPhoneの[BLExplrアプリ](https://apps.apple.com/jp/app/blexplr/id524018027)や[LightBlue(iOS版)](https://apps.apple.com/jp/app/lightblue/id557428110),[LightBlue(Android版)](https://play.google.com/store/apps/details?id=com.punchthrough.lightblueexplorer&hl=ja&gl=US)を利用できる。これらのアプリはBLEアプリを作る際のデバッグでも利用できるため便利である。Bluetooth ExplorerはmacOSで動作するアプリであり、Apple Developer Connection(ADC)のサイトから[Additional Tools for XCode](https://developer.apple.com/download/more/?=additional%20Tools)をダウンロードすると、中に含まれている。ダウンロードにはADCの開発者登録が必要となる。以降、Bluetooth Explorerでの例を示す。

Bluetooth Explorerを起動して、"Devices"メニューから"Low Energy Devices"を選ぶと、THETAがシリアル番号で表示される。このシリアル番号を選択して"Connect"すると、先に説明したサービスリストが表示される。
![BLEDevice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123458/c6b1a99c-9dcf-445c-0ecc-ee2fdda4c566.png)

* 4. BLE APIを有効化

WebAPI(_setBluetoothDevice)で先ほど登録した自身のパスワードを用いてBLE上で認証を行う。認証にはBluetooth Control Commandサービス(0F291746-0C80-4726-87A7-3C501FD3B4B6)にある、[Auth Bluetooth Device(EBAFB2F0-0E0F-40A2-A84F-E2F098DC13C3)](https://github.com/ricohapi/theta-api-specs/blob/main/theta-bluetooth-api/bluetooth_control_command/auth_bluetooth_device.md)を用いる。ここに自身のパスワードを書き込むことで、BLE APIを有効化できる。Bluetooth Explorerで、EBAFB2F0-0E0F-40A2-A84F-E2F098DC13C3のCharacteristicを選択し、先に設定したパスワード("50BC9100-F957-4EC2-BBDF-196D6561A7BF")を"UTF8"で設定("Write")する。すると、BLE接続が有効となり、それまで"Value"と表示された部分に実際の値が表示されるようになる。この有効化はBLE接続の度に毎回必要となる。
![BLEDeviceAuth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123458/04387992-5610-e73a-c9a6-cbb2ee32ea80.png)

### BLE APIでの撮影
 
ここでBLE APIを用いた撮影を試してみる。Shooting Control Commandサービス(1D0F3602-8DFB-4340-9045-513040DAD991)の中に、[Take Picture属性(FEC1805C-8905-4477-B862-BA5E447528A5)](https://github.com/ricohapi/theta-api-specs/blob/main/theta-bluetooth-api/shooting_control_command/take_picture.md)がある。ここに"1"を"RAW"で設定("WRITE")すると、撮影が行われる。
![BLEDeviceTakePicture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123458/09410000-2d60-71bc-b17a-5b8da9bb7ff3.png)

## 3-4. UVC対応
APIではないのだが、システムの一部として利用されることが多いため、UVCについても少し記載する。THETA S / V/ Z1で利用でき、モデルや設定で利用できるバージョンが異なる。THETA V/Z1ではEquirectangular形式でカメラから画像が出力されるため、THETA SでEquirectangularで出力する際に必要であった[DualFish Blender](https://support.theta360.com/ja/download/uvc/)が必ずしも必要ではなくなった。ただし、UVCを扱うアプリでうまく動作しない場合があるため、[RICOH THETA UVC 4K](https://topics.theta360.com/ja/faq/c_06_z1/304_1/)が配布されている。

| モデル | UVC version | 備考 |
|:-:|:-:|:-:|
| RICOH THETA S | v1.1(720p@15fps/MotionJPEG) <br> v1.5(FHD@30fps/H.264) | Dual Fish出力。Equirectangularでの出力や<br>FHDの利用には[DualFish Blender](https://support.theta360.com/ja/download/uvc/)が必要。 |
| RICOH THETA V | v1.5 (FHD or 4K @30fps/H.264) | Equirectangular出力 |
| RICOH THETA Z1 | v1.5 (FHD or 4K @30fps/H.264) | Equirectangular出力 |
| RICOH THETA X | v1.5 (FHD or 4K @30fps/H.264) | Equirectangular出力 （天頂補正可能） |

UVC ver.1.5ではVideo Frame Descriptorの定義としてH.264/VP8など高解像度動画で利用される形式が含まれるようになったが、ver.1.1ではそれらは定義されておらず、主に非圧縮やMJPEGが利用されていた。THETA Vが発売された2017年秋ごろにWindows10(ver.1703)やmacOS(10.12.4)でUVC ver.1.5が利用できるようになった。UbuntuでのUVC ver.1.5対応については今年(2020)の夏に[libuvc for RICOH THETAが公開](https://topics.theta360.com/ja/news/2020-07-28/)されており、この活用について[theta360.guide内のトピック](https://community.theta360.guide/t/live-streaming-over-usb-on-ubuntu-and-linux-nvidia-jetson/4359/25)の後半で議論されている。

## 3-5. Plugin対応

THETA V/Z1はAndroid OSがベースとなっており、アプリ(=プラグイン)を開発してインストールできる。詳細は他にも多くの記事があるので、ここでは説明を省略するが、上記のWebAPIはほぼそのまま、プラグインの中からlocalhost宛ての通信として実行できる。カメラの中では撮影アプリ(com.theta360.receptor)が常駐しており、WebAPIを受け付けている。この辺りの構成は[ここ](https://www.slideshare.net/RICOHTHETAPluginDevloperCommunity/ricoh-theta-120818517)で紹介されている。また、["THETAのプラグイン開発Tips"を以前書いた](https://qiita.com/mktshhr/items/6d9229fb7483d04ee157)ため紹介しておく。

# 4. まとめ
これまでのTHETAのモデルとそれぞれの対応APIについて、改めて仕様を確認した。特に巷のBLE APIの使い方紹介が少なかったため、BLE APIを中心に説明を行い、実際に撮影するところまでを紹介した。ただし、各種APIの中ではWeb APIが最も使いやすい。WebAPIが利用できる環境であれば、WebAPIを利用するのが良いと思う。CLモードを使えばWLAN設定の変更も必要ないため、PC/Macからも比較的簡単にcurlコマンドなどでWebAPIを使った通信を行える。BLE APIは外部から接続設定を行うことなく利用できるため、WLANが使えない環境などで利用できる。アダプタなどを利用して有線LANも利用可能な場合があるが、有線での確実な通信を行いたい場合にはUSB APIも選択肢となる。用途に合わせたAPIを選択すると良いだろう。