MSE Three.js Append Full Play

by dustinkerstein

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<video id="video"></video>
<div id="container"></div>

CSS

video {
  width: 100vw;
  height: 100vh;
}

JavaScript

var sourceBuffer, container, mesh, camera, scene, renderer, texture;
      
var url = "https://files.panomoments.com/sd60fps1x1_dashinit.mp4"; // 1024x1024 DAR 1:1 60fps 100% I-Frames
// var url = "https://files.panomoments.com/hd60fps1x1_dashinit.mp4"; // 2048x2048 DAR 1:1 60fps 100% I-Frames
// var url = "https://files.panomoments.com/uhd60fps16x9_dashinit.mp4"; // 3840x2160 DAR 16:9 60fps 100% I-Frames

var video = document.getElementById('video');
video.autoplay = true;
video.loop = true;
video.muted = true;

var ms = new MediaSource();
ms.addEventListener('sourceopen', onMediaSourceOpen);

// Test 4 combinations
var enableWebGL = true; 
var enableMSE = true; // Will only work on Safari with the above test files due to MSE buffer quota limits. Also when False, you may run into degraded performance due to https://bugs.webkit.org/show_bug.cgi?id=211295

/*
Note that rates don't imply successful full fps rendering, only that playback isn't entirely frozen.

Safari on 2011 Macbook Pro - Max playbackRate with 1024x1024 file:
enableWebGL = false, enableMSE = false - Breaks permanently at loop point if rate >1 && <= 2.0, but if started at >2.0 it breaks around 40 (seems to be due to frameskipping logic based on higher playback rates - seems only enabled for non-MSE path) and can recover
enableWebGL = false, enableMSE = true - Breaks permanently at loop point around 8
enableWebGL = true, enableMSE = false - Breaks permanently at loop point if rate >1 && <= 2.0, but if started at >2.0 it breaks around 40 (seems to be due to frameskipping logic based on higher playback rates - seems only enabled for non-MSE path) and can recover
enableWebGL = true, enableMSE = true - Breaks permanently around 0.1 and breaks render loop (ie. tab frozen)
*/

if (enableWebGL) {
  console.log("WebGL Enabled.");
  video.style.display = 'none';
  container = document.getElementById('container');
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100);
 ...