{"id":17748323,"url":"https://github.com/jankozik/ffmpeg-concat","last_synced_at":"2025-04-05T13:34:52.076Z","repository":{"id":173675471,"uuid":"646061351","full_name":"jankozik/ffmpeg-concat","owner":"jankozik","description":"Concats a list of videos together using ffmpeg with sexy OpenGL transitions.","archived":false,"fork":false,"pushed_at":"2023-07-14T10:32:16.000Z","size":12057,"stargazers_count":27,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2023-07-14T11:39:37.750Z","etag":null,"topics":["ffmpeg","fluent-ffmpeg","javascript","opengl","transition"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jankozik.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-27T06:50:05.000Z","updated_at":"2023-07-14T10:35:18.000Z","dependencies_parsed_at":"2024-05-17T23:31:18.176Z","dependency_job_id":null,"html_url":"https://github.com/jankozik/ffmpeg-concat","commit_stats":null,"previous_names":["jankozik/ffmpeg-concat"],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jankozik%2Fffmpeg-concat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jankozik%2Fffmpeg-concat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jankozik%2Fffmpeg-concat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jankozik%2Fffmpeg-concat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jankozik","download_url":"https://codeload.github.com/jankozik/ffmpeg-concat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223192592,"owners_count":17103564,"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":["ffmpeg","fluent-ffmpeg","javascript","opengl","transition"],"created_at":"2024-10-26T10:01:37.371Z","updated_at":"2024-11-05T15:09:02.941Z","avatar_url":"https://github.com/jankozik.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# ffmpeg-concat\n\n\u003e Concats a list of videos together using ffmpeg with sexy OpenGL transitions.\n\n![](https://raw.githubusercontent.com/jankozik/ffmpeg-concat/master/media/example.gif)\n\n*(example of 9 videos concatenated together with unique transitions)*\n\n## Intro\n\n[FFmpeg](http://ffmpeg.org/) is the de facto standard in command-line video editing, but it is really difficult to concatenate videos together using non-trivial transitions. Here are some [convoluted](https://superuser.com/questions/778762/crossfade-between-2-videos-using-ffmpeg) [examples](https://video.stackexchange.com/questions/17502/concate-two-video-file-with-fade-effect-with-ffmpeg-in-linux) of a simple cross-fade between two videos. FFmpeg filter graphs are extremely powerful, but for implementing transitions, they are just too complicated and error-prone.\n\n[GL Transitions](https://gl-transitions.com/), on the other hand, is a great open source initiative spearheaded by [Gaëtan Renaudeau](https://github.com/gre) that is aimed at using GLSL to establish a universal [collection](https://gl-transitions.com/gallery) of transitions. Its extremely simple spec makes it really easy to customize existing transitions or write your own as opposed to struggling with complex ffmpeg filter graphs.\n\n**This module and CLI make it easy to concat videos together using gl-transitions.**\n\n## Install\n\nThis module requires [ffmpeg](http://ffmpeg.org/) to be installed.\n\n```bash\nnpm install --save ffmpeg-concat\n\n# or if you want to use the CLI\nnpm install -g ffmpeg-concat\n```\n\nThis package runs on Linux, macOS, and Windows.\n\nNode.js versions 10.13.0 and up are supported. Note (**macOS only**): due to an inadvertant low-level breaking change in libuv's process handling code, OpenGL [is not supported](https://github.com/stackgl/headless-gl#supported-platforms-and-nodejs-versions) when running Node.js version 12.13.1 through to 13.6.0 on macOS. A fix has been released in Node.js version 13.7.0. A fix for 12.x is pending. Other platforms are unaffected.\n\n## CLI\n\n```sh\n  Usage: ffmpeg-concat [options] \u003cvideos...\u003e\n\n  Options:\n\n    -V, --version                         output the version number\n    -o, --output \u003coutput\u003e                 path to mp4 file to write (default: out.mp4)\n    -t, --transition-name \u003cname\u003e          name of gl-transition to use (default: fade)\n    -d, --transition-duration \u003cduration\u003e  duration of transition to use in ms (default: 500)\n    -T, --transitions \u003cfile\u003e              json file to load transitions from\n    -f, --frame-format \u003cformat\u003e           format to use for temp frame images (default: raw)\n    -c, --concurrency \u003cnumber\u003e            number of videos to process in parallel (default: 4)\n    -C, --no-cleanup-frames               disables cleaning up temp frame images\n    -O, --temp-dir \u003cdir\u003e                  temporary working directory to store frame data\n    -v, --verbose                         enable verbose logging from FFmpeg\n    -h, --help                            output usage information\n\n  Example:\n\n    ffmpeg-concat -t circleopen -d 750 -o huzzah.mp4 0.mp4 1.mp4 2.mp4\n```\n\n## Usage\n\n```js\nconst concat = require('ffmpeg-concat')\n\n// concat 3 mp4s together using 2 500ms directionalWipe transitions\nawait concat({\n  output: 'test.mp4',\n  videos: [\n    'media/0.mp4',\n    'media/1.mp4',\n    'media/2.mp4'\n  ],\n  transition: {\n    name: 'directionalWipe',\n    duration: 500\n  }\n})\n```\n\n```js\n// concat 5 mp4s together using 4 different transitions\nawait concat({\n  output: 'test.mp4',\n  videos: [\n    'media/0.mp4',\n    'media/1.mp4',\n    'media/2.mp4',\n    'media/0.mp4',\n    'media/1.mp4'\n  ],\n  transitions: [\n    {\n      name: 'circleOpen',\n      duration: 1000\n    },\n    {\n      name: 'crossWarp',\n      duration: 800\n    },\n    {\n      name: 'directionalWarp',\n      duration: 500,\n      // pass custom params to a transition\n      params: { direction: [ 1, -1 ] }\n    },\n    {\n      name: 'squaresWire',\n      duration: 2000\n    }\n  ]\n})\n```\n\n## API\n\n### concat(options)\n\nConcatenates video files together along with OpenGL transitions. Returns a `Promise` for when the output video has been written.\n\nNote that you must specify `videos`, `output`, and either `transition` or `transitions`.\n\nNote that the output video's size and fps are determined by the first input video.\n\n#### options\n\n##### videos\n\nType: `Array\u003cString\u003e`\n**Required**\n\nArray of videos to concat, where each item is a path or URL to a video file.\n\n##### output\n\nType: `String`\n**Required**\n\nPath to an `mp4` video file to write.\n\nNote: we currently only support outputting to mp4; please open an issue if you'd like to see support for more formats.\n\n##### transition\n\nType: `Object`\n\nSpecifies a default transition to be used between each video.\n\nNote that you must specify either `transition` or `transitions`, depending on how much control you want over each transition. If you specify both, `transitions` takes precedence.\n\n```js\n// example\nconst transition = {\n  duration: 1000, // ms\n  name: 'directionalwipe', // gl-transition name to use (will match with lower-casing)\n  params: { direction: [1, -1] } // optionally override default parameters\n}\n```\n\n##### transitions\n\nType: `Array\u003cObject\u003e`\n\nSpecifies a (possibly unique) transition between each video. If there are N videos, then there should be N - 1 transitions.\n\nNote that you must specify either `transition` or `transitions`, depending on how much control you want over each transition. If you specify both, `transitions` takes precedence.\n\n```js\n// example\nconst transitions = [\n  {\n    duration: 1000,\n    name: 'fade'\n  },\n  {\n    duration: 500,\n    name: 'swap'\n  }\n]\n```\n\n##### audio\n\nType: `String`\n**Optional**\n\nPath or URL to an audio file to use as the audio track for the output video.\n\nif parameter is not provided - assuming user wants to concat the source scenes audio.\n\n##### args\n\nType: `Array\u003cString\u003e`\n**Optional**\n\nDefault: `['-c:v', 'libx264', '-profile:v', 'main', '-preset', 'medium', '-crf 20', '-movflags', 'faststart']`\n\nArray of output-only ffmpeg command line arguments for the final video.\n\n##### frameFormat\n\nType: `string`\nDefault: `raw`\n\nThe format for temporary frame images. You may, for example, use `png` or `jpg`.\n\nNote: the default is `raw` for performance reasons, as writing and reading raw binary pixel data is much faster than encoding and decoding `png` frames. Raw format is difficult to preview and debug, however, in which case you may want to change `frameFormat` to `png`.\n\n##### concurrency\n\nType: `Number`\nDefault: `4`\n\nMax number of videos to process in parallel.\n\n##### log\n\nType: `Function`\nDefault: `noop`\n\nOptional function to log progress and the underlying ffmpeg commands. You may, for example, use `console.log`\n\n##### cleanupFrames\n\nType: `boolean`\nDefault: `true`\n\nBy default, we cleanup temporary frame images. Set this to `false` if you need to debug intermediate results.\n\n##### tempDir\n\nType: `string`\nDefault: random  directory in `/tmp`\n\nThe temporary working directory to store intermediate frame data. This is where the frames in `cleanupFrames` will be saved.\n\n## Transitions\n\nHere are some [gl-transitions](https://gl-transitions.com/) that I've found particularly useful for quality video transitions:\n\n- [fade](https://gl-transitions.com/editor/fade)\n- [fadegrayscale](https://gl-transitions.com/editor/fadegrayscale)\n- [circleopen](https://gl-transitions.com/editor/circleopen)\n- [directionalwarp](https://gl-transitions.com/editor/directionalwarp)\n- [directionalwipe](https://gl-transitions.com/editor/directionalwipe)\n- [crosswarp](https://gl-transitions.com/editor/crosswarp)\n- [crosszoom](https://gl-transitions.com/editor/CrossZoom)\n- [dreamy](https://gl-transitions.com/editor/Dreamy)\n- [squareswire](https://gl-transitions.com/editor/squareswire)\n- [angular](https://gl-transitions.com/editor/angular)\n- [radial](https://gl-transitions.com/editor/Radial)\n- [cube](https://gl-transitions.com/editor/cube)\n- [swap](https://gl-transitions.com/editor/swap)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjankozik%2Fffmpeg-concat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjankozik%2Fffmpeg-concat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjankozik%2Fffmpeg-concat/lists"}