Created
August 20, 2019 08:40
-
-
Save schmidtsonian/a2da2a60912a09009235fa7ea3660084 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://stackoverflow.com/a/52357595/2690846 | |
// usage: let frames = await extractFramesFromVideo("https://example.com/video.webm"); | |
async extractFramesFromVideo(videoUrl: string, fps=3) { | |
return new Promise(async (resolve) => { | |
// fully download it first (no buffering): | |
let videoBlob = await fetch(videoUrl).then(r => r.blob()); | |
let videoObjectUrl = URL.createObjectURL(videoBlob); | |
let video = document.createElement('video'); | |
let seekResolve; | |
video.addEventListener('seeked', async function() { | |
if(seekResolve) seekResolve(); | |
}); | |
video.src = videoObjectUrl; | |
// workaround chromium metadata bug (https://stackoverflow.com/q/38062864/993683) | |
while((video.duration === Infinity || isNaN(video.duration)) && video.readyState < 2) { | |
await new Promise(r => setTimeout(r, 1000)); | |
video.currentTime = 10000000*Math.random(); | |
} | |
let duration = video.duration; | |
let canvas = document.createElement('canvas'); | |
let context = canvas.getContext('2d'); | |
let [w, h] = [video.videoWidth, video.videoHeight] | |
canvas.width = w; | |
canvas.height = h; | |
let theFrames: string[] = []; | |
let interval = 1 / fps; | |
let currentTime = 0; | |
while(currentTime < duration) { | |
video.currentTime = currentTime; | |
await new Promise(r => seekResolve=r); | |
if (context) { | |
context.drawImage(video, 0, 0, w, h); | |
let base64ImageData = canvas.toDataURL(); | |
theFrames.push(base64ImageData); | |
} | |
currentTime += interval; | |
} | |
resolve(theFrames); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment