HowTo: Develop 360 Image Desktop Apps with JavaScript and RICOH THETA

Congratulations on your progress. This will be useful to people in the future as there is no easy way for people to set camera parameters from a desktop/laptop.

Also, the mobile app doesn’t allow configuration of the entire API.

Whenever you’re ready, feel free to put your code up on GitHub. Maybe other people will join into the development and submit pull requests.

2 Likes

result2

a little more user friendly.

i will repost to github once i finish what ive been currenly working on,
this is just one step to get me closer to my main plan.

time is a factor.

2 Likes

Kevin,

Really cool that you’re putting in the effort. I’m pretty interested in trying this out myself. I’ve wanted to be able to grab bigger chunks of API accessible info all at once. This seems like a cool answer to that.

No pressure. But if you do get it up in a GitHub repo, I’d love to be able to try it out myself.

Jesse

PS. Time is always a factor. :slight_smile:

2 Likes

Very compelling Motivation, and Quote.

just had to do some work.
not sure if its useful the way im going, but I’ve never made a Github before.


also formatting text so when set at the correct width, the code has a smaller layout of the same data.

The next step i would like to figure out would be how to send a data responce update from the device, or if that is even possible, instead of a timed refresh update.

Ex. After the recording is converted to a file, theta sends a update of some sorts to post that the updates the users incoming request of active info.

2 Likes

this API command may work to check to see if the camera is ready to take another video. The example is with still image, but it may work with video.

https://developers.theta360.com/en/docs/v2.1/api_reference/protocols/commands_status.html

2 Likes

That is perfect for getting a approximate finish time and also convertion time and speed after the video has been converted then transferred*

Thank you

2 Likes

I found a much easyer way to get the info from the json info.

https://www.w3schools.com/js/tryit.asp?filename=tryjson_parse

Ive decoded json before but this seams to be the easyest way todo so for those following.

1 Like

just a little update, i think i found something that will work nicely.
it decodes “Response” and gets each field.

ADDED automatic loop to get current update,
also doesn’t require the"Response" field as show in the image example,
and now updates every second with added format:

  • uptime:1205
    Device On Time: 0D 0H 20M 5S

possibly make a simple interface?..
endless possibility’s?

** As it appears making a windows based camera interface is a given requirement before I move further with what I am currently working towards.


*current… i havn’t had time to add to it but will try todo so today.

1 Like

I am interested in this as well. My objective is to get the livestream preview from the camera in to electron and then view it in an Occulus headset using either Google VR or A-Frame. I think A-Frame and electron work together, but I am not sure.

Do you have a GitHub repo for this setup yet?

3 Likes

There is a gethub for this forum, but I have not posted one for what I am working on yet.
I’m currently just trying to setup a order of getting the info that possible to get from the theta to a easyer to use format.

1 Like

How are you connecting Electron to the Oculus headset? Are you using Oculus Rift or Oculus Go?

5 posts were split to a new topic: Wireless Streaming to VR Headset With On-Premise Equipment

@Kev091190 Did you ever find a JavaScript package that works with Digest Authentication with the THETA? I’m also curious about a package that can do discovery and find the IP address of the camera in client mode.

I have not found the solution yet… just getting back into the project i was working on…

i have found out some usefull info…

using cmd
below code finds the ipadress by using the devices mac address…
**(Replace DeviceMACAddress with your devices mac address)
arp -a | find “DeviceMACAddress”
Responce:
192.168.X.XXX DeviceMACAddress dynamic

then using cmd to ping the address to verify its connected
**(Replacing 192.168.X.XXX with shown device ip)
ping “192.168.X.XXX”

if responce is
" Reply from 192.168.X.XXX: bytes=XX time=Xms TTL=XX "
your device is active
else
" Ping request could not find host DeviceMACAddress. Please check the name and try again. "
failed connection

