WebGL Video

Maybe very slow shader. Bad perf on Safari.

by dustinkerstein

HTML

<script id="shader-fs" type="x-shader/x-fragment">
  varying mediump vec2 vDirection;
  uniform sampler2D uSampler;
  void main(void) {
    gl_FragColor = texture2D(uSampler, vec2(vDirection.x * 0.5 + 0.5, vDirection.y * 0.5 + 0.5));
  }
</script>

<!-- Vertex shader program -->
<script id="shader-vs" type="x-shader/x-vertex">
  attribute mediump vec2 aVertexPosition;
  varying mediump vec2 vDirection;
  void main(void) {
    gl_Position = vec4(aVertexPosition, 1.0, 1.0) * 2.0;
    vDirection = aVertexPosition;
  }
</script>

<div id="video-container" style="width: 100vw; height: 100vh;">
  <canvas id="glcanvas"></canvas>
</div>

JavaScript

// get DOM elements
canvas = document.getElementById('glcanvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// load the video, and play on ready
var sourceBuffer;
var ms = new MediaSource();
var index = 0;
var url = "https://files.panomoments.com/uhd_dashinit.mp4";
var video = document.createElement('video');
video.setAttribute('playsinline', '');
video.preload = "auto";
video.muted = true;
video.autoplay = false;
video.loop = true;
video.crossorigin = "anonymous";
video.src = window.URL.createObjectURL(ms);
ms.addEventListener('sourceopen', onMediaSourceOpen);

video.oncanplaythrough = function() {
  //video.play();
  //setInterval( drawScene, 1000 / 60); // If used, make sure to comment out line #19 and line #153
  drawScene();
};


function onMediaSourceOpen() {
  sourceBuffer = ms.addSourceBuffer('video/mp4; codecs="avc1.640033"');
  fetch(url).then(function(response) {
  	response.arrayBuffer().then(function(myArrayBuffer) {
    	sourceBuffer.appendBuffer(myArrayBuffer);
      drawScene();
    });
  });
}

gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");

// create and attach the shader program to the webGL context
var attributes, uniforms, program;
var attachShader = function(params) {
  // compile the shaders from the shaders scripts
  var getShaderByName = function(id) {
    var shaderScript = document.getElementById(id);

    var theSource = "";
    var currentChild = shaderScript.firstChild;

    while(currentChild) {
      if (currentChild.nodeType === 3) {
        theSource += currentChild.textContent;
      }
      currentChild = currentChild.nextSibling;
    }

    var result;
    if (shaderScript.type === "x-shader/x-fragment") {
      result = gl.createShader(gl.FRAGMENT_SHADER);
    } else {
      result = gl.createShader(gl.VERTEX_SHADER);
    }
    gl.shaderSource(result, theSource);
    gl.compileShader(result);

    if (!gl.getShaderParameter(result, gl.COMPILE_STATUS)) {
      alert("An...