Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve screen recording dimensions #43

Merged
merged 1 commit into from
Nov 11, 2020
Merged

Conversation

dtinth
Copy link
Contributor

@dtinth dtinth commented Nov 6, 2020

navigator.mediaDevices.getDisplayMedia provides less-than-actual video output, especially for HD, 4K, or HiDPI screen. This results in GIFs that look blurry due to downscaling. Adding this constrain results in original display scale, leading to a crisper output.

Without this PR

recording (1)

With this PR

recording (2)

Userland patch

// ==UserScript==
// @name         Improve gifcap resolution
// @namespace    https://dt.in.th/
// @version      0.1
// @description  Make gifcap capture screen at actual size, resulting in crisper image
// @author       dtinth
// @match        https://gifcap.dev/
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    navigator.mediaDevices.getDisplayMedia = (o => function(...args) {
        args[0].video = { width: 9999, height: 9999 }
        return o.apply(this, args)
    })(navigator.mediaDevices.getDisplayMedia)
})();

`navigator.mediaDevices.getDisplayMedia` provides less-than-actual video output, especially for HD, 4K, or HiDPI screen. This results in GIFs that look blurry due to downscaling. Adding this constrain results in original display scale, leading to a crisper output.
@joaomoreno
Copy link
Owner

But this also makes it produce HUGE (as in bytes) gifs right?

Related to #38

@dtinth
Copy link
Contributor Author

dtinth commented Nov 9, 2020

@joaomoreno Yes, it makes the GIF bigger, but gifcap consistently performs better than other screen recording solutions I've tried. From my research, it seems for gifcap the video input is lossless. This made a huge difference in the resulting size.

Example

This GIF has resolution 1438x714 and is 13.77 seconds.

From gifcap: 209 KB (128.6 Kb/s).

gifexample

For comparison, when I use other GIF screen recorders it usually produces files with bitrate of 1000 Kb/s. So gifcap is performing almost a magnitude better.

Possible further optimization

Since this arguably makes the file size larger (in exchange for better quality gifs), there are ways to reduce size further. Using ffmpeg to optimize: 186 KB (114.46 Kb/s).

ffmpeg -i gifexample.gif \
  -vf 'split[s0][s1];[s0]palettegen=max_colors=256[p];[s1][p]paletteuse=dither=bayer:bayer_scale=4:diff_mode=rectangle' \
  -y gifexample-ffmpeg.gif

gifexample-ffmpeg

Using gif-inspector, it shows that gifcap creates frames with a rectangular area when there is a change.

A frame from gifcap:
image

When optimized with ffmpeg, only pixels that are really changed remains.

The same frame after optimized with ffmpeg:
image

@joaomoreno
Copy link
Owner

joaomoreno commented Nov 9, 2020

Yeah gifcap could optimize further, it currently only does one rectangle per frame:

const box = computeDiff(buffer, this.previousBuffer, this.opts.width);
I would take a PR for optimizing that further!

Anyway, on this PR: can you explain how the 9999 works? I find it strange. 🤔 Is that an upper bound, or?

https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/height

@dtinth
Copy link
Contributor Author

dtinth commented Nov 11, 2020

@joaomoreno The number is the “ideal” dimension, if it cannot be obtained browser just choose the closest value.

If you provide an ideal value, the browser will try to get as close as possible to matching that value, given the other constraints specified. https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints#Example_Constraint_exerciser

I just picked the number 9999 out of thin air 😂

@joaomoreno
Copy link
Owner

But why does it actually change anything? Without specifying it, your browser automatically scales down the media stream? What browser is this? Can you repro on other browsers?

@dtinth
Copy link
Contributor Author

dtinth commented Nov 11, 2020

@joaomoreno Chrome on both MBP Retina (macOS) and Surface Pro 7 (Windows) scales the video down on HiDPI displays. Chrome scales 1080p screens down to 720p by default as well.

Device Constraint Resolution
Surface Pro 7 {} 1368 x 912
Surface Pro 7 {video:{width:1920,height:1080}} 1620 x 1080
Surface Pro 7 {video:{width:9999,height:9999}} 2736 x 1824
MBP Retina {} 1280 x 800
MBP Retina {video:{width:1920,height:1080}} 1728 x 1080
MBP Retina {video:{width:9999,height:9999}} 2560 x 1600
An external 1080p screen {} 1280 x 720
An external 1080p screen {video:{width:9999,height:9999}} 1920 x 1080

https://getdisplaymedia-constraints-tester.glitch.me/

@joaomoreno
Copy link
Owner

So weird. Thanks for the glitch link, really helpful. Also, thanks for the PR!

@joaomoreno joaomoreno merged commit b060ef9 into joaomoreno:master Nov 11, 2020
@dtinth dtinth deleted the patch-1 branch April 9, 2021 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants