├── .editorconfig
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── Makefile
├── README.md
├── bin
└── videoshow
├── examples
├── audio.js
├── basic.js
├── captions.js
├── logo.js
├── subtitles.js
└── transition.js
├── lib
├── copy.js
├── index.js
├── merge.js
├── mstime.js
├── options.js
├── render.js
├── subrip.js
├── substation.js
├── video.js
└── videoshow.js
├── package-lock.json
├── package.json
└── test
├── cli.js
├── fixtures
├── config.json
├── logo.png
├── norris.gif
├── song.aac
├── song.mp3
├── song.ogg
├── step_1.png
├── step_2.png
├── step_3.png
├── step_4.png
├── step_5.png
├── subtitles.ass
├── subtitles.srt
└── video.jpg
├── subrip.js
├── substation.js
└── videoshow.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [Makefile]
12 | charset = utf-8
13 | indent_style = tabs
14 | indent_size = 2
15 | end_of_line = lf
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
19 | [*.sh]
20 | insert_final_newline = false
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | npm-debug.log
4 | test/.tmp
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | test/fixtures
2 | test/.tmp
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - stable
4 | script: echo 0
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Tomás Aparicio
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | MOCHA = ./node_modules/.bin/mocha
2 |
3 | default: all
4 | all: test
5 | test: mocha
6 |
7 | mocha:
8 | $(MOCHA) --harmony --timeout 300000 --reporter spec --ui tdd
9 |
10 | publish: test
11 | git push --tags origin HEAD:master
12 | npm publish
13 |
14 | loc:
15 | wc -l lib/*
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # videoshow [](https://codeclimate.com/github/h2non/videoshow) [][npm]
2 |
3 |
4 |
5 | Simple utility for **node.js** to **create straightforward video slideshows based on images** using [ffmpeg](http://ffmpeg.org), with additional features such as **audio**, **subtitles** and **fade in/out transitions** between slides.
6 |
7 | To getting started you can take a look to the [examples](https://github.com/h2non/videoshow/tree/master/examples), [programmatic API](#api) and [command-line](#command-line-interface) interface
8 |
9 | videoshow is used in production rendering thousands of videos per month.
10 |
11 | Click on the image to see an example video generated by `videoshow`:
12 |
13 |
14 |
15 |
16 |
17 | ## Requirements
18 |
19 | - **[ffmpeg](http://ffmpeg.org)** with additional compilation flags `--enable-libass --enable-libmp3lame`
20 |
21 | You can download static builds of ffmpeg from [here](http://johnvansickle.com/ffmpeg/).
22 |
23 | If you want to use videoshow in Heroku, you could use the [ffmpeg2](https://github.com/h2non/heroku-buildpack-ffmpeg2) buildpack
24 |
25 | ## Installation
26 |
27 | ```bash
28 | npm install videoshow
29 | ```
30 |
31 | For command-line usage, install it as global package:
32 | ```bash
33 | npm install -g videoshow
34 | ```
35 |
36 | ## Usage
37 |
38 | **NOTE**: images must all have the same dimensions.
39 |
40 | Below you have an example script generating a video based on images and audio.
41 |
42 | Take a look to the [programmatic API](#api) and [examples](examples/) for more usage details.
43 |
44 | ```js
45 | var videoshow = require('videoshow')
46 |
47 | var images = [
48 | 'step1.jpg',
49 | 'step2.jpg',
50 | 'step3.jpg',
51 | 'step4.jpg'
52 | ]
53 |
54 | var videoOptions = {
55 | fps: 25,
56 | loop: 5, // seconds
57 | transition: true,
58 | transitionDuration: 1, // seconds
59 | videoBitrate: 1024,
60 | videoCodec: 'libx264',
61 | size: '640x?',
62 | audioBitrate: '128k',
63 | audioChannels: 2,
64 | format: 'mp4',
65 | pixelFormat: 'yuv420p'
66 | }
67 |
68 | videoshow(images, videoOptions)
69 | .audio('song.mp3')
70 | .save('video.mp4')
71 | .on('start', function (command) {
72 | console.log('ffmpeg process started:', command)
73 | })
74 | .on('error', function (err, stdout, stderr) {
75 | console.error('Error:', err)
76 | console.error('ffmpeg stderr:', stderr)
77 | })
78 | .on('end', function (output) {
79 | console.error('Video created in:', output)
80 | })
81 | ```
82 |
83 | ## Command-line interface
84 |
85 | ```bash
86 | $ videoshow --help
87 | ```
88 |
89 | ```bash
90 | Create video slideshow easily from images
91 | Usage: bin/videoshow [options]
92 |
93 | Options:
94 | --help, -h Show help
95 | --config, -c File path to JSON config file [required]
96 | --audio, -a Optional audio file path
97 | --subtitles, -s Path to .srt subtitles file
98 | --input, -i Add additional input to video
99 | --output, -o Output video file path
100 | --size, -x Video size resolution
101 | --logo, -l Path to logo image
102 | --debug, -d Enable debug mode in error case
103 |
104 | Examples:
105 | bin/videoshow -c config.json video.mp4
106 | bin/videoshow -c config.json --audio song.mp3 video.mp4
107 | bin/videoshow -c config.json --audio song.mp3 --logo logo.png video.mp4
108 | ```
109 |
110 | Example `config.json` file:
111 |
112 | ```json
113 | {
114 | "output": "video.mp4",
115 | "options": {
116 | "fps": 25,
117 | "loop": 5,
118 | "transition": true,
119 | "transitionDuration": 1,
120 | "videoBitrate": 1024,
121 | "videoCodec": "libx264",
122 | "size": "640x?",
123 | "audioBitrate": "128k",
124 | "audioChannels": 2,
125 | "format": "mp4",
126 | "subtitleStyles": {
127 | "Fontname": "Verdana",
128 | "Fontsize": "26",
129 | "PrimaryColour": "11861244",
130 | "SecondaryColour": "11861244",
131 | "TertiaryColour": "11861244",
132 | "BackColour": "-2147483640",
133 | "Bold": "2",
134 | "Italic": "0",
135 | "BorderStyle": "2",
136 | "Outline": "2",
137 | "Shadow": "3",
138 | "Alignment": "1",
139 | "MarginL": "40",
140 | "MarginR": "60",
141 | "MarginV": "40"
142 | }
143 | },
144 | "images": [
145 | "./test/fixtures/step_1.png",
146 | "./test/fixtures/step_2.png",
147 | "./test/fixtures/step_3.png",
148 | "./test/fixtures/step_4.png",
149 | "./test/fixtures/step_5.png"
150 | ]
151 | }
152 | ```
153 |
154 | ## API
155 |
156 | ### `videoshow(images, [ options ])`
157 | Return: `Videoshow`
158 |
159 | Videoshow constructor. You should pass an `array` or `array