Giter Club home page Giter Club logo

ccapture.js's Introduction

CCapture.js - A library to capture canvas-based animations

CCapture.js is a library to help capturing animations created with HTML5 canvas at a fixed framerate.

An example is probably worth a lot of words: CCapture.js with Game of Life 3D.

Sample

What is CCapture.js and why would I need it?

Let's say that you finally have your amazing canvas-based animation running in your browser, be it 2D or 3D with the power of WebGL. You've been working hard to keep it fast and smooth. If you're using requestAnimationFrame you're aiming for a framerate of 60fps or, in other words, each frame is taking 16ms or less to render.

Now you want to record a video of it. Not a big deal, you can fire up a screen capture software that churns out a video file and be done with it. But what if you wanted to create an HD movie of your animation, and it simply cannot be rendered at higher resolutions because frames start dropping? What if you wanted to put all the quality settings up for the video? What if you wanted to push that particle count to 10 millions?

What if, indeed. What would happen is that you'd get a choppy video at best. At higher resolutions, fillrate is a bottleneck for most canvas-based animations. High quality settings or high number of elements may be only feasible on more powerful hardware.

With CCapture.js you can record smooth videos at a fixed framerate for all these situations, because it doesn't run in realtime: it makes the animations run at a given, fixed framerate which can be specified. You can record animations at smooth and consistent 30 or 60fps even if each frame takes seconds to render. You can even take a 240fps capture and create motion blur with post-production software.

The only requirement is that you step your values per frame according to elapsed time. In other words, don't increment your variables with a fixed value each frame, but use an elapsed time delta to adjust those increments. CCapture.js works by hooking the common methods for obtaining that elapsed time: Date.now(), setTimeout, requestAnimationFrame, etc. and making them behave like a constant time step is happening, fixed by the specified framerate.

Methods supported so far:

  • Date.now, Date.prototype.getTime
  • setTimeout, clearTimeout, setInterval (clearInterval pending)
  • requestAnimationFrame
  • performance.now
  • HTMLVideoElement.prototype.currentTime, HTMLAudioElement.prototype.currentTime

CCapture.js is more or less ryg's kkapture but for JavaScript and canvas.

