ScreenRecorder and cropping videos

When using ScreenRecorder and high resolution canvases I noticed that I get this kind of cropping messages

Why does this happen? Also, on the same topic, what is your favorite way of exporting HD videos?

Hi :slight_smile:

The cropping happens because some video codecs require resolutions that are multiple of 2 (or was it multiple of 4?). Some monitors are (or report) odd resolutions.

I haven’t found the ideal codec yet as I prefer to run it live. I know HAP is popular. Maybe we can add a profile for it. With the default settings h264 there’s quite some quality loss of the kind of visuals I produce.

Update: here’s the ffmpeg HAP instructions: HAP Codecs It should be easy to create a profile for it. The chunks parameter should be configurable and set to the numbers of CPU cores or less.

1 Like

Oh, I see. I forgot to mention that I get this message also when I save frames one by one. How does one get then frames for arbitrary resolutions?

This would be quite cool, yes.

Ah you mean you are using the ScreenRecorder to save frames one by one (as TIFF for example) and it resizes the frames? What file format are you using? Probably the resolution check is not currently format-dependent. Maybe the video profiles could implement a verticalResolutionMultipleOf property, and then set it only to 2 or 4 for h264, h265 and leave it at 1 for TIFF or other images.

Or use the Screenshots extension to save images?

I was using .png files, and it gives that message.

I thought the Screenshots extension works for key interaction. Probably it can be activated at the end of the extend loop?

UPDATE: I tried directly something like this

rt.colorBuffer(0).saveToFile(File("frames/frame-${frame.toString().padStart(5, '0')}.png"))
frame += 1

and I still get the cropping, though no message is outputed.

I finally managed to produce a 1920 x 1080 render, here’s an example

This has been possible thanks to a conversation I had with @abe at the Creative Code Berlin code jam.
Here’s what I have learned and some suggestions if you are facing the same issue:

  • Create variables w and h containing your desired resolution and use them everywhere you would use width and height, since these get updated after the screensize crops (print drawer.width and drawer.height to see that);
  • Render on a render target with dimensions w and h;
  • Draw explicitly to Rectangle(0.0, 0.0, w * 1.0, h * 1.0) inside the drawer.isolateWithTarget() session;
  • When saving the render target’s buffer to file via rt.colorBuffer(0).saveToFile(...) make sure to set async= false: this will deallocate resources that .saveToFile internally uses and avoid memory crash;
  • If you use a fragment shader inside shadestyle, do not use c_boundsPosition for your normalized coordinates, but rather pass a resolution variable containing the resolution, for instance parameter("resolution", Vector2(w * 1.0, h * 1.0)), and define your normalized coordinates via c_screenPosition/p_resolution (in case, make sure you obtain the correct aspect ratio by scaling the uv variable).

The last point was fairly tricky to realize, and this happened after chasing a weird visual effect and some testing. :slight_smile:

1 Like

I like your video! :slight_smile:

I wanted to add some details:

Your screen is 1920x1080 but somewhere it was reporting 1920x1061. I thought it might have been missing 19 pixels for the task bar. This was on Windows. On my Linux I could export sizes larger than the screen without issues. Is the whole issue caused by the height variable is always smaller than expected? Or was it the case that it also didn’t allow buffers larger than the screen?

OPENRNDR uses LWJGL which uses GLFW which is probably responsible for the window height.

I think it’s not exactly that saveToFile with async = false deallocates resources (it always does), but more that when you use that option, the program stops until it’s done saving the requested image so it deals with one image at a time without growing a queue. When the option is true (the default) the program runs at full speed (60 fps) but saving happens much slower (specially because of the PNG file format). Each time the method is called it reserves memory to hold a copy of the requested image until it eventually runs out of memory.

1 Like

This was exactly the point: saved buffer was 1920×1080, but the fact that height is always smaller creates the artifact when saving the buffer to file. I think it might have to do with the bounding box dimension that is used to compute c_boundsPosition. Using c_screenPosition avoids this.

Aaah, right! I got confused, it’s the queue that grows, indeed :slight_smile: