Is there a way to switch between front and back cameras mid application

1.5k Views Asked by At

I am trying to develop a web-ar experience that allows the user to switch between front and back cameras throughout the experience, while utilizing SLAM/6dof while using the back camera. Ideally I'd like to use PlayCanvas, but was unable to get the front camera to work. I have had some mild success implementing this in a-frame, but many things are breaking.

I couldn't find any PlayCanvas specific documentation on enabling the front camera, and using XR.stop(), followed by XR.run({canvas: document.getElementById('camerafeed'), cameraConfig: {direction: XR.XrConfig.camera().FRONT}}) didn't have any effect.

Within a-frame I am doing a similar sequence of events, but I am seeing some results. The front camera gets activated, but there are errors in the log, 3D objects don't render(they render when we start in front camera mode), and trying to switch cameras again displays the "Oops, something went wrong!" screen.

As for toggling the SLAM/6dof I keep getting an error that I can not change disableWorldTracking after XR.run has been executed. Even if I have run the XR.stop function and listened for the stopxr event.

A-frame functionality that is supposed to switch to the front camera(just the important bits):

init: function() {
this.el.sceneEl.addEventListener('stopxr', event => {
      console.log("AR has been stopped.");
      const videoCanvas = document.querySelector('canvas.a-canvas');
      XR.XrController.configure({disableWorldTracking: true});
      XR.run({canvas: videoCanvas, cameraConfig: {direction: XR.XrConfig.camera().FRONT}});
    });
},

switchToFace: function() {
    this.el.sceneEl.emit('stopxr');
    //XR.stop();
  },

What is the proper way to change the disableWorldTracking parameter while the scene is running? What is the proper way to alternate between front and back camera while the scene is running?

2

There are 2 best solutions below

0
On BEST ANSWER

After talking with an 8th wall dev they confirmed that they only support a single XR session per page, so after XR.stop, XR.run can’t be called again. However there is another way to switch between front and back camera, and it works with SLAM enabled.

  1. Listen to the onCameraStatusChange event and grab references to the stream and video elements.
  2. When initiating the camera swap, pause 8th wall using XR.pause().
  3. Stop all the tracks in the stream you grabbed from step one.
  4. Use navigator.mediaDevices.getUserMedia(constraints); to get the stream for the desired camera.
  5. Assign the new stream to the video element you grabbed in step 1.
  6. Listen for the video element to fire the playing event, and call XR.resume();

One thing to note: SLAM will only work if you are starting with the back camera. After switching to the front camera and back SLAM will no longer be working.

0
On

It's now possible to stop and resume XR sessions (as of the 13.1 release from a while back). You can call XR8.stop(), followed by XR8.run() and pass in the new desired camera direction.

If you are using 8th Wall in an AFrame project, you can simply remove the xrweb component from your <a-scene> to stop XR, and then add it back (with a new cameraDirection param, if desired) to restart.

Here are a few projects that illustrate how to flip the camera direction:

https://www.8thwall.com/8thwall/camera-shaders

https://www.8thwall.com/playground/swap-dof