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

Capture speed! #23

Open
rana01645 opened this issue Nov 11, 2019 · 17 comments
Open

Capture speed! #23

rana01645 opened this issue Nov 11, 2019 · 17 comments

Comments

@rana01645
Copy link

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

@danvoyce
Copy link

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?

@ahmic
Copy link

ahmic commented Jan 25, 2020

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

@Asheboy
Copy link

Asheboy commented Jan 27, 2020

@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.

@danvoyce
Copy link

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

@Asheboy
Copy link

Asheboy commented Jan 27, 2020

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

@danvoyce
Copy link

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

@red1
Copy link

red1 commented Jan 30, 2020

@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 ?

@Asheboy
Copy link

Asheboy commented Jan 30, 2020

@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.

@ahmic
Copy link

ahmic commented Jan 30, 2020

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?

@Asheboy
Copy link

Asheboy commented Jan 30, 2020

@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.

@seifsg
Copy link

seifsg commented Feb 8, 2020

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?

@tungs
Copy link
Owner

tungs commented Feb 9, 2020

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.

@ahmic
Copy link

ahmic commented Feb 10, 2020

@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..

@Asheboy
Copy link

Asheboy commented Mar 24, 2020

@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.

@klimentLambevski
Copy link

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
Copy link

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

@traines-source
Copy link

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

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

No branches or pull requests

9 participants