Skip to content

Instantly share code, notes, and snippets.

@veltman
Last active August 12, 2016 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veltman/9104731edd4c87d0712f98d607a35f7c to your computer and use it in GitHub Desktop.
Save veltman/9104731edd4c87d0712f98d607a35f7c to your computer and use it in GitHub Desktop.
Looping video w/ sound (frame seeking)
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
margin: 0;
padding: 0;
}
</style>
<body>
<div>Loading...</div>
<video width="960" height="500" preload="auto" style="display: none;">
<source src="video.mp4" type="video/mp4">
</video>
<script>
var audioContext = new (window.AudioContext || window.webkitAudioContext)(),
request = new XMLHttpRequest(),
video = document.querySelector("video");
request.responseType = "arraybuffer";
request.open("GET", "llcoolj.wav", true);
// XHR complete
request.onload = function() {
audioContext.decodeAudioData(request.response, success, function(err){ throw err; });
};
// Play video once to ensure fully loaded
video.load();
video.play();
video.addEventListener("ended", send);
// Video has played through once
function send(){
document.querySelector("div").remove();
video.currentTime = 0;
video.removeEventListener("ended", send);
video.style.display = "block";
request.send();
}
function success(buffer) {
var source = audioContext.createBufferSource();
var gainNode = audioContext.createGain();
// Keep it quiet
gainNode.gain.value = 0.1;
source.connect(gainNode);
gainNode.connect(audioContext.destination);
// Set the buffer
source.buffer = buffer;
source.loop = true;
var t0 = audioContext.currentTime,
currentFrame = 0,
fps = 20.09;
source.start(0);
requestAnimationFrame(update);
function update(){
var t = (audioContext.currentTime - t0) % buffer.duration,
newFrame = Math.floor(t * fps);
console.log(t);
console.log(currentFrame, newFrame);
// Only update when frame changes or else things get weird
if (newFrame !== currentFrame) {
currentFrame = newFrame;
video.currentTime = (newFrame / fps) + 1e-5;
console.log((newFrame / fps) + 1e-5);
}
requestAnimationFrame(update);
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment