Skip to content

Commit

Permalink
feat: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
h2non committed Feb 7, 2015
1 parent 01d56a1 commit 93e2f3b
Show file tree
Hide file tree
Showing 33 changed files with 646 additions and 5 deletions.
20 changes: 20 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

[Makefile]
charset = utf-8
indent_style = tabs
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

[*.sh]
insert_final_newline = false
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.DS_Store
npm-debug.log
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test/fixtures
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: node_js
node_js:
- "0.10"
- "0.12"
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
MOCHA = ./node_modules/.bin/mocha

default: all
all: test
test: mocha

mocha:
$(MOCHA) --harmony --timeout 300000 --reporter spec --ui tdd

publish: test
git push --tags origin HEAD:master
npm publish

loc:
wc -l lib/*
109 changes: 106 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,110 @@
# photoshow
# videoshow [![Build Status](https://api.travis-ci.org/h2non/videoshow.svg?branch=master)][travis] [![Dependency Status](https://gemnasium.com/h2non/videoshow.svg)][gemnasium] [![Code Climate](https://codeclimate.com/github/h2non/videoshow/badges/gpa.svg)](https://codeclimate.com/github/h2non/videoshow) [![NPM](https://img.shields.io/npm/v/videoshow.svg)][npm]

Funny programmatic interface to create video slides from images using ffmpeg and node.js/io.js
Simple programmatic interface for node/io.js to create basic video slides from images using [ffmpeg](http://ffmpeg.org)

With `videoshow` you to create videos form images with audio, subtitles and fade-in/out transitions.
Take a look to the [examples](https://github.com/h2non/videoshow/tree/master/examples) to see the supported features

Still beta

## Requirements

- **[ffmpeg](http://ffmpeg.org)** with additional compilation flags `--enable-libass --enable-libmp3lame --enable-libx264`

## Installation

```bash
npm install videoshow
```

## Usage

```js
var videoshow = require('videoshow')

var images = [
'step1.jpg',
'step2.jpg',
'step3.jpg',
'step4.jpg'
]

var videoOptions = {
fps: 25,
loop: 5, // seconds
videoBitrate: 1024,
videoCodec: 'libx264',
size: '640x?',
audioBitrate: '128k',
audioChannels: 2,
format: 'mp4'
}

videoshow(images, videoOptions)
.audio('song.mp3')
.save('video.mp4')
```

## 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

```js
videoshow([ 'image1.jpg', 'image2.jpg', 'image'])
.save('video.mp4')
.on('error', function () {})
.on('end', function () {})
```

##### videoshow#audio(path)

Define the audio file path to use. It supports multiple formats and codecs such as `acc`, `mp3` or `ogg`

##### videoshow#subtitles(path)

Define the [SubRip subtitles](http://en.wikipedia.org/wiki/SubRip#SubRip_text_file_format)
file path to load. It should be a `.srt` file

##### videoshow#save(path)
Return: `EventEmitter`

Render and write the final video in the given path

##### videoshow#filter(filter)

Add custom filter to the video

##### videoshow#imageOptions(options)

Add specific image rendering options

##### videoshow#options(options)

Add custom video rendering options

##### videoshow#flag(argument)

Add a custom CLI flag to pass to `ffmpeg`

#### videoshow.VERSION
Type: `string`

Current package semantic version

#### videoshow.ffmpeg
Type: `function`

[fluent-ffmpeg](https://github.com/fluent-ffmpeg/node-fluent-ffmpeg) API constructor

## License

MIT - Tomas Aparicio and contributors
[MIT](http://opensource.org/licenses/MIT) © Tomas Aparicio

[travis]: http://travis-ci.org/h2non/videoshow
[gemnasium]: https://gemnasium.com/h2non/videoshow
[npm]: http://npmjs.org/package/videoshow
21 changes: 21 additions & 0 deletions examples/audio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
var videoshow = require('../')

var audio = __dirname + '/../test/fixtures/song.mp3'

var images = [
__dirname + '/../test/fixtures/step_1.png',
__dirname + '/../test/fixtures/step_2.png',
__dirname + '/../test/fixtures/step_3.png',
__dirname + '/../test/fixtures/step_4.png',
__dirname + '/../test/fixtures/step_5.png'
]

videoshow(images)
.save('audio.mp4')
.audio(audio)
.on('error', function (err) {
console.error('Error:', err)
})
.on('end', function (output) {
console.log('Video created in:', output)
})
18 changes: 18 additions & 0 deletions examples/basic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var videoshow = require('../')

var images = [
__dirname + '/../test/fixtures/step_1.png',
__dirname + '/../test/fixtures/step_2.png',
__dirname + '/../test/fixtures/step_3.png',
__dirname + '/../test/fixtures/step_4.png',
__dirname + '/../test/fixtures/step_5.png'
]

videoshow(images)
.save('test.mp4')
.on('error', function (err) {
console.error('Error:', err)
})
.on('end', function (output) {
console.log('Video created in:', output)
})
22 changes: 22 additions & 0 deletions examples/subtitles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var videoshow = require('../')

var subtitles = __dirname + '/../test/fixtures/subtitles.srt'
var audio = __dirname + '/../test/fixtures/song.mp3'

var images = [
__dirname + '/../test/fixtures/step_1.png',
__dirname + '/../test/fixtures/step_2.png',
__dirname + '/../test/fixtures/step_3.png',
__dirname + '/../test/fixtures/step_4.png',
__dirname + '/../test/fixtures/step_5.png'
]

videoshow(images)
.save('audio.mp4')
.audio(audio)
.on('error', function (err) {
console.error('Error:', err)
})
.on('end', function (output) {
console.log('Video created in:', output)
})
8 changes: 8 additions & 0 deletions lib/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var fs = require('fs')

module.exports = function copy(src, dest, cb) {
fs.createReadStream(src)
.on('error', cb)
.on('end', cb)
.pipe(fs.createWriteStream(dest))
}
12 changes: 12 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var ffmpeg = require('fluent-ffmpeg')
var Videoshow = require('./videoshow')
var pkg = require('../package.json')

module.exports = videoshow

function videoshow(images, options) {
return new Videoshow(images, options)
}

videoshow.VERSION = pkg.version
videoshow.ffmpeg = ffmpeg
25 changes: 25 additions & 0 deletions lib/merge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var os = require('os')
var ffmpeg = require('fluent-ffmpeg')

module.exports = merge

function merge(parts, output, options) {
parts = parts.slice()
var video = ffmpeg(parts.shift())

parts.forEach(function (part) {
video.input(part)
})

if (options) {
Object.keys(options).forEach(function (key) {
if (typeof video[key] === 'function') {
video[key](options[key])
}
})
}

video.mergeToFile(output, os.tmpdir())

return video
}
18 changes: 18 additions & 0 deletions lib/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var merge = require('lodash.merge')

var defaults = {
fps: 25,
loop: 5,
videoBitrate: 1024,
videoCodec: 'libx264',
size: '640x?',
audioBitrate: '128k',
audioChannels: 2,
format: 'mp4'
}

exports = module.exports = function (options) {
return merge({}, defaults, options)
}

exports.defaults = defaults
Loading

0 comments on commit 93e2f3b

Please sign in to comment.