Last active
August 16, 2023 10:08
-
-
Save atwong/49b9e7d911dca0663e23c50c60f28784 to your computer and use it in GitHub Desktop.
Revisions
-
atwong revised this gist
Oct 1, 2018 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -6,6 +6,10 @@ * - frameWidth : screenshot width (default: video width) * Returns * - frames: object with offset => {imgUrl, blob} * * An multiple-frame extension of http://cwestblog.com/2017/05/03/javascript-snippet-get-video-frame-as-an-image/ * In this version, video & canvas elements are reused to extract multiple screenshots. Note, video seeks must * occur serially, hence use of async/await. */ function extractVideoFrames(vidUrl, frOffsets, frameWidth) { -
atwong revised this gist
Oct 1, 2018 . 1 changed file with 16 additions and 5 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,14 @@ /* * Extract multiple screenshots/frames from a video URL * Params * - vidURL : video URL * - frOffsets : array of timestamps * - frameWidth : screenshot width (default: video width) * Returns * - frames: object with offset => {imgUrl, blob} */ function extractVideoFrames(vidUrl, frOffsets, frameWidth) { function extractFrame(video, canvas, offset) { return new Promise((resolve, reject) => { @@ -14,20 +24,21 @@ function extractVideoFrames(vidUrl, frOffsets) { }; async function serialExtractFrames(video, canvas, offsets) { var frames = {}; var lastP = null; for (var offset of offsets) { if (offset < video.duration) { if (lastP) { var f = await lastP frames[f.offset] = f; } lastP = extractFrame(video, canvas, offset); } } if (lastP) { var f = await lastP; frames[f.offset] = f; lastP = null; } return frames; @@ -38,7 +49,7 @@ function extractVideoFrames(vidUrl, frOffsets) { var vcnv = document.createElement("canvas"); vvid.onloadedmetadata = event => { var aspect_ratio = vvid.videoWidth/vvid.videoHeight; vcnv.width = frameWidth !== undefined ? frameWidth : vvid.videoWidth; vcnv.height = vcnv.width/aspect_ratio; if (vvid.duration) { serialExtractFrames(vvid, vcnv, frOffsets).then(resp => { -
atwong created this gist
Oct 1, 2018 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,55 @@ function extractVideoFrames(vidUrl, frOffsets) { function extractFrame(video, canvas, offset) { return new Promise((resolve, reject) => { video.onseeked = event => { var ctx = canvas.getContext('2d'); ctx.drawImage(video, 0, 0, canvas.width, canvas.height); canvas.toBlob(blob => { resolve({offset: offset, imgUrl: canvas.toDataURL() , blob: blob}); }, "image/png"); }; video.currentTime = offset; }); }; async function serialExtractFrames(video, canvas, offsets) { var frames = []; var lastP = null; for (var offset of offsets) { if (offset < video.duration) { if (lastP) { var f = await lastP frames.push(f); } lastP = extractFrame(video, canvas, offset); } } if (lastP) { frames.push(await lastP); lastP = null; } return frames; }; return new Promise((resolve, reject) => { var vvid = document.createElement("video"); var vcnv = document.createElement("canvas"); vvid.onloadedmetadata = event => { var aspect_ratio = vvid.videoWidth/vvid.videoHeight; vcnv.width = 1280; vcnv.height = vcnv.width/aspect_ratio; if (vvid.duration) { serialExtractFrames(vvid, vcnv, frOffsets).then(resp => { resolve(resp); }) } } vvid.src = vidUrl; }); }; export default extractVideoFrames;