timecut icon indicating copy to clipboard operation
timecut copied to clipboard

Capture speed!

Open rana01645 opened this issue 5 years ago • 17 comments

What's the best config I can follow to make the capture speed fast!

The whole library is awesome but Current capture speed is very slow, it's taking almost 2 minutes to capture a 7-second video, with 30fps.

Thanks in advance

rana01645 avatar Nov 11 '19 16:11 rana01645

Yeah, i'd be very interested to know what we can do to speed things up.

I'm running this in a Firebase cloud function, so wondering whether increasing CPU and memory will improve things?

danvoyce avatar Nov 15 '19 09:11 danvoyce

Yeah, i'd be very interested to know what we can do to speed things up.

I'm running this in a Firebase cloud function, so wondering whether increasing CPU and memory will improve things?

Can you share some example or tutorial on how to setup this in the firebase cloud or aws lambda? Thanks

ahmic avatar Jan 25 '20 02:01 ahmic

@ahmic @danvoyce It will depend on a few things. Firstly, the speed of what you are rendering will limit the speed. You will also be limited by the speed at which puppeteer can screenshot the page, which can be improved be using jpegs instead of pngs. See https://github.com/tungs/timesnap#cli-options-screenshot-type.

Asheboy avatar Jan 27 '20 14:01 Asheboy

I ended up doing this completely client side. It's pretty easygoing to setup, and so much better for my use case https://github.com/ffmpegjs/ffmpeg.js

danvoyce avatar Jan 27 '20 14:01 danvoyce

@danvoyce Did you use that to actually record the browser too?

Asheboy avatar Jan 27 '20 14:01 Asheboy

Just the canvas. You can see a rough example here https://github.com/ffmpegjs/ffmpeg.js/issues/9

danvoyce avatar Jan 27 '20 14:01 danvoyce

@ahmic @danvoyce It will depend on a few things. Firstly, the speed of what you are rendering will limit the speed. You will also be limited by the speed at which puppeteer can screenshot the page, which can be improved be using jpegs instead of pngs. See https://github.com/tungs/timesnap#cli-options-screenshot-type.

So @Asheboy did you tried to switch to jpgs ? did it speed up things ?

red1 avatar Jan 30 '20 10:01 red1

@red1 Yes. If you're still needing it faster, you'll need to investigate what the bottle neck is (CPU, memory or maybe something inside Chrome?). Generally, if you're running on cloud infrastructure, you're not going to be getting the best performance as the resources are shared.

Asheboy avatar Jan 30 '20 10:01 Asheboy

The solution I'm thinking of is to split the complete process into multiple tasks and run it on AWS Lambda in parallel.

Anyone here managed to port this to Lambda?

ahmic avatar Jan 30 '20 10:01 ahmic

@ahmic I've had that thought before and I'm sure it will work as I've seen others have used puppeteer on Lambda. Just bear in mind that the CPU on Lambda instances are not going to be the best. For my use-case, we've ended up going with a dedicated Hetzner server.

Asheboy avatar Jan 30 '20 10:01 Asheboy

The solution I'm thinking of is to split the complete process into multiple tasks and run it on AWS Lambda in parallel.

Anyone here managed to port this to Lambda?

@ahmic Is it even possible to parallel the process?

seifsg avatar Feb 08 '20 22:02 seifsg

There's a similar discussion happening in timesnap: tungs/timesnap#8. The summary there is that we haven't found any magical flags in puppeteer yet to capture faster than real time. Built in screenshotting in puppeteer seems to be the bottleneck. Using jpeg seems to help, and using canvas-capture mode (which bypasses puppeteer's screenshotting function, though only works for canvases) yields faster results.

In theory it's possible to parallelize this, but it's not the intended use and might not be ultimately practical.

If you want to pursue this you could use a different start for each of the processes. For instance, if you wanted to capture a 60 second movie among four processes, you'd have start be 0s, 15s, 30s, and 45s with a duration of 15s each, and then stitch the movies together.

Alternatively, you could use timesnap to capture frames at a lower fps and offsetting the start for each of the processes. For instance, if you ultimately want to capture a 30fps movie with four parallel processes, you'd use an fps of 7.5 (e.g. 30/4) for each of the processes, and have different starts of 0s, 0.33s, 0.66s, and 0.1s (e.g. the frame duration of 30fps) for the four processes. Then you'd collect all of the captured frames and sort them into the right order, and then pass them to the movie maker of your choice. This approach may be better if there is a lot of computation occurring on the web page where longer starts take significantly longer time.

If anyone does go this route, I'd be interested in the results, though I don't personally have the time to test this out myself. The bottleneck does seem to be capturing the screenshot, and parallelization should, in theory, bypass that bottleneck.

tungs avatar Feb 09 '20 17:02 tungs

@ahmic Is it even possible to parallel the process?

@seifsg For my use case, it is possible. I'm recording multiple webpages for 5 seconds, and all generated videos are merging into one (using FFMPEG). If I set it up on the AWS lambda, the total duration for all pages will be like for one page with a current single instance..

ahmic avatar Feb 10 '20 14:02 ahmic

@tungs I actually tried to implement your suggestion a couple of months ago, however I ended up getting timing issues and ending up with duplicate frames.

Asheboy avatar Mar 24 '20 09:03 Asheboy

What if there is nothing happening on the page between some actions? For example, I am recording webgl sort of collaborative whiteboard and i am replaying the user actions that happened on the whiteboard for the purpose of recording. There is times where the frames are the same for next couple of seconds.

My idea is to skip those frames and duplicate then manually because i know the time when nothing is happening. Is there an event on pupeteer to see if nothing is happening on the page just to fast forward the images? at least to run it at normal speed

klimentLambevski avatar Apr 02 '20 11:04 klimentLambevski

Actually I tried canvasCaptureMode and was much faster on recording frames that are stale and only slows down when there is change in the canvas

klimentLambevski avatar Apr 02 '20 12:04 klimentLambevski

Voilà a shell script that splits the rendering into parts of equal duration, starts up multiple Docker containers for rendering simultaneously, and concatenates the output videos when the workers are finished. Maybe it is useful for someone else.

timecut-parallel.sh -i <file to render> -o <output directory> -d <duration> [-s <start time>] [-w <number of workers>]

https://gist.github.com/traines-source/378677dd3b360de109d712dbb8205110

traines-source avatar Jul 11 '21 22:07 traines-source