{"id":15485999,"url":"https://github.com/pankod/canvas2video","last_synced_at":"2025-08-12T16:09:25.335Z","repository":{"id":55091579,"uuid":"290171658","full_name":"pankod/canvas2video","owner":"pankod","description":"canvas2video is a backend solution for creating and rendering dynamic videos.","archived":false,"fork":false,"pushed_at":"2021-03-23T09:41:05.000Z","size":25784,"stargazers_count":288,"open_issues_count":12,"forks_count":37,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-28T09:04:33.115Z","etag":null,"topics":["canvas","ffmepg","rendering","typescript"],"latest_commit_sha":null,"homepage":"https://pankod.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pankod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-25T09:25:52.000Z","updated_at":"2025-02-16T23:16:20.000Z","dependencies_parsed_at":"2022-08-14T11:40:48.389Z","dependency_job_id":null,"html_url":"https://github.com/pankod/canvas2video","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pankod%2Fcanvas2video","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pankod%2Fcanvas2video/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pankod%2Fcanvas2video/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pankod%2Fcanvas2video/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pankod","download_url":"https://codeload.github.com/pankod/canvas2video/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332612,"owners_count":20921853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["canvas","ffmepg","rendering","typescript"],"created_at":"2024-10-02T06:05:32.443Z","updated_at":"2025-04-05T12:09:24.672Z","avatar_url":"https://github.com/pankod.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n \u003cimg src=\"media/pankod.png\" width=\"350\"\u003e\n  \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\u003cdiv align=\"center\"\u003e \u003ch3\u003e\u003cb\u003e@pankod/canvas2video\u003c/b\u003e\u003c/h3\u003e \u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003eCreate dynamic, data-driven videos on the fly.\u003c/div\u003e\n\u003cbr/\u003e\n\u003cdiv align=\"center\"\u003e\n\n[![Maintainability](https://api.codeclimate.com/v1/badges/ce77e17d733e937fbf3b/maintainability)](https://codeclimate.com/github/pankod/canvas2video/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/ce77e17d733e937fbf3b/test_coverage)](https://codeclimate.com/github/pankod/canvas2video/test_coverage)\n[![npm version](https://img.shields.io/npm/v/@pankod/canvas2video.svg)](https://www.npmjs.com/package/@pankod/canvas2video)\n![npm](https://img.shields.io/npm/dm/@pankod/canvas2video)\n[![dependencies Status](https://david-dm.org/pankod/canvas2video/status.svg)](https://david-dm.org/pankod/canvas2video)\n[![dev-dependencies Status](https://david-dm.org/pankod/canvas2video/dev-status.svg)](https://david-dm.org/pankod/canvas2video?type=dev) [![Meercode CI Score](https://meercode.io/badge/pankod/canvas2video?type=ci-score\u0026branch=master)](https://meercode.io/pankod/canvas2video)\n\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003csub\u003eCreated by \u003ca href=\"https://www.pankod.com\"\u003ePankod\u003c/a\u003e\u003c/sub\u003e\n\u003c/div\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n## About\n\n@pankod/canvas2video is a backend solution for creating and rendering dynamic videos. It lets you build web canvas scenes by using the *Cairo-backed* [fabric](https://github.com/fabricjs/fabric.js) library and add animations with [gsap](https://github.com/greensock/GSAP).\nYour animation timeline will be rendered frame by frame and piped to ffmpeg renderer for the final video output.\n\n## Use Cases\n\n📺 Personalized video advertising\n\n🎞️ Programmatical customization of video templates\n\n⛅ Creating dynamic videos with real-time data (See: [Weather Example ](./examples) - [Youtube](https://www.youtube.com/watch?v=xv8M3ScElv0))\n\n\n## Getting started\n\nTo install the module, run the following in the command line:\n\n```bash\nnpm install @pankod/canvas2video --save\n```\n\nor\n\n```bash\nyarn add @pankod/canvas2video\n```\n\n## Usage\n\n`renderer` expects a `makeScene` function where you create your canvas animation by using [fabric](https://github.com/fabricjs/fabric.js) and \n[gsap](https://github.com/greensock/GSAP) methods. It returns a *stream of frames* to be consumed by the `encoder` in the next step.\n\nBelow is a basic example of a one-second rotation animation of \"Hello World\" text. After rendering the animation and encoding the video, the output will be saved to `output/hello-world.mp4`.\n\n```js\nimport { renderer, encoder } from \"@pankod/canvas2video\";\n\nconst helloWorld = async () =\u003e {\n    const stream = await renderer({\n        silent: false,\n        width: 1920,\n        height: 1080,\n        fps: 30,\n        makeScene: (fabric, canvas, anim, compose) =\u003e {\n            const text = new fabric.Text(\"Hello world\", {\n                left: 400,\n                top: 400,\n                fontSize: 100,\n                fill: \"#f99339\",\n                angle: 0,\n            });\n            canvas.add(text);\n            anim.to(text, {\n                duration: 1,\n                angle: 360,\n                ease: Power3.easeOut,\n            });\n            compose();\n        },\n    });\n\n    const output = await encoder({\n        silent: false,\n        frameStream: stream,\n        output: \"output/hello-world.mp4\",\n        fps: {\n            input: 30,\n            output: 30,\n        },\n        \n    });\n    console.log(\"process done,\", output.path);\n};\n```\n\nYou may refer the following documentations to learn how the construct your own `makeScene` methods:\n\n📃[Fabric.js Documentation](http://fabricjs.com/docs/)\n\n📃[GSAP Documentation](https://greensock.com/docs/)\n\nYou can optionally provide the `encoder` function a `backgroundVideo` object. In this case, your animation will be used as an overlay layer and merged with the background video. More information about the usage of background videos is given in the *Options* section.\n\n\n## Examples\n\n\u003cdiv align=\"center\"\u003e\n \u003cimg width=\"600\" src=\"media/pullr-gif.gif\" \u003e\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\nYou'll find two working demos int the [examples](./examples) folder folder of the project. Give them a try by following the steps below:\n\n#### **Check out examples**\n\n\n```bash\n$ git clone https://github.com/pankod/canvas2video.git\n````\n```\n$ cd examples\n```\n```\n$ npm i\n```\nAfter this, you can run commands at the below then check examples/output directory:\n#### **Example 1**\n\n```bash\n$ npm run start:hello-world\n```\n\n\n#### **Example 2**\n\n```bash\n$ npm run start:weather\n```\n\n\u003cbr/\u003e\n\n## Options\n\n### **Renderer**\n\n| Properties                      | Type       | Description                          |\n| ------------------------------- | ---------- | ------------------------------------ |\n| **width** \u003cbr\u003e \\*_required_     | `number`   | canvas width                 |\n| **height** \u003cbr\u003e \\*_required_    | `number`   | canvas height               |\n| **fps** \u003cbr\u003e \\*_required_       | `number`   | animation fps |\n| **makeScene** \u003cbr\u003e \\*_required_ | `function` | [See below](#makeScene)              |\n\n\u003cbr/\u003e\n\n#### **_makeScene_**\n\nThe function takes 4 arguments(fabric, canvas, anim and compose) which is passed by the `renderer` function.\n\n```js\nrenderer({\n    /* .. */\n    makeScene: (fabric, canvas, anim, compose) =\u003e {\n        /**\n         * your code to create and manipulate your canvas\n         */\n    },\n});\n```\n\n| _Parameter_ | _Type_              |                                               |\n| ----------- | ------------------- | --------------------------------------------- |\n| **fabric**  | fabric.js instance  | [Repo](https://github.com/fabricjs/fabric.js) |\n| **canvas**  | fabric.StaticCanvas | [Repo](https://github.com/fabricjs/fabric.js) |\n| **anim**    | gsap.TimelineMax    | [Repo](https://github.com/greensock/GSAP)     |\n| **compose** | () =\u003e void          |\n\n\u003cbr/\u003e\n\n### **Encoder**\n\n| Properties                        | Type       | Description                         |\n| --------------------------------- | ---------- | ----------------------------------- |\n| **frameStream** \u003cbr\u003e \\*_required_ | `Readable` |  `renderer` function return value    |\n| **output** \u003cbr\u003e \\*_required_      | `string`   | output file path               |\n| **fps** \u003cbr\u003e \\*_required_         | `Object`   | `{ input: number, output: number }` |\n| **backgroundVideo**               | `Object`   | [See below](#backgroundVideo)       |\n\n\u003cbr/\u003e\n\n#### **_backgroundVideo_**\n\n```ts\nbackgroundVideo: {\n  videoPath: string, // your background video path\n  inSeconds: number, // video start time in seconds\n  outSeconds: number, // video end time in seconds\n}\n```\n\n\u003cbr/\u003e\n\n## To-do\n\n📌 [Lottie](https://airbnb.design/lottie/) animation support\n\n📌 Thread \u0026 concurrency management\n\n📌 Finer control over encoder settings\n\n\n\n## License\n\n[License](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpankod%2Fcanvas2video","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpankod%2Fcanvas2video","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpankod%2Fcanvas2video/lists"}