diff --git a/index.js b/index.js index 79c3a7e..2640dfc 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,15 @@ const probe = require('ffmpeg-probe') const noop = () => { } +const applyVFList = (cmd, list) => { + if (!Array.isArray(list) || list.length === 0) { + return + } + cmd.outputOptions([ + '-vf', list.join(',') + ]) +} + module.exports = async (opts) => { const { log = noop, @@ -19,7 +28,10 @@ module.exports = async (opts) => { offsets, fps, numFrames, - ffmpegPath + ffmpegPath, + forceSARRatio, + startOffset, + duration, } = opts if (!input) throw new Error('missing required input') @@ -34,10 +46,26 @@ module.exports = async (opts) => { const cmd = ffmpeg(input) .on('start', (cmd) => log({ cmd })) + const vfList = [] + + if (Boolean(forceSARRatio)) { + vfList.push('scale=iw*sar:ih') + } + + if (startOffset) { + cmd.addInputOptions(["-ss", parseInt(startOffset, 10)]); + } + + if (duration) { + cmd.addInputOptions(["-t", parseInt(duration, 10)]); + } + if (timestamps || offsets) { const folder = outputPath.dir const filename = outputPath.base + applyVFList(cmd, vfList) + return new Promise((resolve, reject) => { cmd .on('end', () => resolve(output)) @@ -55,13 +83,16 @@ module.exports = async (opts) => { ]) } else if (numFrames) { const info = await probe(input) - const numFramesTotal = parseInt(info.streams[0].nb_frames) + let numFramesTotal = parseInt(info.streams[0].nb_frames) + if (isNaN(numFramesTotal)) { + numFramesTotal = Math.ceil((info.duration / 1000) * info.fps); + } const nthFrame = (numFramesTotal / numFrames) | 0 cmd.outputOptions([ '-vsync', 'vfr', - '-vf', `select=not(mod(n\\,${nthFrame}))` ]) + vfList.push(`select=not(mod(n\\,${nthFrame}))`) } if (outputPath.ext === '.raw') { @@ -70,6 +101,9 @@ module.exports = async (opts) => { ]) } + + applyVFList(cmd, vfList) + return new Promise((resolve, reject) => { cmd .on('end', () => resolve(output)) diff --git a/package.json b/package.json index 5fba57c..091b465 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,16 @@ { "name": "ffmpeg-extract-frames", - "version": "2.0.2", + "version": "2.0.3", "description": "Extracts frames from a video.", "main": "index.js", "repository": "transitive-bullshit/ffmpeg-extract-frames", "author": "Travis Fischer ", + "contributors": [ + { + "name" : "Adam Hunter" + , "url" : "https://github.com/adamrhunter" + } + ], "license": "MIT", "reveal": true, "scripts": { diff --git a/readme.md b/readme.md index 4ecef21..0026de3 100644 --- a/readme.md +++ b/readme.md @@ -4,6 +4,8 @@ [![NPM](https://img.shields.io/npm/v/ffmpeg-extract-frames.svg)](https://www.npmjs.com/package/ffmpeg-extract-frames) [![Build Status](https://travis-ci.com/transitive-bullshit/ffmpeg-extract-frames.svg?branch=master)](https://travis-ci.com/transitive-bullshit/ffmpeg-extract-frames) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) +> This is a fork from the orginal (which seemed to have stopped accpeting PRs). I've added some additional parameters/options to pass into the process (and fixed some bugs with frame offsets) + ## Install ```bash @@ -113,6 +115,25 @@ Type: `String` Specify a path for the ffmpeg binary. +##### forceSARRatio + +Type: `Boolean` +Default: false + +Force ffmpeg to use `scale=iw*sar:ih` video filter to use SampleAspectRatio as aspect ratio for thumbnail images. + +##### startOffset + +Type: `Number` + +Start the frame extraction from the given offset (in seconds) + +##### duration + +Type: `Number` + +Run the extraction for only the given duration (in seconds) + ## Related - [ffmpeg-extract-frame](https://github.com/transitive-bullshit/ffmpeg-extract-frame) - Extracts a single frame from a video.