nypublicradio / audiogram

Turn audio into a shareable video.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Improve background image performance

veltman opened this issue · comments

Layering a JPG background image into a video seems to hurt the performance a lot (PNGs too, but less so). My guess is that it's from node-canvas re-decoding unnecessarily, can probably fix this by drawing the background image onto a separate Node canvas initially and relayering.

A few initial impressions on this:

  • The rendering code takes a trivial amount of time (a few ms per frame) - almost all of the time is spent on writing the rendered canvas to disk.
  • There's no real difference between a pngStream and using synchronous .toBuffer() in terms of performance.
  • Using an asynchronous .toBuffer() is about 4x faster, but means that we can't render in parallel on the same canvas. This is probably fine
  • Adding compression as a second argument would probably speed it up some more.

One possibility is to create a new Canvas for every frame, rather than a shared one. This would speed up the I/O a lot, but add some overhead for that. The smarter option would probably work is to create a pool of n canvases, where n is the max concurrency, and share them that way.

Tried this with a pool of canvases and async toBuffer() and rendering time is about 4x lower than previously. Will have to test this elsewhere, it may run into memory issues. May also involve refactoring the renderer/ code a bit.

Have a seemingly-working version of this on the refactor branch.

No apparent memory issues, but the performance benefits seem to be contingent on having multiple cores.

Per the above, might want to set the parallelism based on the value of os.cpus(), though it's not clear whether it would hurt anything.

Merged this to master. Should see performance improvements on a multicore machine.