Skip to content

Instantly share code, notes, and snippets.

@atwong
Last active August 16, 2023 10:08
Show Gist options
  • Select an option

  • Save atwong/49b9e7d911dca0663e23c50c60f28784 to your computer and use it in GitHub Desktop.

Select an option

Save atwong/49b9e7d911dca0663e23c50c60f28784 to your computer and use it in GitHub Desktop.

Revisions

  1. atwong revised this gist Oct 1, 2018. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions extractvideo.js
    Original 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) {
  2. atwong revised this gist Oct 1, 2018. 1 changed file with 16 additions and 5 deletions.
    21 changes: 16 additions & 5 deletions extractvideo.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,14 @@
    function extractVideoFrames(vidUrl, frOffsets) {
    /*
    * 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 frames = {};
    var lastP = null;

    for (var offset of offsets) {
    if (offset < video.duration) {
    if (lastP) {
    var f = await lastP
    frames.push(f);
    frames[f.offset] = f;
    }
    lastP = extractFrame(video, canvas, offset);
    }
    }
    if (lastP) {
    frames.push(await 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 = 1280;
    vcnv.width = frameWidth !== undefined ? frameWidth : vvid.videoWidth;
    vcnv.height = vcnv.width/aspect_ratio;
    if (vvid.duration) {
    serialExtractFrames(vvid, vcnv, frOffsets).then(resp => {
  3. atwong created this gist Oct 1, 2018.
    55 changes: 55 additions & 0 deletions extractvideo.js
    Original 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;