UNPKG

@yaron24/ffmpeg-concat

Version:

Concats a list of videos together using ffmpeg with sexy OpenGL transitions.

268 lines (186 loc) 10 kB
# ffmpeg-concat > Concats a list of videos together using ffmpeg with sexy OpenGL transitions. [![NPM](https://img.shields.io/npm/v/ffmpeg-concat.svg)](https://www.npmjs.com/package/ffmpeg-concat) [![Build Status](https://travis-ci.com/transitive-bullshit/ffmpeg-concat.svg?branch=master)](https://travis-ci.com/transitive-bullshit/ffmpeg-concat) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) ![](https://raw.githubusercontent.com/transitive-bullshit/ffmpeg-concat/master/media/example.gif) *(example of 9 videos concatenated together with unique transitions)* *(note that the quality and fps is only poor due to the GIF preview; [here](https://raw.githubusercontent.com/transitive-bullshit/ffmpeg-concat/master/media/example.mp4) is the original)* - [![china](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/China.png) **中文/Chinese**](https://github.com/transitive-bullshit/ffmpeg-concat/blob/master/readme.zh.md) ## Intro [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. [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. **This module and CLI make it easy to concat videos together using gl-transitions.** ## Install This module requires [ffmpeg](http://ffmpeg.org/) to be installed. ```bash npm install --save ffmpeg-concat # or if you want to use the CLI npm install -g ffmpeg-concat ``` This package runs on Linux, macOS, and Windows. Node.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. ## CLI ```sh Usage: ffmpeg-concat [options] <videos...> Options: -V, --version output the version number -o, --output <output> path to mp4 file to write (default: out.mp4) -t, --transition-name <name> name of gl-transition to use (default: fade) -d, --transition-duration <duration> duration of transition to use in ms (default: 500) -T, --transitions <file> json file to load transitions from -f, --frame-format <format> format to use for temp frame images (default: raw) -c, --concurrency <number> number of videos to process in parallel (default: 4) -C, --no-cleanup-frames disables cleaning up temp frame images -O, --temp-dir <dir> temporary working directory to store frame data -v, --verbose enable verbose logging from FFmpeg -h, --help output usage information Example: ffmpeg-concat -t circleopen -d 750 -o huzzah.mp4 0.mp4 1.mp4 2.mp4 ``` ## Usage ```js const concat = require('ffmpeg-concat') // concat 3 mp4s together using 2 500ms directionalWipe transitions await concat({ output: 'test.mp4', videos: [ 'media/0.mp4', 'media/1.mp4', 'media/2.mp4' ], transition: { name: 'directionalWipe', duration: 500 } }) ``` ```js // concat 5 mp4s together using 4 different transitions await concat({ output: 'test.mp4', videos: [ 'media/0.mp4', 'media/1.mp4', 'media/2.mp4', 'media/0.mp4', 'media/1.mp4' ], transitions: [ { name: 'circleOpen', duration: 1000 }, { name: 'crossWarp', duration: 800 }, { name: 'directionalWarp', duration: 500, // pass custom params to a transition params: { direction: [ 1, -1 ] } }, { name: 'squaresWire', duration: 2000 } ] }) ``` ## API ### concat(options) Concatenates video files together along with OpenGL transitions. Returns a `Promise` for when the output video has been written. Note that you must specify `videos`, `output`, and either `transition` or `transitions`. Note that the output video's size and fps are determined by the first input video. #### options ##### videos Type: `Array<String>` **Required** Array of videos to concat, where each item is a path or URL to a video file. ##### output Type: `String` **Required** Path to an `mp4` video file to write. Note: we currently only support outputting to mp4; please open an issue if you'd like to see support for more formats. ##### transition Type: `Object` Specifies a default transition to be used between each video. Note 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. ```js // example const transition = { duration: 1000, // ms name: 'directionalwipe', // gl-transition name to use (will match with lower-casing) params: { direction: [1, -1] } // optionally override default parameters } ``` ##### transitions Type: `Array<Object>` Specifies a (possibly unique) transition between each video. If there are N videos, then there should be N - 1 transitions. Note 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. ```js // example const transitions = [ { duration: 1000, name: 'fade' }, { duration: 500, name: 'swap' } ] ``` ##### audio Type: `String` **Optional** Path or URL to an audio file to use as the audio track for the output video. if parameter is not provided - assuming user wants to concat the source scenes audio. ##### args Type: `Array<String>` **Optional** Default: `['-c:v', 'libx264', '-profile:v', 'main', '-preset', 'medium', '-crf 20', '-movflags', 'faststart']` Array of output-only ffmpeg command line arguments for the final video. ##### frameFormat Type: `string` Default: `raw` The format for temporary frame images. You may, for example, use `png` or `jpg`. Note: 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`. ##### concurrency Type: `Number` Default: `4` Max number of videos to process in parallel. ##### log Type: `Function` Default: `noop` Optional function to log progress and the underlying ffmpeg commands. You may, for example, use `console.log` ##### cleanupFrames Type: `boolean` Default: `true` By default, we cleanup temporary frame images. Set this to `false` if you need to debug intermediate results. ##### tempDir Type: `string` Default: random directory in `/tmp` The temporary working directory to store intermediate frame data. This is where the frames in `cleanupFrames` will be saved. ## Transitions Here are some [gl-transitions](https://gl-transitions.com/) that I've found particularly useful for quality video transitions: - [fade](https://gl-transitions.com/editor/fade) - [fadegrayscale](https://gl-transitions.com/editor/fadegrayscale) - [circleopen](https://gl-transitions.com/editor/circleopen) - [directionalwarp](https://gl-transitions.com/editor/directionalwarp) - [directionalwipe](https://gl-transitions.com/editor/directionalwipe) - [crosswarp](https://gl-transitions.com/editor/crosswarp) - [crosszoom](https://gl-transitions.com/editor/CrossZoom) - [dreamy](https://gl-transitions.com/editor/Dreamy) - [squareswire](https://gl-transitions.com/editor/squareswire) - [angular](https://gl-transitions.com/editor/angular) - [radial](https://gl-transitions.com/editor/Radial) - [cube](https://gl-transitions.com/editor/cube) - [swap](https://gl-transitions.com/editor/swap) ## Related - [ffmpeg-gl-transition](https://github.com/transitive-bullshit/ffmpeg-gl-transition) - Low-level ffmpeg filter for applying GLSL transitions between video streams ([gl-transitions](https://gl-transitions.com/)). It allows the use of more advanced and customizable filter graphs, but it requires you to build a custom version of ffmpeg. - [gl-transitions](https://gl-transitions.com/) - Collection of GLSL transitions. - [fluent-ffmpeg](https://github.com/fluent-ffmpeg/node-fluent-ffmpeg) - Underlying ffmpeg wrapper library. - [awesome-ffmpeg](https://github.com/transitive-bullshit/awesome-ffmpeg) - A curated list of awesome ffmpeg resources with a focus on JavaScript. ## License MIT © [Travis Fischer](https://github.com/transitive-bullshit) Support my OSS work by <a href="https://twitter.com/transitive_bs">following me on twitter <img src="https://storage.googleapis.com/saasify-assets/twitter-logo.svg" alt="twitter" height="24px" align="center"></a>