Playing video in ar with 8th wall on iOS

So i have an app built with 8th wall which has a video that plays.
Everything works great on android but when i try it on iOS the video does not play. If I turn off the one script from 8th wall it works (ofcourse not in the AR environment). I can jump to different sections of the video but it stays on that frame. so i see that it is getting the video data.
I posed this question to 8th wall because it seems to be something it there code but wanted to see if anyone could see a quick conflict.
Here is the one script I am turning on/off
off everything works great
on video does not play

/*jshint esversion: 6, asi: true, laxbreak: true*/

// xrcontroller.js: Opens the browser's web camera and runs AR. Attach this to an entity in the
// PlayCanvas scene.

var xrcontroller = pc.createScript('xrcontroller')

// Optionally, world tracking can be disabled to increase efficiency when tracking image targets.
xrcontroller.attributes.add('disableWorldTracking', {type: 'boolean'})

// Optionally, add a material to this script to make it a transparent shadow receiver, which is
// very helpful for producing a good AR effect.
xrcontroller.attributes.add('shadowmaterial', {type: 'asset'})

//xrcontroller.attributes.add('loading Icon', {type: 'asset'})


xrcontroller.prototype.initialize = function() {
  const disableWorldTracking = this.disableWorldTracking

  // After XR has fully loaded, open the camera feed and start displaying AR.
  const runOnLoad = ({pcCamera, pcApp}, extramodules) => () => {
    XR8.xrController().configure({disableWorldTracking})
    XR8.PlayCanvas.runXr({pcCamera, pcApp}, extramodules)
  }

  // If a shadow material was given, apply the appropriate shaders.
  // if (this.shadowmaterial) {
  //   XRExtras.PlayCanvas.makeShadowMaterial({pc, material: this.shadowmaterial})
  // }

  // Find the camera in the playcanvas scene, and tie it to the motion of the user's phone in the
  // world.
  const pcCamera = XRExtras.PlayCanvas.findOneCamera(this.entity)

 
  
  // While XR is still loading, show some helpful things.
  // Almost There: Detects whether the user's environment can support web ar, and if it doesn't,
  //     shows hints for how to view the experience.
  // Loading: shows prompts for camera permission and hides the scene until it's ready for display.
  // Runtime Error: If something unexpected goes wrong, display an error screen.

//uncomment  
  XRExtras.Loading.showLoading({onxrloaded: runOnLoad({pcCamera, pcApp: this.app}, [
    // Optional modules that developers may wish to customize or theme.
    XRExtras.AlmostThere.pipelineModule(),       // Detects unsupported browsers and gives hints. 
    XRExtras.Loading.pipelineModule(),           // Manages the loading screen on startup.
    XRExtras.RuntimeError.pipelineModule(),      // Shows an error image on runtime error.
  ])})
  
  
    
//   const loadBackground = document.querySelector('#loadBackground')

//   if (loadBackground) {
//     loadBackground.style.backgroundColor = '#FFFFFF'
//   }

    
}

How are you playing the video? Are you rendering to a texture?

yes it is rendering to a texture. here are my scripts.

videoTextures.js

var VideoTextures = pc.createScript('videoTextures');


VideoTextures.attributes.add('video', {
    title: 'Video',
    type: 'asset'
});

VideoTextures.attributes.add('playEvent', {
    title: 'Play Event',
    type: 'string',
    default: ''
});


// initialize code called once per entity
VideoTextures.prototype.initialize = function() { 
     
    this.videoIndex = 0;
    
    this.app.on('vt:nextVideo', function (event) {
        this.videoIndex++;
    }, this);   
    
    
    var app = this.app;
    
    var videoPhone = document.createElement('video');
    videoPhone.muted = true;
    videoPhone.autoplay = true;
    videoPhone.crossOrigin = 'anonymous';
    videoPhone.loop = true;


    videoPhone.muted = true;

    videoPhone.playsInline = true;

    videoPhone.src = this.video.getFileUrl();
    
    var style = videoPhone.style;
    style.width = '1px';
    style.height = '1px';
    style.position = 'absolute';
    style.opacity = '0';
    style.zIndex = '-1000';
    style.pointerEvents = 'none';
    
    document.body.appendChild(videoPhone);
    
    this.videoTexture = new pc.Texture(app.graphicsDevice, {
        format: pc.PIXELFORMAT_R8_G8_B8,
        minFilter: pc.FILTER_LINEAR_MIPMAP_LINEAR,
        magFilter: pc.FILTER_LINEAR,
        addressU: pc.ADDRESS_CLAMP_TO_EDGE,
        addressV: pc.ADDRESS_CLAMP_TO_EDGE,
        mipmaps: true,
        autoMipmap: true
    });
    this.videoTexture.setSource(videoPhone);

    videoPhone.addEventListener('canplay', function (e) {
        app.fire(this.playEvent, this.videoTexture);
    }.bind(this));
    
    this.app.on('vt:resetVideoIndex', function(){
        this.videoIndex=0;
    }.bind(this));
    
    
    this.videoHolder = videoPhone;
};

// update code called every frame
VideoTextures.prototype.update = function(dt) {

    if(this.videoIndex === 0){
        if(this.videoHolder.currentTime > 4.08){
            this.videoHolder.currentTime = 0;
        }
    }
    
    else if(this.videoIndex === 1){
        this.videoHolder.currentTime = 4.08;
        this.videoIndex++;
    }
    
    else if(this.videoIndex === 2){
        if(this.videoHolder.currentTime > 7.09){
            this.videoHolder.currentTime = 6.28;
        }
    }
    
    else if(this.videoIndex === 3){
        this.videoHolder.currentTime = 7.09;
        this.videoIndex++;
    }
    
    else if(this.videoIndex === 4){
        if(this.videoHolder.currentTime > 13.17){
            this.videoHolder.currentTime = 10.65;
        }
    }
    
    else if(this.videoIndex === 5){
        this.videoHolder.currentTime = 13.17;
        this.videoIndex++;
    }
    
    else if(this.videoIndex === 6){
        if(this.videoHolder.currentTime > 16.20){
            this.videoHolder.currentTime = 15.80;
        }
    }
    
    else if(this.videoIndex >= 7){
        this.videoHolder.currentTime = 0;
        this.videoIndex = 0;
    }
    
    
    this.videoTexture.upload();    
};

and PhoneScreen

var PhoneScreen = pc.createScript('phoneScreen');



PhoneScreen.attributes.add('screenMaterial', {
    title:'Screen Mat',                          
    type: 'asset',
    assetType: 'material'  
});

PhoneScreen.attributes.add('playEvent', {
    title:'Play event',
    type:'string',
    default: ''             
});


PhoneScreen.prototype.initialize = function() {
    
    this.app.on(this.playEvent, function (videoTexture){
        var material = this.screenMaterial.resource;
        material.emissiveMap = videoTexture;
        material.update();
    }, this);
       
};

so i console logged this.videoHolder.currentTime and on iOS it counts up untill i say use camera for 8th wall and then it stops at that frame and does not count anymore

looks as though iOS pauses the video when requesting for camera access and never resumes play.

2 Likes

Sounds like iOS Safari specific behaviour :thinking: https://stackoverflow.com/questions/48279581/video-stream-is-paused-in-ios-safari-11-webrtc-getusermedia-when-in-background

This explains the issue you are having as the camera access is a getusermedia call right?