Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
This GIF / YouTube was created with this command: "editly commonFeatures.json5". See more examples here.
Editly is a tool and framework for declarative NLE (non-linear video editing) using Node.js and ffmpeg. Editly allows you to easily and programmatically create a video from a set of clips, images, audio and titles, with smooth transitions and music overlaid.
Editly has a simple CLI for quickly assembling a video from a set of clips or images, or you can use its more flexible JavaScript API.
Inspired by ffmpeg-concat, editly is much faster and doesn't require much storage because it uses streaming editing. Editly aims to be very extensible and feature rich with a pluggable interface for adding new dynamic content.
cutFrom
/cutTo
segment length with each clip's duration
Video must be 1337x1000 30fps
)See examples
Make sure you have ffmpeg
and ffprobe
installed and available in PATH
npm i -g editly
Run editly --help
for usage
Create a simple randomized video edit from videos, images and text with an audio track:
editly \
title:'My video' \
clip1.mov \
clip2.mov \
title:'My slideshow' \
img1.jpg \
img2.jpg \
title:'THE END' \
--fast \
--audio-file-path /path/to/music.mp3
Or create an MP4 (or GIF) from a JSON or JSON5 edit spec (JSON5 is just a more friendly JSON format):
editly my-editly.json5 --fast --out output.gif
For examples of how to make a JSON edit spec, see below or https://github.com/mifi/editly/tree/master/examples
When you run with --fast
or fast: true
, it will render a much quicker low-resolution preview ⏩
Without --fast
it will default to using the width, height and frame rate from the first input video. All other clips will be converted to these dimensions. You can of course override any or all of these parameters.
TIP: Use this tool in conjunction with LosslessCut
TIP: If you need catchy music for your video, have a look at this YouTube or the YouTube audio library. Then use youtube-dl to download the video, and then point --audio-file-path
at the video file. Be sure to respect their license!
const editly = require('editly');
// See editSpec documentation
await editly(editSpec)
.catch(console.error);
Edit specs are JavaScript / JSON objects describing the whole edit operation with the following structure:
{
outPath,
width,
height,
fps,
defaults: {
duration: 4,
transition: {
duration: 0.5,
name: 'random',
audioOutCurve: 'tri',
audioInCurve: 'tri',
},
layer: {
fontPath,
// ...more layer defaults
},
layerType: {
'fill-color': {
color: '#ff6666',
}
// ...more per-layer-type defaults
},
},
audioFilePath,
loopAudio: false,
keepSourceAudio: false,
allowRemoteRequests: false,
clips: [
{
transition,
duration,
layers: [
{
type,
// ...more layer-specific options
}
// ...more layers
],
}
// ...more clips
],
// Testing options:
enableFfmpegLog: false,
verbose: false,
fast: false,
}
Parameter | CLI equivalent | Description | Default | |
---|---|---|---|---|
outPath | --out | Output path (mp4, mkv), can also be a .gif | ||
width | --width | Width which all media will be converted to | 640 | |
height | --height | Height which all media will be converted to | auto based on width and aspect ratio of first video | |
fps | --fps | FPS which all videos will be converted to | First video FPS or 25 | |
audioFilePath | --audio-file-path | Set an audio track for the whole video | ||
loopAudio | --loop-audio | Loop the audio track if it is shorter than video? | false | |
keepSourceAudio | --keep-source-audio | Keep audio from source files | false | |
allowRemoteRequests | --allow-remote-requests | Allow remote URLs as paths | false | |
fast | --fast , -f | Fast mode (low resolution and FPS, useful for getting a quick preview) | false | |
defaults.layer.fontPath | --font-path | Set default font to a .ttf | System font | |
defaults.layer.* | Set any layer parameter that all layers will inherit | |||
defaults.duration | --clip-duration | Set default clip duration for clips that don't have an own duration | 4 | sec |
defaults.transition | An object { name, duration } describing the default transition. Set to null to disable transitions | |||
defaults.transition.duration | --transition-duration | Default transition duration | 0.5 | sec |
defaults.transition.name | --transition-name | Default transition type. See Transition types | random | |
defaults.transition.audioOutCurve | Default fade out curve in audio cross fades | tri | ||
defaults.transition.audioInCurve | Default fade in curve in audio cross fades | tri | ||
clips[] | List of clip objects that will be played in sequence. Each clip can have one or more layers. | |||
clips[].duration | Clip duration. See defaults.duration . If unset, the clip duration will be that of the first video layer. | defaults.duration | ||
clips[].transition | Specify transition at the end of this clip. See defaults.transition | defaults.transition | ||
clips[].layers[] | List of layers within the current clip that will be overlaid in their natural order (final layer on top) | |||
clips[].layers[].type | Layer type, see below | |||
clips[].layers[].visibleFrom | What time into the clip should this layer start | sec | ||
clips[].layers[].visibleUntil | What time into the clip should this layer stop | sec |
transition.name
can be any of gl-transitions, or any of the following: directional-left
, directional-right
, directional-up
, directional-down
, random
or dummy
.
See examples and commonFeatures.json5
For video layers, if parent clip.duration
is specified, the video will be slowed/sped-up to match clip.duration
. If cutFrom
/cutTo
is set, the resulting segment (cutTo
-cutFrom
) will be slowed/sped-up to fit clip.duration
. If the layer has audio, it will be kept (and mixed with other audio layers if present.)
Parameter | Description | Default | |
---|---|---|---|
path | Path to video file | ||
resizeMode | See Resize modes | ||
cutFrom | Time value to cut from | 0 | sec |
cutTo | Time value to cut to | end of video | sec |
width | Width relative to screen width | 1 | 0 to 1 |
height | Height relative to screen height | 1 | 0 to 1 |
left | X-position relative to screen width | 0 | 0 to 1 |
top | Y-position relative to screen height | 0 | 0 to 1 |
originX | X anchor | left | left or right |
originY | Y anchor | top | top or bottom |
mixVolume | Relative volume when mixing this video's audio track with others | 1 |
Audio layers will be mixed together. If cutFrom
/cutTo
is set, the resulting segment (cutTo
-cutFrom
) will be slowed/sped-up to fit clip.duration
. The slow down/speed-up operation is limited to values between 0.5x
and 100x
.
Parameter | Description | Default | |
---|---|---|---|
path | Path to audio file | ||
cutFrom | Time value to cut from | 0 | sec |
cutTo | Time value to cut to | clip.duration | sec |
mixVolume | Relative volume when mixing this audio track with others | 1 |
Full screen image
Parameter | Description | Default | |
---|---|---|---|
path | Path to image file | ||
resizeMode | See Resize modes |
See also See Ken Burns parameters.
Image overlay with a custom position and size on the screen.
Parameter | Description | Default | |
---|---|---|---|
path | Path to image file | ||
position | See Position parameter | ||
width | Width (from 0 to 1) where 1 is screen width | ||
height | Height (from 0 to 1) where 1 is screen height |
See also Ken Burns parameters.
fontPath
- See defaults.layer.fontPath
text
- Title text to show, keep it shorttextColor
- default #ffffff
position
- See Position parameterSee also Ken Burns parameters
fontPath
- See defaults.layer.fontPath
text
- Subtitle text to showtextColor
- default #ffffff
Title with background
text
- See type title
textColor
- See type title
background
- { type, ... }
- See type radial-gradient
, linear-gradient
or fill-color
fontPath
- See type title
fontPath
- See defaults.layer.fontPath
text
textColor
- default #ffffff
backgroundColor
- default #d02a42
position
- See Position parameterfontPath
- See defaults.layer.fontPath
text
fontSize
charSpacing
color
position
- See Position parametercolor
- Color to fill background, default: randomizecolors
- Array of two colors, default: randomizecolors
- Array of two colors, default: randomize🌈🌈🌈
See customCanvas.js
func
- Custom JavaScript functionSee customFabric.js
func
- Custom JavaScript functionLoads a GLSL shader. See gl.json5 and rainbow-colors.frag
fragmentPath
vertexPath
(optional)resizeMode
- How to fit image to screen. Can be one of:
contain
- All the video will be contained within the frame and letterboxedcontain-blur
- Like contain
, but with a blurred copy as the letterboxcover
- Video be cropped to cover the whole screen (aspect ratio preserved)stretch
- Video will be stretched to cover the whole screen (aspect ratio ignored).Default contain-blur
.
See:
Certain layers support the position parameter
position
can be one of either:
top
, bottom
center
, top-left
, top-right
, center-left
, center-right
, bottom-left
, bottom-right
{ x, y, originX = 'left', originY = 'top' }
, where { x: 0, y: 0 }
is the upper left corner of the screen, and { x: 1, y: 1 }
is the lower right corner, x
is relative to video width, y
to video height. originX
and originY
are optional, and specify the position's origin (anchor position) of the object.See position.json5
Parameter | Description | Default | |
---|---|---|---|
zoomDirection | Zoom direction for Ken Burns effect: in , out or null to disable | ||
zoomAmount | Zoom amount for Ken Burns effect | 0.1 |
Error: The specified module could not be found.
, try: npm un -g editly && npm i -g --build-from-source editly
(see #15)/bin/sh: pkg-config: command not found
, try to use newest Node.js LTS versionThis project is maintained by me alone. The project will always remain free and open source, but if it's useful for you, consider supporting me. :) It will give me extra motivation to improve it.
Made with ❤️ in 🇳🇴
Follow me on GitHub, YouTube, IG, Twitter for more awesome content!
FAQs
Simple, sexy, declarative video editing
The npm package editly receives a total of 124 weekly downloads. As such, editly popularity was classified as not popular.
We found that editly demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.