ilove-videoshow
v1.0.0
Published
Simple command-line and programmatic interface to create videos slideshows from images using ffmpeg
Maintainers
Readme
videoshow
Simple utility for node.js to create straightforward video slideshows based on images using ffmpeg, with additional features such as audio, subtitles and fade in/out transitions between slides.
To getting started you can take a look to the examples, programmatic API and command-line interface
videoshow is used in production rendering thousands of videos per month.
Click on the image to see an example video generated by videoshow
:
Requirements
- ffmpeg with additional compilation flags
--enable-libass --enable-libmp3lame
You can download static builds of ffmpeg from here.
If you want to use videoshow in Heroku, you could use the ffmpeg2 buildpack
Installation
npm install videoshow
For command-line usage, install it as global package:
npm install -g videoshow
Usage
NOTE: images must all have the same dimensions.
Below you have an example script generating a video based on images and audio.
Take a look to the programmatic API and examples for more usage details.
var videoshow = require('videoshow')
var images = [
'step1.jpg',
'step2.jpg',
'step3.jpg',
'step4.jpg'
]
var videoOptions = {
fps: 25,
loop: 5, // seconds
transition: true,
transitionDuration: 1, // seconds
videoBitrate: 1024,
videoCodec: 'libx264',
size: '640x?',
audioBitrate: '128k',
audioChannels: 2,
format: 'mp4',
pixelFormat: 'yuv420p'
}
videoshow(images, videoOptions)
.audio('song.mp3')
.save('video.mp4')
.on('start', function (command) {
console.log('ffmpeg process started:', command)
})
.on('error', function (err, stdout, stderr) {
console.error('Error:', err)
console.error('ffmpeg stderr:', stderr)
})
.on('end', function (output) {
console.error('Video created in:', output)
})
Command-line interface
$ videoshow --help
Create video slideshow easily from images
Usage: bin/videoshow [options]
Options:
--help, -h Show help
--config, -c File path to JSON config file [required]
--audio, -a Optional audio file path
--subtitles, -s Path to .srt subtitles file
--input, -i Add additional input to video
--output, -o Output video file path
--size, -x Video size resolution
--logo, -l Path to logo image
--debug, -d Enable debug mode in error case
Examples:
bin/videoshow -c config.json video.mp4
bin/videoshow -c config.json --audio song.mp3 video.mp4
bin/videoshow -c config.json --audio song.mp3 --logo logo.png video.mp4
Example config.json
file:
{
"output": "video.mp4",
"options": {
"fps": 25,
"loop": 5,
"transition": true,
"transitionDuration": 1,
"videoBitrate": 1024,
"videoCodec": "libx264",
"size": "640x?",
"audioBitrate": "128k",
"audioChannels": 2,
"format": "mp4",
"subtitleStyles": {
"Fontname": "Verdana",
"Fontsize": "26",
"PrimaryColour": "11861244",
"SecondaryColour": "11861244",
"TertiaryColour": "11861244",
"BackColour": "-2147483640",
"Bold": "2",
"Italic": "0",
"BorderStyle": "2",
"Outline": "2",
"Shadow": "3",
"Alignment": "1",
"MarginL": "40",
"MarginR": "60",
"MarginV": "40"
}
},
"images": [
"./test/fixtures/step_1.png",
"./test/fixtures/step_2.png",
"./test/fixtures/step_3.png",
"./test/fixtures/step_4.png",
"./test/fixtures/step_5.png"
]
}
API
videoshow(images, [ options ])
Return: Videoshow
Videoshow constructor. You should pass an array<string>
or array<object>
or array<ReadableStream>
with the desired images,
and optionally passing the video render options
object per each image.
Image formats supported are: jpg
, png
or bmp
.
videoshow([ 'image1.jpg', 'image2.jpg', 'image3.jpg'])
.save('video.mp4')
.on('error', function () {})
.on('end', function () {})
images
param could be a collection as well:
videoshow([{
path: 'image1.jpg',
caption: 'Hello world as video subtitle'
}, {
path: 'image2.jpg',
caption: 'This is a sample subtitle',
loop: 10 // long caption
}])
.save('video.mp4')
.on('error', function () {})
.on('end', function () {})
Video options
You can define as option any method name allowed by fluent-ffmpeg
Default options are:
{
fps: 25,
loop: 5, // seconds
transition: true,
transitionDuration: 1,
captionDelay: 1000,
useSubRipSubtitles: false,
subtitleStyle: null,
videoBitrate: 1024,
videoCodec: 'libx264',
size: '640x?',
audioBitrate: '128k',
audioChannels: 2,
format: 'mp4'
}
Options details:
- captionDelay
number
- Miliseconds to delay the show/hide of the caption. Default to1000
- useSubRipSubtitles
boolean
- Use SubRip subtitles format. It uses by default SSA/ASS. Defaultfalse
- subtitleStyle
object
- SSA/ASS subtitles style. See substation.js and fixture file for allowed params
Image options
- path
string
- File path to image - loop
number
- Image slide duration in seconds. Default to5
- transition
boolean
- Enable fade in/out transition for the current image - transitionDuration
number
- Fade in/out transition duration in seconds. Default to1
- transitionColor
string
- Fade in/out transition background color. Default toblack
. See supported colors - filters
array<string|object>
- Add custom ffmpeg video filters to the image slide. - disableFadeOut
boolean
- If transition is enable, disable the fade out. Defaultfalse
- disableFadeIn
boolean
- If transition is enable, disable the fade in. Defaultfalse
- caption
string
- Caption text as subtitle. It allows a limited set of HTML tags. See Subrip - captionDelay
number
- Miliseconds to delay the show/hide of the caption. Default to1000
- captionStart
number
- Miliseconds to start the caption. Default to1000
- captionEnd
number
- Miliseconds to remove the caption. Default toloop - 1000
- logo
string
- Path to logo image. Seelogo()
method
videoshow#image(image)
Push an image to the video. You can pass an string
as path to the image,
or a plain object
with image options
videoshow#audio(path [, params ])
Define the audio file path to use.
It supports multiple formats and codecs such as acc
, mp3
or ogg
Supported params:
- delay
number
- Delay audio start in seconds. Default to0
seconds - fade
boolean
- Enable audio fade in/out effect. Defaulttrue
videoshow#logo(path [, params ])
Add a custom image as logo in the left-upper corner by default. You can customize the position by x/y
axis.
It must be a png
or jpeg
image
Supported params:
- start
number
- Video second to show the logo. Default5
seconds - end
number
- Video second to remove the logo. DefaulttotalLength - 5
seconds - xAxis
number
- Logox
axis position. Default10
- yAxis
number
- Logoy
axis position. Default10
videoshow#subtitles(path)
Define the SubRip subtitles or SubStation Alpha (SSA/ASS)
file path to load. It should be a .str
or .ass
file respectively
See fixtures for examples
videoshow#save(path)
Return: EventEmitter
Alias: render
Render and write in disk the resultant video in the given path
Supported events for subscription:
- start
cmd
- Fired when ffmpeg process started - error
error, stdout, stderr
- Fired when transcoding error happens - progress
data
- Fired with transcoding progress information - codecData
codec
- Fired when input codec data is available - end
videoPath
- Fired when the process finish successfully
For more information, see the ffmpeg docs
videoshow#input(input)
Add input file to video. By default you don't need to call this method
videoshow#filter(filter)
Add a custom video filter to the video. See the docs
videoshow#complexFilter(filter)
Add a custom complex filter to the video. See the docs
videoshow#loop(seconds)
Default image loop time in seconds. Default to 5
videoshow#size(resolution)
Video size resolution. Default to 640x?
.
See the docs
videoshow#aspect(aspect)
Video aspect ration. Default autocalculated from video size
param.
See the docs
videoshow#options(options)
Alias: flags
Add a set of video output options as command-line flag.
options
argument should be an array.
See the docs
videoshow#option(argument)
Alias: flag
Add a custom output option as command-line flag to pass to ffmpeg
videoshow#options(arguments)
Alias: flags
Add multiple output options as command-line flags to pass to ffmpeg
.
The argument must be an array
videoshow.VERSION
Type: string
Current package semantic version
videoshow.ffmpeg
Type: function
fluent-ffmpeg API constructor
License
MIT © Tomas Aparicio