At first
RICOH THETA API V2 There is a Developer Page (https://developers.theta360.com/en/), a Reference (https://developers.theta360.com/en/docs/v2/api_reference/) and a Forum. ](Https://developers.theta360.com/ja/forums/) is open to the public.
This page shows an example of actually hitting the following API based on Getting Started.
Basically, JSON format parameters and responses are exchanged by POST.
Prerequisite
Shell Script First, in order to get an image of the processing flow, let's hit from Shell while checking the response. This time, we will use the "curl" command that is installed by default on Mac OS X.
#Get information about the camera body
$ curl http://192.168.1.1:80/osc/info
{"manufacturer":"RICOH","model":"RICOH THETA S","serialNumber":"XXXXXXXX","firmwareVersion":"01.11","supportUrl":"https://theta360.com/en/support/","endpoints":{"httpPort":80,"httpUpdatesPort":80},"gps":false,"gyro":false,"uptime":583,"api":["/osc/info","/osc/state","/osc/checkForUpdates","/osc/commands/execute","/osc/commands/status"]}
Information on the camera body has been acquired. This value will not be used after this.
#Session start
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.startSession"}'
{"name":"camera.startSession","state":"done","results":{ "sessionId":"SID_0001","timeout":180}}
The "sessionId" obtained here will be used later. You need to manually put it in the place corresponding to "SID_0001" on the next line.
#Still image shooting
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.takePicture", "parameters": {"sessionId": "SID_0001"}}'
{"name":"camera.takePicture","state":"inProgress","id":"2","progress":{"completion":0.0}}
The camera is called a cure. It will take some time to finish shooting the image.
#Acquisition of shooting status
$ curl -X POST http://192.168.1.1:80/osc/state
{"fingerprint":"FIG_0006","state":{"sessionId":"SID_0001","batteryLevel":1.0,"storageChanged":false,"_captureStatus":"idle","_recordedTime":0,"_recordableTime":0,"_latestFileUri":"100RICOH/R0010174.JPG","_batteryState":"charging"}}
Here, use "_latestFileUri" that can be obtained when the shooting process is completed with the following API. If there is a change in "fingerprint", the image processing is finished. You may need to run it several times until you get the "_latestFileUri".
#File acquisition
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.getImage", "parameters": {"fileUri": "100RICOH/R0010174.JPG"}}' > image.jpg && open image.jpg
I have taken the file and saved it in image.jpg in the execution directory. It is open in the viewer after picking up.
#End of session
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.closeSession", "parameters": {"sessionId": "SID_0001"}}'
{"name":"camera.closeSession","state":"done"}
The cleanup is complete.
It takes some time to specify the parameters, but I think it was confirmed that you can easily take pictures and take back images with HTTP.
Ruby
require 'net/http'
require 'json'
http = Net::HTTP.new('192.168.1.1', 80)
JSON.parse(http.get("/osc/info").body)
res = http.post('/osc/commands/execute', {name: "camera.startSession"}.to_json)
sessionId = JSON.parse(res.body)["results"]["sessionId"]
params = {name: "camera.takePicture", parameters: {sessionId: sessionId}}.to_json
http.post('/osc/commands/execute', params)
fileUri = JSON.parse(http.post('/osc/state',"").body)["state"]["_latestFileUri"] while fileUri.empty?
params = {name: "camera.getImage", parameters: {fileUri: fileUri}}.to_json
res = http.post('/osc/commands/execute', params)
open("image.jpg ", "wb") {|f| f.write(res.body)}
`open image.jpg`
params = {name: "camera.closeSession", parameters: {sessionId: sessionId}}.to_json
http.post('/osc/commands/execute', params)
I think you can read it intuitively. I like Ruby.
Python
import urllib
import json
urllib.urlopen("http://192.168.1.1/osc/info").read()
data = json.dumps({"name":"camera.startSession"})
res = urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)
sessionId = json.loads(res.read())["results"]["sessionId"]
data = json.dumps({"name":"camera.takePicture", "parameters": {"sessionId": sessionId}})
urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)
fileUri = ""
while not fileUri:
res = urllib.urlopen('http://192.168.1.1/osc/state', urllib.urlencode({}))
fileUri = json.loads(res.read())["state"]["_latestFileUri"]
data = json.dumps({"name":"camera.getImage", "parameters": {"fileUri": fileUri}})
res = urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)
with open("image.jpg ", "wb") as file:
file.write(res.read())
data = json.dumps({"name":"camera.closeSession", "parameters": {"sessionId": sessionId}})
urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)
I think you can read this intuitively as well.
I wanted to open the image, but when I paste the following code together after the above code, the behavior of Popen was not stable. If it is executed at any time, the image could be opened with the following code even from the REPL environment.
import subprocess
subprocess.Popen(['open', 'image.jpg'])
Swift
import UIKit
// for asynchronous use in Playground
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let session = NSURLSession.sharedSession()
// osc/info
var url = NSURL(string: "http://192.168.1.1/osc/info")
var task = session.dataTaskWithURL(url!) {
(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()
// camera.startSession
var sessionId = "";
var jsonDic = NSDictionary()
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
var req = NSMutableURLRequest(URL: url!)
var params: [String: AnyObject] = ["name": "camera.startSession"]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
do {
jsonDic = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
} catch {}
let result = jsonDic["results"] as! NSDictionary
sessionId = result["sessionId"] as! String
}
task.resume()
while sessionId.isEmpty { sleep(1) }
// camera.takePicture
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
req = NSMutableURLRequest(URL: url!)
params = ["name": "camera.takePicture", "parameters": ["sessionId": sessionId]]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params,
options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()
// osc/state
var fileUri = "";
url = NSURL(string: "http://192.168.1.1/osc/state")
req = NSMutableURLRequest(URL: url!)
req.HTTPMethod = "POST"
repeat {
sleep(1)
print("try osc/state")
task = session.dataTaskWithRequest(req) {
(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
do {
jsonDic = try NSJSONSerialization.JSONObjectWithData(data!,
options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
} catch {}
let result = jsonDic["state"] as! NSDictionary
fileUri = result["_latestFileUri"] as! String
}
task.resume()
} while fileUri.isEmpty
print(fileUri)
// camera.getImage
var img :UIImage?
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
req = NSMutableURLRequest(URL: url!)
params = ["name": "camera.getImage", "parameters": ["fileUri": fileUri]]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params,
options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
(data, response, error) in
// NSData.init(data: data!)
img = UIImage(data: data!)
}
task.resume()
while (img == nil) { sleep(1) }
// camera.closeSession
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
req = NSMutableURLRequest(URL: url!)
params = ["name": "camera.closeSession", "parameters": ["sessionId": sessionId]]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params,
options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()
Since NSURLSession is an API that executes asynchronously, waiting processing is inserted here and there. When the value is entered in img, you can see the image by previewing the variable in the Results Sidebar of the Playground environment. Where to process JSON, I want to write it a little more beautifully.
Unity
using UnityEngine;
using UnityEngine.UI;
using System.Text;
using System.Collections;
using System.Collections.Generic;
public class THETAOSC : MonoBehaviour {
void Start () {
StartCoroutine(StartThetaS());
}
IEnumerator StartThetaS () {
string url = "http://192.168.1.1/osc/info";
WWW www = new WWW(url);
yield return www;
Debug.Log(www.text);
Dictionary<string, string> header = new Dictionary<string, string>();
url = "http://192.168.1.1/osc/commands/execute";
string jsonStr = "{\"name\": \"camera.startSession\"}";
byte[] postBytes = Encoding.Default.GetBytes (jsonStr);
www = new WWW (url, postBytes, header);
yield return www;
JsonNode json = JsonNode.Parse(www.text);
string sessionId = json["results"]["sessionId"].Get<string>();
Debug.Log(sessionId);
jsonStr = "{\"name\": \"camera.takePicture\", \"parameters\": {\"sessionId\": \"" + sessionId + "\"}}";
postBytes = Encoding.Default.GetBytes (jsonStr);
www = new WWW (url, postBytes, header);
yield return www;
Debug.Log(www.text);
string fileUri = "";
url = "http://192.168.1.1/osc/state";
jsonStr = "{}";
postBytes = Encoding.Default.GetBytes (jsonStr);
while(fileUri == "") {
www = new WWW (url, postBytes, header);
yield return www;
Debug.Log(www.text);
json = JsonNode.Parse(www.text);
fileUri = json["state"]["_latestFileUri"].Get<string>();
}
Debug.Log(fileUri);
//Even if fileUri is obtained, the process may not be completed, so wait for a while
yield return new WaitForSeconds(3);
url = "http://192.168.1.1/osc/commands/execute";
jsonStr = "{\"name\": \"camera.getImage\", \"parameters\": {\"fileUri\": \"" + fileUri + "\"}}";
postBytes = Encoding.Default.GetBytes (jsonStr);
www = new WWW (url, postBytes, header);
yield return www;
//Show in Raw Image for confirmation
RawImage rawImage = GetComponent<RawImage>();
rawImage.texture = www.textureNonReadable;
rawImage.SetNativeSize();
jsonStr = "{\"name\": \"camera.closeSession\", \"parameters\": {\"sessionId\": \"" + sessionId + "\"}}";
postBytes = Encoding.Default.GetBytes (jsonStr);
www = new WWW (url, postBytes, header);
yield return www;
Debug.Log(www.text);
}
}
Summary Using the OSC-compliant API of THETA S, I actually tried to move the flow of shooting and image collection and how to hit the API in each environment. You can set shooting options for the camera in the same way, so I think you can play around with it. I hope it will be a reference and an opportunity!