WebGL Video 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="control">
<span id="text"></span>
<br>
<button id="play" onclick="playAgain()">Play Again</button>
</div>
<div id="video-container" style="width: 100vw; height: 100vh;">
<canvas id="glcanvas"></canvas>
</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
// get DOM elements
canvas = document.getElementById('glcanvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// load the video, and play on ready
var url = "https://files.panomoments.com/longGOP60fps_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";
download();
function download() {
fetch(url).then(function(response) {
response.blob().then(function(myBlob) {
video.src = window.URL.createObjectURL(myBlob);
});
});
}
function playAgain() {
download();
}
video.addEventListener('canplaythrough', (event) => {
console.log("Playing.")
video.play();
if (!animating) 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 error occurred compiling the shaders: " + gl.getShaderInfoLog(result));
return null;
}
return result;
};
fragmentShader = getShaderByName(params.fragmentShaderName);
vertexShader = getShaderByName(params.vertexShaderName);
...