Video.js: Take snapshot from video

Created on 26 Sep 2017  路  5Comments  路  Source: videojs/video.js

I am trying to capture the snapshot from the video, but giving the error

TypeError: Argument 1 of CanvasRenderingContext2D.drawImage could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, ImageBitmap.

Here is the code,

<video id=my-video width=500 height=400 class="video-js vjs-default-skin" controls>
  <source
     src="https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8"
     type="application/x-mpegURL">
</video>
<script src="video.js"></script>
<script src="videojs.hls.min.js"></script>
<script>
var player = videojs('my-video');
player.play();
</script>

<button id="snap" onclick="snap2()">Take screenshot</button>
<a id="downlink"  style="display:none;" download="screenshot"> </a>

    <script>
       function snap2(){
        var frame = captureVideoFrame('my-video', 'png');
                var myImage = frame.dataUri;
        var link = document.getElementById("downlink");
        link.download = "screenshot.png";
        link.href = myImage;
        link.click();   

       }

    </script>

And the JS part

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else {
        root.captureVideoFrame = factory();
    }
}(this, function () {
    return function captureVideoFrame(video, format) {
        if (typeof video === 'string') {
            video = document.getElementById(video);
        }

        format = format || 'jpeg';

        if (!video || (format !== 'png' && format !== 'jpeg')) {
            return false;
        }

        var canvas = document.createElement("CANVAS");

        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;

        canvas.getContext('2d').drawImage(video, 0, 0);

        var dataUri = canvas.toDataURL('image/' + format);
        var data = dataUri.split(',')[1];
        var mimeType = dataUri.split(';')[0].slice(5)

        var bytes = window.atob(data);
        var buf = new ArrayBuffer(bytes.length);
        var arr = new Uint8Array(buf);

        for (var i = 0; i < bytes.length; i++) {
            arr[i] = bytes.charCodeAt(i);
        }

        var blob = new Blob([ arr ], { type: mimeType });
        return { blob: blob, dataUri: dataUri, format: format };
};
}));

Is there any way to accomplish to capture the current frame from video,

I am using videojs-contrib-hls to play hls stream.

Most helpful comment

I got it to work with this change:

context.drawImage(video.children_[0], 0, 0, canvas.width, canvas.height);

Worked with Desktop Chrome 67 and Android (Chrome 69, Android 8.0.0)

All 5 comments

@harispp How did you solved for video snapshot?
I also got issue like you do.

A common issue, and which is the case with the code sample above, would be trying to capture from the rendered player div element rather than the video element

Im using the same code, how can i capture all the frame? In pc its working well but in android its not working

A common issue

I got it to work with this change:

context.drawImage(video.children_[0], 0, 0, canvas.width, canvas.height);

Worked with Desktop Chrome 67 and Android (Chrome 69, Android 8.0.0)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gfviegas picture gfviegas  路  3Comments

uikoo9 picture uikoo9  路  4Comments

d3x7r0 picture d3x7r0  路  4Comments

pblasi picture pblasi  路  3Comments

stephanedemotte picture stephanedemotte  路  4Comments