I've been learning how to use AR.js and A-Frame to display videos in an AR space, but I've come across the fabled issue with playing videos on an iOS devices.
When researching this issue, I found several threads that presented workarounds. The most common trends were to include <meta name="apple-mobile-web-app-capable" content="yes">
, put playinline
and/or webkit-playinline
in<video>
, and have an interaction from the user to play the video (such as a button press, a screen tap, or et cetera). I also found a library that supposedly handles these issues called iphone-inline-video.
My References:
- https://aframe.io/docs/1.2.0/introduction/faq.html#why-does-my-video-not-play
- https://developer.apple.com/documentation/webkit/delivering_video_content_for_safari
- https://github.com/aframevr/aframe/issues/1846
- https://github.com/aframevr/aframe/issues/316#issuecomment-183006679
- https://github.com/misterburton/ideo-sf-vr-nerd-night#bonus-points
- Can't play video texture under a-frame framework on iPhone
- Why is my video or videosphere not playing on mobile in A-Frame VR?
However, none of their solutions worked with my code. Looking through my research, a lot of the posts were rather dated, so I wanted to know if there has been any new knowledge at tackling this issue? If not, does anyone know why the commonly suggested workarounds don't work in my example (am I using them incorrectly)?
EDIT: Also, I'm testing this on an iPhone 6s with iOS 13.4.1
My code (HTML):
<!DOCTYPE html>
<html>
<head>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta charset="UTF-8">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
<script src="js/iphone-inline-video.min.js"></script>
<script src="js/script.js" defer></script>
<script>
//Loads Videos
AFRAME.registerComponent("vidloader", {
init: function () {
this.materialLoaded = this.materialLoaded.bind(this);
console.log("init");
// wait until the material is ready
this.el.addEventListener("loaded", this.materialLoaded);
},
materialLoaded: function () {
// grab the material
let material = this.el.getObject3D("mesh").material;
console.log(material.map.format);
// swap the format
material.map.format = THREE.RGBAFormat;
material.map.needsUpdate = true;
console.log(material.map);
},
remove: function () {
this.el.removeEventListener("loaded", this.materialLoaded);
},
});
// Handles Playing/Pausing (User must tap the screen once for the video[s] to play)
// Set up for multiple markers+videos later...
AFRAME.registerComponent('vidhandler', {
schema: {
videos: { type: 'string' }
},
init: function () {
this.clickCheck = false
this.videoNodes = document.querySelectorAll(this.data.videos)
document.body.addEventListener("click", e => {
this.clickCheck = true
});
},
//Handles playing marker-specifc videos
tick: function () {
if (this.el.object3D.visible == true) {
if (!this.toggle && Boolean(this.clickCheck)) {
this.toggle = true;
for (let i = 0; i < this.videoNodes.length; i++) {
this.videoNodes[i].play();
}
}
} else {
if (this.toggle) {
for (let i = 0; i < this.videoNodes.length; i++) {
this.videoNodes[i].pause();
}
this.toggle = false;
this.clickCheck = false
}
}
}
});
</script>
</head>
<body style="margin : 0px; overflow: hidden;">
<a-scene
vr-mode-ui="enabled: false"
embedded
arjs>
<a-assets>
<video
id="bunny-vid"
loop="true"
crossorigin="anonymous"
src="https://cdn.glitch.com/f8908c29-7a4c-455b-93ca-6172548f04c2%2FBig_Buck_Bunny_Trailer_1080p.ogv.360p.vp9.webm?v=1566582340300"
playsinline
webkit-playsinline
></video>
</a-assets>
<a-marker preset='hiro' vidhandler='videos: #bunny-vid'>
<a-video
vidloader
width="1.32"
height="1"
rotation="270 0 0"
position="0 0.10 0"
src="#bunny-vid"
material="transparent: true"
></a-video>
</a-marker>
<a-entity camera></a-entity>
</a-scene>
</body>
</html>