Full Webpage Screenshot using getDisplayMedia() of MediaDevices API

1.9k views Asked by At

I am using navigator.mediaDevices.getDisplayMedia to get a screenshot, but it's capturing the only the visible part of the page but there is more content which is hidden in scroll area and which is getting missed. So can it be possible to capture the full page?

   function getDisplayMedia(options) {
        if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
            return navigator.mediaDevices.getDisplayMedia(options)
        }
        if (navigator.getDisplayMedia) {
            return navigator.getDisplayMedia(options)
        }
        if (navigator.webkitGetDisplayMedia) {
            return navigator.webkitGetDisplayMedia(options)
        }
        if (navigator.mozGetDisplayMedia) {
            return navigator.mozGetDisplayMedia(options)
        }
        throw new Error('getDisplayMedia is not defined')
    }

    async function takeScreenshotStream() {
        const width = screen.width * (window.devicePixelRatio || 1)
        const height = screen.height * (window.devicePixelRatio || 1)

        const errors = [];
        let stream;
        const mediaStreamConstraints = {
            audio: false,
            video: {
                width,
                height,
                frameRate: 1,
            },
        };

        try {
            stream = await getDisplayMedia(mediaStreamConstraints)
        } catch (ex) {
            errors.push(ex)
        }

        if (errors.length) {
            console.debug(...errors)
            if (!stream) {
                throw errors[errors.length - 1]
            }
        }

        return stream
    }

    async function takeScreenshotCanvas() {
        const stream = await takeScreenshotStream()
        const video = document.createElement('video')
        const result = await new Promise((resolve, reject) => {
            video.onloadedmetadata = () => {
                video.play()
                video.pause()
                const canvas = document.createElement('canvas');
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                const context = canvas.getContext('2d')
                context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight)
                resolve(canvas)
            }
            video.srcObject = stream
        })

        stream.getTracks().forEach(function (track) {
            track.stop()
        })

        if (result == null) {
            throw new Error('Cannot take canvas screenshot')
        }

        return result
    }

    document.body.onclick = async () => {
        const canvas = await takeScreenshotCanvas()
        document.getElementById("screenshot-preview").src = canvas.toDataURL(); 
    }

I tried using Html2Canvas and dom-to-image which take full page screenshot but they have their own drow back like they don't capture iframe, SVG, etc.

Any help will be highly appreciated.

0

There are 0 answers