Sadly you cannot use JavaScript to do this…
(well only idea id have to use JavaScript this way is to try and discover the devices ip address based on if it can connect to the web page and get a response… but you would have to scan through 254 pages and if your devices ip address has a layout as show with a number above 2 in the third column (192.168.2.50),
then you would have to scan through 254 pages per each number until you stop scanning though.

Example i want to search from 192.168.1.1 to 192.168.2.254 thats about 508 web pages to scan through to find one that connects to http://192.168.X.XXX/osc/info/ .)

Im sure with some work in making a cmd script i could find these values and make it return to a text file a response with the address,mac address, Status

I hope this is some help to others.

@Kev091190, thanks for the update.

There’s a way to set the IP address of the THETA V/Z1 so that when it goes into client-mode, it goes to a known IP address.

First, coonnect to the camera in AP mode. Then send this:

  name: "camera._setAccessPoint",
  parameters: {
    "ssid": config.ssid,  // change to string for your ssid
    "security": "WPA/WPA2 PSK",
    "password": config.password,  // set string to the password of your router
    "connectionPriority": 1,
    "ipAddressAllocation": "static",
    "ipAddress": "192.168.2.123",
    "subnetMask": "255.255.255.0",
    "defaultGateway": "192.168.2.1"

After that, reboot the camera and the client-mode IP address will be saved. Now, you can go back to that IP address from your Electron app.

According to the documentation for request, it supports Digest authentication, but I have not been able to get it to work yet.

Digest authentication is supported, but it only works with sendImmediately set to false ; otherwise request will send basic authentication on the initial request, which will probably cause the request to fail.

Application in Electron which you can use to control the Theta, paste the url for a YouTube stream and my application starts a new stream with OBS. But the problems already start by choosing the right API.
I am going to use Windows, this pc is connected to the internet with ethernet and activates a hotspot where the Theta can connect to in client mode.
The live stream to OBS will be going over a USB cable but when I connect the Theta to a pc the wifi gets disabled (I read this already in your post here). Is there a workaround for this?

No, you can’t send WiFi API commands to the THETA when it is streaming through the USB cable. You can send USB API commands to control the stream.

I’m still testing on a Theta V but I will be using the Theta Z1 for the final project. I will have the Z1 in a few days and I don’t know yet if the it also disables the wifi on USB connection.

I do not think you can use the Wi-Fi API while the THETA Z1 is streaming over the USB cable. You can use the USB API with the USB cable and the stream will work.

You can stream over Wi-Fi. One of the easier solutions is to use the RICOH THETA LiveView, however that will not generate the FPS you need for streaming to YouTube. This Wi-Fi plug-in can stream to YouTube.

It sounds like your application would benefit from the USB API.

  • Is it possible to have client mode always enabled on the Theta V or Z1?

You can leave the THETA in client mode 24/7 and it will stay up if you disable sleep and shutdown. You can do this with the API.

  • Can I use the USB for the stream in OBS and the Web API for commands simultaneously?

No.

  • Alternatively how can I use the full USB API with Electron?
  1. Use existing library for PTP on the desktop. For Linux, it is libptp
  2. Use Electron child process to run the shell command from Electron (It will run the host command line script) Child process | Node.js v21.4.0 Documentation

On Windows Desktop, look at WpdMtp.

  • Also, do I need to be a real professional to make this work? Its my first Electron app and I’m still in secondary school.

Get it working from a shell script first and then do the GUI with Electron later. This developer was in high school too. His application didn’t stream.

If you divide your project into small steps and test each step, you can do it. The streaming and the USB API access (with existing library) are controlled by components other people built, so you should be able to glue the components together with JavaScript and Electron.

The primary difficulties you will encounter:

  1. there’s no example using the USB API with Electron, but you should be able to find some from the command line, then you just need to practice using sub-process (I think called child process in Electron) . With this technique, you should be able to use an command line example that someone else built and then adapt it for your specific application
  2. There are more examples on this forum of using the USB API with Linux (on Raspberry Pi), but I believe there are people using Windows. Please help out the community and document your work with Windows and the USB API.
    Translate this from Japanese to your language.

I think I can take care of the OBS part (OBS settings are in JSON format) but I was wondering if you could share your thoughts and experience with me about the Theta.

Feel free to ask more questions.

1 Like

thank you so much but i still have a proplem when i test the application i got error ((require is undefinde))

in first line im index.js

what can i doing??

this one is more recent.

Example with GET

import fetch from 'node-fetch';

// basic info with get
const response = await fetch('http://192.168.1.1/osc/info');
const body = await response.text();

console.log(body);

Response

$ node javascript-test.js 
{"api":["/osc/info","/osc/state","/osc/checkForUpdates","/osc/commands/execute","/osc/commands/status"],"apiLevel":[2],"_bluetoothMacAddress":"58:38:79:03:0C:47","endpoints":{"httpPort":80,"httpUpdatesPort":80},"firmwareVersion":"2.01.0","gps":false,"gyro":true,"manufacturer":"RICOH","model":"RICOH THETA Z1","serialNumber":"10010104","supportUrl":"https://theta360.com/en/support/","uptime":16258,"_wlanMacAddress":"58:38:79:03:17:06"}

Example with POST

Same code as above. Just change the line with the request.

// camera state with POST
const response = await fetch('http://192.168.1.1/osc/state', 
  {method: 'POST', body: {}});

response

$ node javascript-test.js 
{"fingerprint":"FIG_0015","state":{"_apiVersion":2,"batteryLevel":0.99,"_batteryState":"charged","_cameraError":["COMPASS_CALIBRATION"],"_captureStatus":"idle","_capturedPictures":0,"_compositeShootingElapsedTime":0,"_function":"normal","_latestFileUrl":"","_mySettingChanged":false,"_pluginRunning":false,"_pluginWebServer":true,"_recordableTime":0,"_recordedTime":0,"storageUri":"http://192.168.1.1/files/150100524436344d42013765da9bc400/"}}

Example POST with body

same as above with different response

  // example command
  const response = await fetch('http://192.168.1.1/osc/commands/execute', 
  {method: 'POST', body: 
  JSON.stringify({
    name: 'camera.takePicture'
  }),
  headers: {'Content-type': 'application/json; charset=UTF-8'},
});  

Example with POST, body and parameters

// example to set option
const response = await fetch('http://192.168.1.1/osc/commands/execute', 
{method: 'POST', body: 
JSON.stringify({
  name: 'camera.setOptions',
  parameters: {
    options: {
      _filter : 'hdr'
    }
  }
}),
headers: {'Content-type': 'application/json; charset=UTF-8'},
});  

response

$ node javascript-test.js 
{"name":"camera.setOptions","state":"done"}

get multiple options from camera

// example to get options
const response = await fetch('http://192.168.1.1/osc/commands/execute', 
{method: 'POST', body: 
JSON.stringify({
  name: 'camera.getOptions',
  parameters: {
    optionNames: [
      '_filter',
      'sleepDelay',
      'offDelay',
      'videoStitching',
      '_visibilityReduction',
    ]
  }
}),
headers: {'Content-type': 'application/json; charset=UTF-8'},
});  

response

$ node javascript-test.js 
{"name":"camera.getOptions","results":{"options":{"_filter":"hdr","offDelay":0,"sleepDelay":65535,"videoStitching":"none","_visibilityReduction":"OFF"}},"state":"done"}