The library supports multiple export formats using modular encoders (`CCFrameEncoder):

  • CCWebMEncoder uses WebM Writer for JavaScript to create a WebM movie
  • CCPNGEncoder and CCJPEGEncoder export PNG and JPEG files in a TAR file, respectively
  • CCGIFEncoder uses gifjs to create animated GIFs
  • CCFFMpegServerEncoder uses ffmpegserver.js to generate video on the server

Forks, pull requests and code critiques are welcome!

Using the code

Include CCapture[.min].js and WebM Writer or gifjs.

<script src="CCapture.min.js"></script>
<!-- Include WebM Writer if you want to export WebM -->
<script src="webm-writer-0.2.0.js"></script>
<!-- Include gifjs if you want to export GIF -->
<script src="gif.js"></script>
<!-- Include tar.js if you want to export PNG or JPEG -->
<script src="tar.js"></script>
<!-- Include download.js for easier file download -->
<script src="download.js"></script>

Or include the whole pack

<script src="CCapture.all.min.js"></script>

Or use npm or bower to install the package:

npm install ccapture.js

Or use bower to install the package:

bower install ccapture.js

To create a CCapture object, write:

// Create a capturer that exports a WebM video
var capturer = new CCapture( { format: 'webm' } );

// Create a capturer that exports an animated GIF
// Notices you have to specify the path to the gif.worker.js 
var capturer = new CCapture( { format: 'gif', workersPath: 'js/' } );

// Create a capturer that exports PNG images in a TAR file
var capturer = new CCapture( { format: 'png' } );

// Create a capturer that exports JPEG images in a TAR file
var capturer = new CCapture( { format: 'jpg' } );

This creates a CCapture object to run at 60fps, non-verbose. You can tweak the object by setting parameters on the constructor:

var capturer = new CCapture( {
	framerate: 60,
	verbose: true
} );

The complete list of parameters is:

  • framerate: target framerate for the capture
  • motionBlurFrames: supersampling of frames to create a motion-blurred frame (0 or 1 make no effect)
  • format: webm/gif/png/jpg/ffmpegserver
  • quality: quality for webm/jpg
  • name: name of the files to be exported. if no name is provided, a GUID will be generated
  • verbose: dumps info on the console
  • display: adds a widget with capturing info (WIP)
  • timeLimit: automatically stops and downloads when reaching that time (seconds). Very convenient for long captures: set it and forget it (remember autoSaveTime!)
  • autoSaveTime: it will automatically download the captured data every n seconds (only available for webm/png/jpg)
  • startTime: skip to that mark (seconds)
  • workersPath: path to the gif worker script

You can decide when to start the capturer. When you call the .start() method, the hooks are set, so from that point on setTimeout, setInterval and other methods that are hooked will behave a bit differently. When you have everything ready to start capturing, and your animation loop is running, call:

capturer.start();

requestAnimationFrame, setTimeout, etc. won't work as expected after capture is started. Make sure your animation loop is running

And then, in your render() method, after the frame is been drawn, call .capture() passing the canvas you want to capture.

function render(){
	requestAnimationFrame(render);
	// rendering stuff ...
	capturer.capture( canvas );
}

render()

That's all. Once you're done with the animation, you can call .stop() and then .save(). That will compose the video and return a URL that can be previewed or downloaded.

capturer.stop();

// default save, will download automatically a file called {name}.extension (webm/gif/tar)
capturer.save();

// custom save, will get a blob in the callback
capturer.save( function( blob ) { /* ... */ } );

Note: you don't need to .stop() in order to .save(). Call capturer.save() anytime you want to get a download up to that moment.

Limitations

CCapture.js only works on browsers that have a `canvas implementation.

WebM Writer current version only works on a browser that supports the image/webp format. Exporting video is basically Chrome-only for now :( If you want to help to make it Firefox, Opera or even Internet Explorer compatible, please do!

gif.js has some performance limitations, be careful if capturing a lot of frames.

The autoSaveTime parameter

Different browsers have different issues with big files: most break for big Uint8Array allocations, or when a file to downloads is larger than 1GB, etc. I haven't been able to find a solid solution for all, so I introduced the autoSaveTime parameter, just to prevent loss of large files. If used with a webm/png/jpg capturer, it will automatically compile, download and free the captured frames every n seconds specified in the parameter. The downloaded file will have the structure {name}-part-00000n and the extension (.webm or .tar). The files inside the TAR file will have the right number of sequence.

Use an autoSaveTime value that give you a file that is small enough to not trip the browser, but large enough to not generate a thousand part files. A value between 10 and 30 seconds for a 4K capture I've found works best: just make sure the file is under 1GB. For most regular, viewport-sized or even Full-HD captures it shouldn't be an issue, but keep in mind this issue.

Memory allocation and garbage collection

There's some issues in which memory -mostly from accumulated frames- will not be freed, depending on the platform and the mood of the browser. If you run into non-sawtooth like memory profiles, and are running chrome, try running it with --js-flags="--expose-gc". This way CCapture will run gc() every frame and memory consumption should stay stable.

Gallery

cru·ci·form 4K CCapture obsidian by xplsv 4K CCapture dataworld by xplsv 4K CCapture

Credits

Contributors

Big thanks to hugohil and Greggman!

License

MIT licensed

Copyright (C) 2012-2016 Jaume Sanchez Elias, http://www.clicktorelease.com

ccapture.js's People

Contributors

depstein avatar dvberkel avatar greggman avatar gsimone avatar hugohil avatar nijk avatar queenvictoria avatar rreusser avatar spite avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ccapture.js's Issues

Use Case Query

Hi,

First of all, many thanks for this wonderful package.

My use case is as follows:
I have a trading canvas stockchart which gets updated with new data coming from server every 1 minute or so. The chart is practically static in nature waiting for the next data point to arrive at which point, it re gets re rendered and updated. Now I would like to create a fast paced video of the canvas every time it gets updated (rendered) as against capturing the idle time in between. So I can create some logic to make sure that the video starts capturing every time there is a render of the chart and immediate stop it using a timer few milliseconds after the rendering is complete.
My query is as follows:

  1. Can the library manage the above out of the box to produce a video that captures every chart render and filters out the idle time
  2. If yes, how?
  3. If no, then I can build a logic at my end to capture few hundred of such videos capturing each render of the chart but how do I knit them together to build one past paced video out of the session

Thank you

Resolution Independence - possible ?

I would like to record frames or video, for a canvas bigger than the screen resolution of my laptop.

Was wondering if you had thought about this. I am thinking that dong it server side is the only way.
Basically a way to call webkit on the server, a bit like phantomjs does.

Framerate bug above 60

Hi there,

I tried capturing a 60 fps animation in 3 seconds and it worked out perfectly. Now I want to capture the animation at double the speed, so I set animation to 120 fps, the framerate to 120, and the timeLimit to be 1.5 seconds. For some reason, the ccapture behaves like it's recording 180 frame in 3 seconds, but not in 1.5 seconds, which causes the last 1.5 seconds to be static.

For the animation, I'm using GSAP and using the timeScale(2) to double up the animation speed.

Is this normal or is it a bug?

Export tar to send to server

I need to export the tar file not for download but to send it to the server. Is there a way to do this currently?

gif framedelay control

Hello
I wish one could control frame delays in some way when exporting to gif. Something like:
{frames:{1:200,10:200, 20:200, 30:300}}
I don't know something like that.
Those frames, 1,10,20 and 30 would have those delays and the rest, would have the default delay.
Thanks.

Is PNG Support still working?

When downloading the file i get project.tar than unpacks to project.tar.cpgz with nothing inside. Longer movies have 0 bytes or fail completely. JPG export works fine.

OSX 10.12, Chrome 53

canvas has been tainted by cross-origin data

Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.

The images does show while running my canvas but when i try to capture the canvas i get this issue.
FYI. i tried to capture gif of the canvas.

Do you have any solution about it?
I tried image.crossOrigin = 'anonymous';

Gif Recording

Is it possible to record a fixed length of time? Say 1 second, on a button click?

I've tried to do the following with the Gif renderer. I'm using a Canvas object previously created via p5.js:

function setup() {
    // setup camera capture
    videoInput = createCapture();
    videoInput.size(canvasWidth, canvasHeight);
    videoInput.position(0, 0);
    videoInput.parent('wrapper');

     // setup canvas
    cnv = createCanvas(canvasWidth, canvasHeight);
    cnv.position(0, 0);
    cnv.parent('wrapper');
}

With canvas rendering done in the draw function:

function draw() {
    clear();
    // a bunch of drawing calls go here ..
    render();      
 }

function render(){
    capturer.capture( cnv.elt );
 }

Then in my button handler:

 capturer.start();
 setTimeout(function(){
     capturer.stop();
     capturer.save( function( e ) { 
            console.log(e);
           //$('#gifOutput').attr('src', url);
         } );
  }, 1000);

I get an exception (which hangs the browser), from gif.coffee on line 72: "Width and height must be set prior to rendering".

Frames captured against black background

Hi
I am using tar.js to export jpg images. But the background color of the images is black,
In my canvas, i have set the background color as white
What should i do to get the exported images with white background?

Thanks in advance

alpha transparency

Thanks for this script, it's just what I needed.

I'm trying to save a transparent canvas to webm but I get a black background.
Is it possible to save a transparent background with webm?

Thanks

Everything Desaturated?

I think this is more related to the canvas in three.js, but when I save images or video out using this awesome module, they all come out desaturated? Is there an easy way to get the colors to look right when you save an image or animation?

Thanks!

Sampling / Playback Speed

I'm trying to get a smoother animation. Here are the settings I'm using. When I lower the framerate, the animation becomes too choppy, when I increase it, it plays back way too fast. How do I get better sampling and keep a good speed?

Thanks!

    var capturer = new CCapture( {
        framerate: 35,
        verbose: true,
        format: 'webm',
        quality: 80,
        name: 'MyVid',
        motionBlurFrames: 0   
    } );

Webm capture corrupted by enabled alpha in THREE.js

Capturing with format set to Webm causes the file to be corrupt on export when the alpha of the canvas is set to true.

With the latest version THREE.js (v82) and THREE.WebGLRenderer({ alpha: false }) it works totally fine! With alpha set to true and format set to png the export does actually work.

Using with setInterval

I'm trying to take a screen capture of my app (made with BabylonJS), but i need to limit the quantity of images generated, because my app runs with 60 FPS.

I have tryed limit the capture every 200ms in my renderLoop, but this returns the error: Uncaught Error: Width and height must be set prior to rendering.

How can i make it?

Thanks a lot

Black animated gif

I'm trying to export an animated GIF from an a-frame scene.
But in the downloaded gif file every frame is black.

my code:

$('#start').click(function(){ $('canvas').attr('id','bit'); var canvas = document.getElementById('bit'); var capturer = new CCapture( { format: 'gif', workersPath: 'capture/src/', framerate: 30, verbose: true, name:'file', timeLimit: 2, }); capturer.start(); function render(){ requestAnimationFrame(render); capturer.capture(canvas); } render(); })

Running ccapture.js headless?

Does anyone know how to run ccapture.js headless - without opening a browser window? I'd love to use this on a server, but there are limits on what can be done.

If someone could shed some experience or light on this - much appreciated!

Add missing download.js import

The correct way to import the lib in order for jpeg to work should be changed from:

<script src="CCapture.min.js"></script>
<script src="tar.js"></script>

to:

<script src="build/CCapture.min.js"></script>
<script src="src/tar.js"></script>
<script src="src/download.js"></script>

GIF is not defined()

Hi,

I installed using npm and am creating a new capture like this

var capturer = new CCapture({
                        framerate: 60,
                        format: 'gif',
                        workersPath: './node_modules/ccapture.js/src/',
                        verbose: true
                    });

i get an error that GIF is not defined so i'm assuming that i'm not settings the workersPath correctly. I've also tried / and js/

Breaks Phaser-based games

I'm not sure whether this is ultimately an upstream or downstream issue, but when I start the GIF capturer my game seems to freeze. I'm assuming this has something to do with the methods CCapture overrides, but haven't had a chance to dig deeper. I'd really love to be able to use this lib to record gameplay videos.

I can't figure out how to setup the script on my site

I created a new JS file with the following content:

$("#startRecording").click(function(event){
        capturer.start();

        render();

        capturer.stop();

        capturer.save();

    });


var capturer = new CCapture( {
    format: 'webm',
    name: 'aman',
    framerate: 60,
    verbose: true
} );

var canvas = $(".canvas");

function render(){
            requestAnimationFrame(render);
            animateImage();
            capturer.capture( canvas );
}

When I click on the start button, nothing happens and nothing is added in the console.

I am very sorry if it's a basic question but can you please tell me a workaround for this.

Thanks

How to use with fabric.js?

I'm trying to use this library with fabric.js

Capturing like this

canvas.on('after:render', () => {
    capturer.capture( $canvas );
});

it works and saves the data, but it's low fps,
I specified 120 fps in ccapture but always get ~40

npm?

Hi,
Have you thought about releasing ccapture on npm? It would make it much easier to include it in modern projects.

bower install error

I'm getting this error when i try bower install:
Unexpected token ]

I think the bower file might need a comma removed after the author. From this:

"authors": [ "Jaume Sanchez <[email protected]> (https://www.clicktorelease.com)", ],

to this:

"authors": [ "Jaume Sanchez <[email protected]> (https://www.clicktorelease.com)" ],

Suggestion : WebWorker Based Streaming !

I think it would be amazing if i can do something like this

recorder.on('chunk',function(packet){
some_rtc_channel.send(packet);
});

It can be used for a lot of stuff :D /* process and broadcast a video in realtime using rtc channels maybe */

autoSaveTime does not work with PNG & JPG

When trying to use the autoSaveTime parameter (set to 5) with the JPG encoder, it did not automatically save the frames.

There is a vestigial fragment of a previous implementation commented out on this line here. Was autoSaveTime removed intentionally for PNG & JPG encoders? If not, I can take a stab at reimplementing it.

Is there a way to capture Plotly 3D graph using this library?

Sorry for opening an issue but i couldnt find any support on stack oveerflow

This is the codepen of what i have tried so far. I am not able to link the render function of plotly to the construct mentioned in the documentation.

function render(){
    requestAnimationFrame(render);
    // rendering stuff ...
    capturer.capture( canvas );
}

render()

Need Some help

Gif is not animated

Hi there !

I'm using your library with seriouslyjs to convert the canvas animation into a gif.

I get no error while running my code, but when I open the blob, I just have the first frame (the one when I clicked the button), but no animation.

I made a codepen to show you, but due to CORS policy you cannot run it directly. However, you can copy/paste the code there and download the videos to perform a quick test locally.

Video playback speed hook.

Can we also hook video playbackrate to the step? When we add a video to THREEJS Scene the video loses frames while getting captured.

Error while recording as gif

Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///C:/Users/Admin/Downloads/ccapture.js-master/ccapture.js-master/src/gif.worker.js' cannot be accessed from origin 'null'.

While running the example im getting above error. I tried with chrome and safari browser. No response.

Capture multiple videos

Is it possible to start/stop the capture multiple times using CCapture.js?

Whenever I call capturer.start() I get these errors:

Uncaught Error: Width and height must be set prior to rendering
Uncaught TypeError: Cannot redefine property: currentTime

Is there a fix around this?

Several problems

Hi there,

First of all: great work! I have, howerver, some problems. I am using CCapture.all.min.js

First of all, even when setting the display option to false when constructing the capturer, the black box with red text is being displayed in the top left corner. How can I get rid of that?

The second issue is, that the framerate option also seems to be ignored. I set it to 3 or 1, but the frame counter in the top left quickly goes into the hundreds within a few seconds.

And thirdly: When I use gif as output format, the output is only in black and white. How can that happen and how do I get it to record colors? There also seems to be quite a performance issue with gif generation, although I'm only capturing a canvas of 500x500px in size.

Any help appreciated!

P.S.: The demo also seems to be broken for gif output. You get the following in the console:
"NetworkError: 404 Not Found - https://www.clicktorelease.com/src/gif.worker.js"

Export JPG/PNG as blob

I have a use case where I want to use CCapture to export the Canvas frames to use with an external AVI Encoder.

In order to do this most effectively, I'd like to export each Canvas frame as an individual file blob so that it can be passed directly to the encoder.

I'm about to embark on this work, so any thoughts on how this might work in the context of PR would be helpful to allow me to contribute it back.

Capture with video texture

I have a complex scene that is successfully rendering out at just under 2 frames per second using Ccapture. All the objects in the scene are textured with video which is playing back behind the scenes at its normal speed (25FPS). The result is the scene plays back super well but the video texture plays back at several times the correct speed.

I've tried setting the video currentTime to synchronise it with time delta like so.

var video = document.getElementById("source");
video.currentTime += dt;

Strangely that, and just console.log(video.currentTime);, both pause the video texture completely (but not the actual video in the page). console.log(video.played); does not.

This is using Chrome Version 51.0.2704.103 (64-bit).

Any thoughts on a work around? And thank you very much for the beautiful library!

Latest Version of Firefox Breaks Rendering

I love this script and use it daily to render webGL animations. Unfortunately it looks like the latest Firefox update v55 breaks the rendering process. It took me awhile to figure out what was going on, but once I downgraded to Firefox v54 it worked flawlessly again. I assume this is related to the security part of the release notes. (https://www.mozilla.org/en-US/security/advisories/mfsa2017-18/). When on v55 the render can still be downloaded but it contains empty black frames for PNG sequences/gif frames.

Hope this helps someone else.

Less Nauseating Game of Life 3D Settings for First Example

Seriously, I can see this affecting your adoption rates. The Game of Life 3D example eventually chills out and is less nauseating. But I can tell you that, as a new user struggling to get the settings right and not yet knowing how to change what I'm recording, I'm getting nauseous every time I try to learn your software.

That's not a state of mind that you want new people experiencing on top of the necessary stress involved in learning a new system. I highly suggest you fast forward the example to a more chill state within Game of Life 3D. You can include the frantic state to demonstrate slow motion and blur effects in a second or third example file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.