rAF WebGL Video Safari

by dustinkerstein

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/105/three.min.js"></script>
<div id="control">
  <span id="text"></span>
  <br>
  <button id="play" onclick="playAgain()">Play Again</button>
</div>

CSS

body {
  margin: 0;
  padding: 0;
  background-color: #000000; 
  overflow: hidden;
} 
video {
  display:none;
  height: 100vh;
  width: 100vw;
}
span {
  color: white;
  font-size: xx-large;
}
button {
  width: 100px;
  height: 50px;
}
#control {
  height: 10vh;
  z-index: 9999;
  position: absolute;
}

JavaScript

var url = "https://files.panomoments.com/longGOP60fps_dashinit.mp4";
var video, mesh, camera, scene, renderer, texture;
var container = document.createElement('container');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100);
camera.target = new THREE.Vector3(0, 0, 0);
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
video = document.createElement('video');
document.body.appendChild(video);
video.loop = true;
video.autoplay = false;
video.muted = true;
video.crossOrigin = "anonymous";
video.preload = 'auto';
video.setAttribute('playsinline', '');
video.addEventListener('canplaythrough', (event) => {
  console.log("Playing.")
  video.play();
  if (!texture) init();
});

var useRAF = true; // Setting false doesn't replicate
var useBlob = true; // Replicates both true and false.
var showBothCanvasAndVideoTag = false; // Setting false doesn't replicate

if (useRAF) {
  renderer.setAnimationLoop(update);
} else {
  setInterval(update, 1000/60)
}

download();

function download() {
	console.log("Downloading.");
  if (useBlob) {
    fetch(url).then(function(response) {
      response.blob().then(function(myBlob) {
        video.src = window.URL.createObjectURL(myBlob);
      });
    });
  } else {
    video.src = null;
    video.src = url;
  }
}

function update() {
  if (texture) {
    document.getElementById("text").innerHTML = "video.readyState: " + video.readyState + "<br>video.paused: " + video.paused + "<br>video.currentTime: " + video.currentTime.toFixed(2) + "<br>texture.version: " + texture.version;
  }
  renderer.render(scene, camera);
}

function init () {
  if (showBothCanvasAndVideoTag) {
    video.style.display = "block";
    video.style.height = "50vh";
    container.childNodes[0].style.height = "50vh";
  } else {
   ...