1
0
mirror of https://github.com/musix-org/musix-oss synced 2025-06-17 01:16:00 +00:00
This commit is contained in:
MatteZ02
2020-03-03 22:30:50 +02:00
parent edfcc6f474
commit 30022c7634
11800 changed files with 1984416 additions and 1 deletions

2
node_modules/ffmpeg/.npmignore generated vendored Normal file
View File

@ -0,0 +1,2 @@
/nbproject/private/
/nbproject/

349
node_modules/ffmpeg/README.md generated vendored Normal file
View File

@ -0,0 +1,349 @@
node-ffmpeg
===========
[FFmpeg](http://ffmpeg.org/) module for [Node](http://nodejs.org/). This library provides a set of functions and utilities to abstract commands-line usage of ffmpeg. To use this library requires that ffmpeg is already installed (including all necessary encoding libraries like libmp3lame or libx264)
You can install this module using [npm](http://github.com/isaacs/npm):
npm install ffmpeg
## Usage
To start using this library, you must include it in your project and then you can either use the callback function or through the [promise](https://github.com/cujojs/when) library:
var ffmpeg = require('ffmpeg');
Use the callback function
try {
new ffmpeg('/path/to/your_movie.avi', function (err, video) {
if (!err) {
console.log('The video is ready to be processed');
} else {
console.log('Error: ' + err);
}
});
} catch (e) {
console.log(e.code);
console.log(e.msg);
}
Use the approach with the library promise
try {
var process = new ffmpeg('/path/to/your_movie.avi');
process.then(function (video) {
console.log('The video is ready to be processed');
}, function (err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e.code);
console.log(e.msg);
}
## The video object
Each time you create a new instance, this library provides a new object to retrieve the information of the video, the ffmpeg configuration and all methods to make the necessary conversions:
try {
var process = new ffmpeg('/path/to/your_movie.avi');
process.then(function (video) {
// Video metadata
console.log(video.metadata);
// FFmpeg configuration
console.log(video.info_configuration);
}, function (err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e.code);
console.log(e.msg);
}
## Preset functions
The video object contains a set of functions that allow you to perform specific operations independent of the settings for the conversion. In all the functions you can use the approach with the callback function or with the promise object
### *video.fnExtractSoundToMP3 (destionationFileName, callback)*
This function extracts the audio stream of a video into an mp3 file
Params:
* __destionationFileName__: Full path of the new file:
> /path/to/your_audio_file.mp3
* __callback__: *(optional)* If specified at the end of the process it will return the path of the new audio file:
> function (error, file)
Example:
try {
var process = new ffmpeg('/path/to/your_movie.avi');
process.then(function (video) {
// Callback mode
video.fnExtractSoundToMP3('/path/to/your_audio_file.mp3', function (error, file) {
if (!error)
console.log('Audio file: ' + file);
});
}, function (err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e.code);
console.log(e.msg);
}
### *video.fnExtractFrameToJPG(destinationFolder, settings, callback)*
This function takes care of extracting one or more frames from the video that is being developed. At the end of the operation will return an array containing the list of extracted images
Params:
* __destinationFolder__: Destination folder for the frames generated:
> /path/to/save_your_frames
* __settings__: *(optional)* Settings to change the default settings:
{
start_time : null // Start time to recording
, duration_time : null // Duration of recording
, frame_rate : null // Number of the frames to capture in one second
, size : null // Dimension each frame
, number : null // Total frame to capture
, every_n_frames : null // Frame to capture every N frames
, every_n_seconds : null // Frame to capture every N seconds
, every_n_percentage : null // Frame to capture every N percentage range
, keep_pixel_aspect_ratio : true // Mantain the original pixel video aspect ratio
, keep_aspect_ratio : true // Mantain the original aspect ratio
, padding_color : 'black' // Padding color
, file_name : null // File name
}
* __callback__: *(optional)* If specified at the end of the process will be returned list of paths of frames created:
> function (error, files)
Example:
try {
var process = new ffmpeg('/path/to/your_movie.avi');
process.then(function (video) {
// Callback mode
video.fnExtractFrameToJPG('/path/to/save_your_frames', {
frame_rate : 1,
number : 5,
file_name : 'my_frame_%t_%s'
}, function (error, files) {
if (!error)
console.log('Frames: ' + files);
});
}, function (err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e.code);
console.log(e.msg);
}
### *video.fnAddWatermark(watermarkPath, newFilepath, settings, callback)*
This function takes care of adding a watermark to the video that is being developed. You can specify the exact position in which position the image
Params:
* __watermarkPath__: The full path where the image is stored to add as watermark:
> /path/to/retrieve/watermark_file.png
* __newFilepath__: *(optional)* Name of the new video. If not specified will be created by the function:
> /path/to/save/your_file_video.mp4
* __settings__: *(optional)* Settings to change the default settings:
{
position : "SW" // Position: NE NC NW SE SC SW C CE CW
, margin_nord : null // Margin nord
, margin_sud : null // Margin sud
, margin_east : null // Margin east
, margin_west : null // Margin west
};
* __callback__: *(optional)* If specified at the end of the process it will return the path of the new video containing the watermark:
> function (error, files)
Example:
try {
var process = new ffmpeg('/path/to/your_movie.avi');
process.then(function (video) {
// Callback mode
video.fnAddWatermark('/path/to/retrieve/watermark_file.png', '/path/to/save/your_file_video.mp4', {
position : 'SE'
}, function (error, file) {
if (!error)
console.log('New video file: ' + file);
});
}, function (err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e.code);
console.log(e.msg);
}
## Custom settings
In addition to the possibility of using the preset, this library provides a variety of settings with which you can modify to your liking settings for converting video
* __video.setDisableAudio()__: Disables audio encoding
* __video.setDisableVideo()__: Disables video encoding
* __video.setVideoFormat(format)__: Sets the new video format. Example:
video.setVideoFormat('avi')
* __video.setVideoCodec(codec)__: Sets the new audio codec. Example:
video.setVideoCodec('mpeg4')
* __video.setVideoBitRate(bitrate)__: Sets the video bitrate in kb. Example:
video.setVideoBitRate(1024)
* __video.setVideoFrameRate(framerate)__: Sets the framerate of the video. Example:
video.setVideoFrameRate(25)
* __video.setVideoStartTime(time)__: Sets the start time. You can specify the value in seconds or in date time format. Example:
// Seconds
video.setVideoStartTime(13)
// Date time format
video.setVideoStartTime('00:00:13')
* __video.setVideoDuration(duration)__: Sets the duration. You can specify the value in seconds or in date time format. Example:
// Seconds
video.setVideoDuration(100)
// Date time format
video.setVideoDuration('00:01:40')
* __video.setVideoAspectRatio(aspect)__: Sets the new aspetc ratio. You can specify the value with a number or with a string in the format 'xx:xx'. Example:
// Value
video.setVideoAspectRatio(1.77)
// Format xx:xx
video.setVideoAspectRatio('16:9')
* __video.setVideoSize(size, keepPixelAspectRatio, keepAspectRatio, paddingColor)__: Set the size of the video. This library can handle automatic resizing of the video. You can also apply a padding automatically keeping the original aspect ratio
The following size formats are allowed to be passed to _size_:
> 640x480 _Fixed size (plain ffmpeg way)_
> 50% _Percental resizing_
> ?x480 _Fixed height, calculate width_
> 640x? _Fixed width, calculate height_
Example:
// In this example, the video will be automatically resized to 640 pixels wide and will apply a padding white
video.setVideoSize('640x?', true, true, '#fff')
// In this example, the video will be resized to 640x480 pixel, and if the aspect ratio is different the video will be stretched
video.setVideoSize('640x480', true, false)
* __video.setAudioCodec(codec)__: Sets the new audio codec. Example:
video.setAudioCodec('libfaac')
* __video.setAudioFrequency(frequency)__: Sets the audio sample frequency for audio outputs in kb. Example:
video.setAudioFrequency(48)
* __video.setAudioChannels(channel)__: Sets the number of audio channels. Example:
video.setAudioChannels(2)
* __video.setAudioBitRate(bitrate)__: Sets the audio bitrate in kb. Example:
video.setAudioBitRate(128)
* __video.setAudioQuality(quality)__: Sets the audio quality. Example:
video.setAudioQuality(128)
* __video.setWatermark(watermarkPath, settings)__: Sets the watermark. You must specify the path where the image is stored to be inserted as watermark
The possible settings (the values shown are the default):
* **position : "SW"**
Position: NE NC NW SE SC SW C CE CW
* **margin_nord : null**
Margin nord (specify in pixel)
* **margin_sud : null**
Margin sud (specify in pixel)
* **margin_east : null**
Margin east (specify in pixel)
* **margin_west : null**
Margin west (specify in pixel)
Example:
// In this example will be added the watermark at the bottom right of the video
video.setWatermark('/path/to/retrieve/watermark_file.png')
## Add custom options
If the ffmpeg parameters are not present in the list of available function you can add it manually through the following function
**video.addCommand(command, argument)**
Example:
// In this example will be changed the output to avi format
video.addCommand('-f', 'avi');
## Save the file
After setting the desired parameters have to start the conversion process. To do this you must call the function 'save'. This method takes as input the final destination of the file and optionally a callback function. If the function callback is not specified it's possible use the promise object.
**video.save(destionationFileName, callback)**
Example:
try {
var process = new ffmpeg('/path/to/your_movie.avi');
process.then(function (video) {
video
.setVideoSize('640x?', true, true, '#fff')
.setAudioCodec('libfaac')
.setAudioChannels(2)
.save('/path/to/save/your_movie.avi', function (error, file) {
if (!error)
console.log('Video file: ' + file);
});
}, function (err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e.code);
console.log(e.msg);
}

1
node_modules/ffmpeg/index.js generated vendored Normal file
View File

@ -0,0 +1 @@
module.exports = require('./lib/ffmpeg');

8
node_modules/ffmpeg/lib/configs.js generated vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Basic configuration
*/
module.exports = function () {
this.encoding = 'utf8';
this.timeout = 0;
this.maxBuffer = 200 * 1024
}

35
node_modules/ffmpeg/lib/errors.js generated vendored Normal file
View File

@ -0,0 +1,35 @@
var util = require('util');
// Error list with code and message
var list = {
'empty_input_filepath' : { 'code' : 100, 'msg' : 'The input file path can not be empty' }
, 'input_filepath_must_be_string' : { 'code' : 101, 'msg' : 'The input file path must be a string' }
, 'invalid_option_name' : { 'code' : 102, 'msg' : 'The option "%s" is invalid. Check the list of available options' }
, 'fileinput_not_exist' : { 'code' : 103, 'msg' : 'The input file does not exist' }
, 'format_not_supported' : { 'code' : 104, 'msg' : 'The format "$s" is not supported by the version of ffmpeg' }
, 'audio_channel_is_invalid' : { 'code' : 105, 'msg' : 'The audio channel "$s" is not valid' }
, 'mkdir' : { 'code' : 106, 'msg' : 'Error occurred during creation folder: $s' }
, 'extract_frame_invalid_everyN_options' : { 'code' : 107, 'msg' : 'You can specify only one option between everyNFrames and everyNSeconds' }
, 'invalid_watermark' : { 'code' : 108, 'msg' : 'The watermark "%s" does not exists' }
, 'invalid_watermark_position' : { 'code' : 109, 'msg' : 'Invalid watermark position "%s"' }
, 'size_format' : { 'code' : 110, 'msg' : 'The format "%s" not supported by the function "setSize"' }
, 'resolution_square_not_defined' : { 'code' : 111, 'msg' : 'The resolution for pixel aspect ratio is not defined' }
, 'command_already_exists' : { 'code' : 112, 'msg' : 'The command "%s" already exists' }
, 'codec_not_supported' : { 'code' : 113, 'msg' : 'The codec "$s" is not supported by the version of ffmpeg' }
}
/**
* Return the error by the codename
*/
var renderError = function (codeName) {
// Get the error object by the codename
var params = [list[codeName].msg];
// Get the possible arguments
if (arguments.length > 1)
params = params.concat(Array.prototype.slice.call(arguments, 1));
// Call the function for replace the letter '%s' with the found arguments
return { 'code' : list[codeName].code, 'msg' : util.format.apply(this, params) };
}
module.exports.list = list;
module.exports.renderError = renderError;

251
node_modules/ffmpeg/lib/ffmpeg.js generated vendored Normal file
View File

@ -0,0 +1,251 @@
var when = require('when')
, fs = require('fs');
var errors = require('./errors')
, utils = require('./utils')
, configs = require('./configs')
, video = require('./video');
var ffmpeg = function (/* inputFilepath, settings, callback */) {
/**
* Retrieve the list of the codec supported by the ffmpeg software
*/
var _ffmpegInfoConfiguration = function (settings) {
// New 'promise' instance
var deferred = when.defer();
// Instance the new arrays for the format
var format = { modules : new Array(), encode : new Array(), decode : new Array() };
// Make the call to retrieve information about the ffmpeg
utils.exec(['ffmpeg','-formats','2>&1'], settings, function (error, stdout, stderr) {
// Get the list of modules
var configuration = /configuration:(.*)/.exec(stdout);
// Check if exists the configuration
if (configuration) {
// Get the list of modules
var modules = configuration[1].match(/--enable-([a-zA-Z0-9\-]+)/g);
// Scan all modules
for (var indexModule in modules) {
// Add module to the list
format.modules.push(/--enable-([a-zA-Z0-9\-]+)/.exec(modules[indexModule])[1]);
}
}
// Get the codec list
var codecList = stdout.match(/ (DE|D|E) (.*) {1,} (.*)/g);
// Scan all codec
for (var i in codecList) {
// Get the match value
var match = / (DE|D|E) (.*) {1,} (.*)/.exec(codecList[i]);
// Check if match is valid
if (match) {
// Get the value from the match
var scope = match[1].replace(/\s/g,'')
, extension = match[2].replace(/\s/g,'');
// Check which scope is best suited
if (scope == 'D' || scope == 'DE')
format.decode.push(extension);
if (scope == 'E' || scope == 'DE')
format.encode.push(extension);
}
}
// Returns the list of supported formats
deferred.resolve(format);
});
// Return 'promise' instance
return deferred.promise;
}
/**
* Get the video info
*/
var _videoInfo = function (fileInput, settings) {
// New 'promise' instance
var deferred = when.defer();
// Make the call to retrieve information about the ffmpeg
utils.exec(['ffmpeg','-i',fileInput,'2>&1'], settings, function (error, stdout, stderr) {
// Perse output for retrieve the file info
var filename = /from \'(.*)\'/.exec(stdout) || []
, title = /(INAM|title)\s+:\s(.+)/.exec(stdout) || []
, artist = /artist\s+:\s(.+)/.exec(stdout) || []
, album = /album\s+:\s(.+)/.exec(stdout) || []
, track = /track\s+:\s(.+)/.exec(stdout) || []
, date = /date\s+:\s(.+)/.exec(stdout) || []
, is_synched = (/start: 0.000000/.exec(stdout) !== null)
, duration = /Duration: (([0-9]+):([0-9]{2}):([0-9]{2}).([0-9]+))/.exec(stdout) || []
, container = /Input #0, ([a-zA-Z0-9]+),/.exec(stdout) || []
, video_bitrate = /bitrate: ([0-9]+) kb\/s/.exec(stdout) || []
, video_stream = /Stream #([0-9\.]+)([a-z0-9\(\)\[\]]*)[:] Video/.exec(stdout) || []
, video_codec = /Video: ([\w]+)/.exec(stdout) || []
, resolution = /(([0-9]{2,5})x([0-9]{2,5}))/.exec(stdout) || []
, pixel = /[SP]AR ([0-9\:]+)/.exec(stdout) || []
, aspect = /DAR ([0-9\:]+)/.exec(stdout) || []
, fps = /([0-9\.]+) (fps|tb\(r\))/.exec(stdout) || []
, audio_stream = /Stream #([0-9\.]+)([a-z0-9\(\)\[\]]*)[:] Audio/.exec(stdout) || []
, audio_codec = /Audio: ([\w]+)/.exec(stdout) || []
, sample_rate = /([0-9]+) Hz/i.exec(stdout) || []
, channels = /Audio:.* (stereo|mono)/.exec(stdout) || []
, audio_bitrate = /Audio:.* ([0-9]+) kb\/s/.exec(stdout) || []
, rotate = /rotate[\s]+:[\s]([\d]{2,3})/.exec(stdout) || [];
// Build return object
var ret = {
filename : filename[1] || ''
, title : title[2] || ''
, artist : artist[1] || ''
, album : album[1] || ''
, track : track[1] || ''
, date : date[1] || ''
, synched : is_synched
, duration : {
raw : duration[1] || ''
, seconds : duration[1] ? utils.durationToSeconds(duration[1]) : 0
}
, video : {
container : container[1] || ''
, bitrate : (video_bitrate.length > 1) ? parseInt(video_bitrate[1], 10) : 0
, stream : video_stream.length > 1 ? parseFloat(video_stream[1]) : 0.0
, codec : video_codec[1] || ''
, resolution : {
w : resolution.length > 2 ? parseInt(resolution[2], 10) : 0
, h : resolution.length > 3 ? parseInt(resolution[3], 10) : 0
}
, resolutionSquare : {}
, aspect : {}
, rotate : rotate.length > 1 ? parseInt(rotate[1], 10) : 0
, fps : fps.length > 1 ? parseFloat(fps[1]) : 0.0
}
, audio : {
codec : audio_codec[1] || ''
, bitrate : audio_bitrate[1] || ''
, sample_rate : sample_rate.length > 1 ? parseInt(sample_rate[1], 10) : 0
, stream : audio_stream.length > 1 ? parseFloat(audio_stream[1]) : 0.0
, channels : {
raw : channels[1] || ''
, value : (channels.length > 0) ? ({ stereo : 2, mono : 1 }[channels[1]] || 0) : ''
}
}
};
// Check if exist aspect ratio
if (aspect.length > 0) {
var aspectValue = aspect[1].split(":");
ret.video.aspect.x = parseInt(aspectValue[0], 10);
ret.video.aspect.y = parseInt(aspectValue[1], 10);
ret.video.aspect.string = aspect[1];
ret.video.aspect.value = parseFloat((ret.video.aspect.x / ret.video.aspect.y));
} else {
// If exists horizontal resolution then calculate aspect ratio
if(ret.video.resolution.w > 0) {
var gcdValue = utils.gcd(ret.video.resolution.w, ret.video.resolution.h);
// Calculate aspect ratio
ret.video.aspect.x = ret.video.resolution.w / gcdValue;
ret.video.aspect.y = ret.video.resolution.h / gcdValue;
ret.video.aspect.string = ret.video.aspect.x + ':' + ret.video.aspect.y;
ret.video.aspect.value = parseFloat((ret.video.aspect.x / ret.video.aspect.y));
}
}
// Save pixel ratio for output size calculation
if (pixel.length > 0) {
ret.video.pixelString = pixel[1];
var pixelValue = pixel[1].split(":");
ret.video.pixel = parseFloat((parseInt(pixelValue[0], 10) / parseInt(pixelValue[1], 10)));
} else {
if (ret.video.resolution.w !== 0) {
ret.video.pixelString = '1:1';
ret.video.pixel = 1;
} else {
ret.video.pixelString = '';
ret.video.pixel = 0.0;
}
}
// Correct video.resolution when pixel aspectratio is not 1
if (ret.video.pixel !== 1 || ret.video.pixel !== 0) {
if( ret.video.pixel > 1 ) {
ret.video.resolutionSquare.w = parseInt(ret.video.resolution.w * ret.video.pixel, 10);
ret.video.resolutionSquare.h = ret.video.resolution.h;
} else {
ret.video.resolutionSquare.w = ret.video.resolution.w;
ret.video.resolutionSquare.h = parseInt(ret.video.resolution.h / ret.video.pixel, 10);
}
}
// Returns the list of supported formats
deferred.resolve(ret);
});
// Return 'promise' instance
return deferred.promise;
}
/**
* Get the info about ffmpeg's codec and about file
*/
var _getInformation = function (fileInput, settings) {
var deferreds = [];
// Add promise
deferreds.push(_ffmpegInfoConfiguration(settings));
deferreds.push(_videoInfo(fileInput, settings));
// Return defer
return when.all(deferreds);
}
var __constructor = function (args) {
// Check if exist at least one option
if (args.length == 0 || args[0] == undefined)
throw errors.renderError('empty_input_filepath');
// Check if first argument is a string
if (typeof args[0] != 'string')
throw errors.renderError('input_filepath_must_be_string');
// Get the input filepath
var inputFilepath = args[0];
// Check if file exist
if (!fs.existsSync(inputFilepath))
throw errors.renderError('fileinput_not_exist');
// New instance of the base configuration
var settings = new configs();
// Callback to call
var callback = null;
// Scan all arguments
for (var i = 1; i < args.length; i++) {
// Check the type of variable
switch (typeof args[i]) {
case 'object' :
utils.mergeObject(settings, args[i]);
break;
case 'function' :
callback = args[i];
break;
}
}
// Building the value for return value. Check if the callback is not a function. In this case will created a new instance of the deferred class
var deferred = typeof callback != 'function' ? when.defer() : { promise : null };
when(_getInformation(inputFilepath, settings), function (data) {
// Check if the callback is a function
if (typeof callback == 'function') {
// Call the callback function e return the new instance of 'video' class
callback(null, new video(inputFilepath, settings, data[0], data[1]));
} else {
// Positive response
deferred.resolve(new video(inputFilepath, settings, data[0], data[1]));
}
}, function (error) {
// Check if the callback is a function
if (typeof callback == 'function') {
// Call the callback function e return the error found
callback(error, null);
} else {
// Negative response
deferred.reject(error);
}
});
// Return a possible promise instance
return deferred.promise;
}
return __constructor.call(this, arguments);
};
module.exports = ffmpeg;

43
node_modules/ffmpeg/lib/presets.js generated vendored Normal file
View File

@ -0,0 +1,43 @@
module.exports.size = {
'SQCIF' : '128x96'
, 'QCIF' : '176x144'
, 'CIF' : '352x288'
, '4CIF' : '704x576'
, 'QQVGA' : '160x120'
, 'QVGA' : '320x240'
, 'VGA' : '640x480'
, 'SVGA' : '800x600'
, 'XGA' : '1024x768'
, 'UXGA' : '1600x1200'
, 'QXGA' : '2048x1536'
, 'SXGA' : '1280x1024'
, 'QSXGA' : '2560x2048'
, 'HSXGA' : '5120x4096'
, 'WVGA' : '852x480'
, 'WXGA' : '1366x768'
, 'WSXGA' : '1600x1024'
, 'WUXGA' : '1920x1200'
, 'WOXGA' : '2560x1600'
, 'WQSXGA' : '3200x2048'
, 'WQUXGA' : '3840x2400'
, 'WHSXGA' : '6400x4096'
, 'WHUXGA' : '7680x4800'
, 'CGA' : '320x200'
, 'EGA' : '640x350'
, 'HD480' : '852x480'
, 'HD720' : '1280x720'
, 'HD1080' : '1920x1080'
}
module.exports.ratio = {
'4:3' : 1.33
, '3:2' : 1.5
, '14:9' : 1.56
, '16:9' : 1.78
, '21:9' : 2.33
}
module.exports.audio_channel = {
'mono' : 1
, 'stereo' : 2
}

132
node_modules/ffmpeg/lib/utils.js generated vendored Normal file
View File

@ -0,0 +1,132 @@
var exec = require('child_process').exec
, fs = require('fs')
, path = require('path');
var errors = require('./errors');
/**
* Exec the list of commands and call the callback function at the end of the process
*/
module.exports.exec = function (commands, settings, callback) {
// Create final command line
var finalCommand = commands.join(" ");
// Create the timeoutId for stop the timeout at the end the process
var timeoutID = null;
// Exec the command
var process = exec(finalCommand, settings, function (error, stdout, stderr) {
// Clear timeout if 'timeoutID' are setted
if (timeoutID !== null) clearTimeout(timeoutID);
// Call the callback function
callback(error, stdout, stderr);
});
// Verify if the timeout are setting
if (settings.timeout > 0) {
// Set the timeout
timeoutID = setTimeout(function () {
process.kill();
}, 100);
}
}
/**
* Check if object is empty
*/
module.exports.isEmptyObj = function (obj) {
// Scan all properties
for(var prop in obj)
// Check if obj has a property
if(obj.hasOwnProperty(prop))
// The object is not empty
return false;
// The object is empty
return true;
}
/**
* Merge obj1 into obj
*/
module.exports.mergeObject = function (obj, obj1) {
// Check if there are options set
if (!module.exports.isEmptyObj(obj1)) {
// Scan all settings
for (var key in obj1) {
// Check if the option is valid
if (!obj.hasOwnProperty(key))
throw errors.renderError('invalid_option_name', key);
// Set new option value
obj[key] = obj1[key];
}
}
}
/**
* Calculate the duration in seconds from the string retrieved by the ffmpeg info
*/
module.exports.durationToSeconds = function(duration) {
var parts = duration.substr(0,8).split(':');
return parseInt(parts[0], 10) * 3600 + parseInt(parts[1], 10) * 60 + parseInt(parts[2], 10);
};
/**
* Calculate the greatest common divisor
*/
module.exports.gcd = function (a, b) {
if (b === 0) return a;
return module.exports.gcd(b, a % b);
}
/**
* Offers functionality similar to mkdir -p
*/
module.exports.mkdir = function (dirpath, mode, callback, position) {
// Split all directories
var parts = path.normalize(dirpath).split('/');
// If the first part is empty then remove this part
if (parts[0] == "")
parts = parts.slice(1);
// Set the initial configuration
mode = mode || 0777;
position = position || 0;
// Check se current position is greater than the list of folders
if (position > parts.length) {
// If isset the callback then it will be invoked
if (callback)
callback();
// Exit and return a positive value
return true;
}
// Build the directory path
var directory = (dirpath.charAt(0) == '/' ? '/' : '') + parts.slice(0, position + 1).join('/');
// Check if directory exists
if (fs.existsSync(directory)) {
module.exports.mkdir(dirpath, mode, callback, position + 1);
} else {
if (fs.mkdirSync(directory, mode)) {
// If isset the callback then it will be invoked
if (callback)
callback(errors.renderError('mkdir', directory));
// Send the new exception
throw errors.renderError('mkdir', directory);
} else {
module.exports.mkdir(dirpath, mode, callback, position + 1);
}
}
}
/**
* Check if a value is present inside an array
*/
module.exports.in_array = function (value, array) {
// Scan all element
for (var i in array)
// Check if value exists
if (array[i] == value)
// Return the position of value
return i;
// The value not exists
return false;
}

863
node_modules/ffmpeg/lib/video.js generated vendored Normal file
View File

@ -0,0 +1,863 @@
var fs = require('fs')
, path = require('path')
, when = require('when');
var errors = require('./errors')
, presets = require('./presets')
, utils = require('./utils');
module.exports = function (filePath, settings, infoConfiguration, infoFile) {
// Public info about file and ffmpeg configuration
this.file_path = filePath;
this.info_configuration = infoConfiguration;
this.metadata = infoFile;
// Commands for building the ffmpeg string conversion
var commands = new Array()
, inputs = new Array()
, filtersComlpex = new Array()
, output = null;
// List of options generated from setting functions
var options = new Object();
/*****************************************/
/* FUNCTION FOR FILL THE COMMANDS OBJECT */
/*****************************************/
/**
* Add a command to be bundled into the ffmpeg command call
*/
this.addCommand = function (command, argument) {
// Check if exists the current command
if (utils.in_array(command, commands) === false) {
// Add the new command
commands.push(command);
// Add the argument to new command
if (argument != undefined)
commands.push(argument);
} else
throw errors.renderError('command_already_exists', command);
}
/**
* Add an input stream
*/
this.addInput = function (argument) {
inputs.push(argument);
}
/**
* Add a filter complex
*/
this.addFilterComplex = function (argument) {
filtersComlpex.push(argument);
}
/**
* Set the output path
*/
var setOutput = function (path) {
output = path;
}
/*********************/
/* SETTING FUNCTIONS */
/*********************/
/**
* Disables audio encoding
*/
this.setDisableAudio = function () {
if (options.audio == undefined)
options.audio = new Object();
// Set the new option
options.audio.disabled = true;
return this;
}
/**
* Disables video encoding
*/
this.setDisableVideo = function () {
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.disabled = true;
return this;
}
/**
* Sets the new video format
*/
this.setVideoFormat = function (format) {
// Check if the format is supported by ffmpeg version
if (this.info_configuration.encode.indexOf(format) != -1) {
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.format = format;
return this;
} else
throw errors.renderError('format_not_supported', format);
}
/**
* Sets the new audio codec
*/
this.setVideoCodec = function (codec) {
// Check if the codec is supported by ffmpeg version
if (this.info_configuration.encode.indexOf(codec) != -1) {
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.codec = codec;
return this;
} else
throw errors.renderError('codec_not_supported', codec);
}
/**
* Sets the video bitrate
*/
this.setVideoBitRate = function (bitrate) {
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.bitrate = bitrate;
return this;
}
/**
* Sets the framerate of the video
*/
this.setVideoFrameRate = function (framerate) {
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.framerate = framerate;
return this;
}
/**
* Sets the start time
*/
this.setVideoStartTime = function (time) {
if (options.video == undefined)
options.video = new Object();
// Check if time is a string that contain: hours, minutes and seconds
if (isNaN(time) && /([0-9]+):([0-9]{2}):([0-9]{2})/.exec(time)) {
time = utils.durationToSeconds(time);
} else if (!isNaN(time) && parseInt(time) == time) {
time = parseInt(time, 10);
} else {
time = 0;
}
// Set the new option
options.video.startTime = time;
return this;
}
/**
* Sets the duration
*/
this.setVideoDuration = function (duration) {
if (options.video == undefined)
options.video = new Object();
// Check if duration is a string that contain: hours, minutes and seconds
if (isNaN(duration) && /([0-9]+):([0-9]{2}):([0-9]{2})/.exec(duration)) {
duration = utils.durationToSeconds(duration);
} else if (!isNaN(duration) && parseInt(duration) == duration) {
duration = parseInt(duration, 10);
} else {
duration = 0;
}
// Set the new option
options.video.duration = duration;
return this;
}
/**
* Sets the new aspetc ratio
*/
this.setVideoAspectRatio = function (aspect) {
// Check if aspect is a string
if (isNaN(aspect)) {
// Check if aspet is string xx:xx
if (/([0-9]+):([0-9]+)/.exec(aspect)) {
var check = /([0-9]+):([0-9]+)/.exec(aspect);
aspect = parseFloat((check[1] / check[2]));
} else {
aspect = this.metadata.video.aspect.value;
}
}
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.aspect = aspect;
return this;
}
/**
* Set the size of the video
*/
this.setVideoSize = function (size, keepPixelAspectRatio, keepAspectRatio, paddingColor) {
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.size = size;
options.video.keepPixelAspectRatio = keepPixelAspectRatio;
options.video.keepAspectRatio = keepAspectRatio;
options.video.paddingColor = paddingColor;
return this;
}
/**
* Sets the new audio codec
*/
this.setAudioCodec = function (codec) {
// Check if the codec is supported by ffmpeg version
if (this.info_configuration.encode.indexOf(codec) != -1) {
// Check if codec is equal 'MP3' and check if the version of ffmpeg support the libmp3lame function
if (codec == 'mp3' && this.info_configuration.modules.indexOf('libmp3lame') != -1)
codec = 'libmp3lame';
if (options.audio == undefined)
options.audio = new Object();
// Set the new option
options.audio.codec = codec;
return this;
} else
throw errors.renderError('codec_not_supported', codec);
}
/**
* Sets the audio sample frequency for audio outputs
*/
this.setAudioFrequency = function (frequency) {
if (options.audio == undefined)
options.audio = new Object();
// Set the new option
options.audio.frequency = frequency;
return this;
}
/**
* Sets the number of audio channels
*/
this.setAudioChannels = function (channel) {
// Check if the channel value is valid
if (presets.audio_channel.stereo == channel || presets.audio_channel.mono == channel) {
if (options.audio == undefined)
options.audio = new Object();
// Set the new option
options.audio.channel = channel;
return this;
} else
throw errors.renderError('audio_channel_is_invalid', channel);
}
/**
* Sets the audio bitrate
*/
this.setAudioBitRate = function (bitrate) {
if (options.audio == undefined)
options.audio = new Object();
// Set the new option
options.audio.bitrate = bitrate;
return this;
}
/**
* Sets the audio quality
*/
this.setAudioQuality = function (quality) {
if (options.audio == undefined)
options.audio = new Object();
// Set the new option
options.audio.quality = quality;
return this;
}
/**
* Sets the watermark
*/
this.setWatermark = function (watermarkPath, settings) {
// Base settings
var baseSettings = {
position : "SW" // Position: NE NC NW SE SC SW C CE CW
, margin_nord : null // Margin nord
, margin_sud : null // Margin sud
, margin_east : null // Margin east
, margin_west : null // Margin west
};
// Check if watermark exists
if (!fs.existsSync(watermarkPath))
throw errors.renderError('invalid_watermark', watermarkPath);
// Check if the settings are specified
if (settings != null)
utils.mergeObject(baseSettings, settings);
// Check if position is valid
if (baseSettings.position == null || utils.in_array(baseSettings.position, ['NE','NC','NW','SE','SC','SW','C','CE','CW']) === false)
throw errors.renderError('invalid_watermark_position', baseSettings.position);
// Check if margins are valid
if (baseSettings.margin_nord == null || isNaN(baseSettings.margin_nord))
baseSettings.margin_nord = 0;
if (baseSettings.margin_sud == null || isNaN(baseSettings.margin_sud))
baseSettings.margin_sud = 0;
if (baseSettings.margin_east == null || isNaN(baseSettings.margin_east))
baseSettings.margin_east = 0;
if (baseSettings.margin_west == null || isNaN(baseSettings.margin_west))
baseSettings.margin_west = 0;
var overlay = '';
var getSing = function (val, inverse) {
return (val > 0 ? (inverse ? '-' : '+') : (inverse ? '+' : '-')).toString() + Math.abs(val).toString();
}
var getHorizontalMargins = function (east, west) {
return getSing(east, false).toString() + getSing(west, true).toString();
}
var getVerticalMargins = function (nord, sud) {
return getSing(nord, false).toString() + getSing(sud, true).toString();
}
// Calculate formula
switch (baseSettings.position) {
case 'NE':
overlay = '0' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':0' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'NC':
overlay = 'main_w/2-overlay_w/2' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':0' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'NW':
overlay = 'main_w-overlay_w' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':0' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'SE':
overlay = '0' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':main_h-overlay_h' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'SC':
overlay = 'main_w/2-overlay_w/2' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':main_h-overlay_h' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'SW':
overlay = 'main_w-overlay_w' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':main_h-overlay_h' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'CE':
overlay = '0' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':main_h/2-overlay_h/2' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'C':
overlay = 'main_w/2-overlay_w/2' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':main_h/2-overlay_h/2' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
case 'CW':
overlay = 'main_w-overlay_w' + getHorizontalMargins(baseSettings.margin_east, baseSettings.margin_west) + ':main_h/2-overlay_h/2' + getVerticalMargins(baseSettings.margin_nord, baseSettings.margin_sud);
break;
}
// Check if the call comes from internal function
if (arguments[2] == undefined || arguments[2] == null) {
if (options.video == undefined)
options.video = new Object();
// Set the new option
options.video.watermark = { path : watermarkPath, overlay : overlay };
return this;
} else if (arguments[2] != undefined && arguments[2] === true) {
this.addInput(watermarkPath);
this.addFilterComplex('overlay=' + overlay);
}
}
/**
* Save all set commands
*/
this.save = function (destionationFileName, callback) {
// Check if the 'video' is present in the options
if (options.hasOwnProperty('video')) {
// Check if video is disabled
if (options.video.hasOwnProperty('disabled')) {
this.addCommand('-vn');
} else {
// Check all video property
if (options.video.hasOwnProperty('format'))
this.addCommand('-f', options.video.format);
if (options.video.hasOwnProperty('codec'))
this.addCommand('-vcodec', options.video.codec);
if (options.video.hasOwnProperty('bitrate'))
this.addCommand('-b', parseInt(options.video.bitrate, 10) + 'kb');
if (options.video.hasOwnProperty('framerate'))
this.addCommand('-r', parseInt(options.video.framerate, 10));
if (options.video.hasOwnProperty('startTime'))
this.addCommand('-ss', parseInt(options.video.startTime, 10));
if (options.video.hasOwnProperty('duration'))
this.addCommand('-t', parseInt(options.video.duration, 10));
if (options.video.hasOwnProperty('watermark')) {
this.addInput(options.video.watermark.path);
this.addFilterComplex('overlay=' + options.video.watermark.overlay);
}
// Check if the video should be scaled
if (options.video.hasOwnProperty('size')) {
var newDimension = _calculateNewDimension.call(this);
if (newDimension.aspect != null) {
this.addFilterComplex('scale=iw*sar:ih, pad=max(iw\\,ih*(' + newDimension.aspect.x + '/' + newDimension.aspect.y + ')):ow/(' + newDimension.aspect.x + '/' + newDimension.aspect.y + '):(ow-iw)/2:(oh-ih)/2' + (options.video.paddingColor != null ? ':' + options.video.paddingColor : ''));
this.addCommand('-aspect', newDimension.aspect.string);
}
this.addCommand('-s', newDimension.width + 'x' + newDimension.height);
}
}
}
// Check if the 'audio' is present in the options
if (options.hasOwnProperty('audio')) {
// Check if audio is disabled
if (options.audio.hasOwnProperty('disabled')) {
this.addCommand('-an');
} else {
// Check all audio property
if (options.audio.hasOwnProperty('codec'))
this.addCommand('-acodec', options.audio.codec);
if (options.audio.hasOwnProperty('frequency'))
this.addCommand('-ar', parseInt(options.audio.frequency));
if (options.audio.hasOwnProperty('channel'))
this.addCommand('-ac', options.audio.channel);
if (options.audio.hasOwnProperty('quality'))
this.addCommand('-aq', options.audio.quality);
if (options.audio.hasOwnProperty('bitrate'))
this.addCommand('-ab', parseInt(options.audio.bitrate, 10) + 'k');
}
}
setOutput(destionationFileName);
return execCommand.call(this, callback);
}
/*********************/
/* INTERNAL FUNCTION */
/*********************/
/**
* Reset the list of commands
*/
var resetCommands = function (self) {
commands = new Array()
inputs = [self.file_path];
filtersComlpex = new Array();
output = null;
options = new Object();
}
/**
* Calculate width, height and aspect ratio by the new dimension data
*/
var _calculateNewDimension = function () {
// Check if keepPixelAspectRatio is undefined
var keepPixelAspectRatio = typeof options.video.keepPixelAspectRatio != 'boolean' ? false : options.video.keepPixelAspectRatio;
// Check if keepAspectRatio is undefined
var keepAspectRatio = typeof options.video.keepAspectRatio != 'boolean' ? false : options.video.keepAspectRatio;
// Resolution to be taken as a reference
var referrerResolution = this.metadata.video.resolution;
// Check if is need keep pixel aspect ratio
if (keepPixelAspectRatio) {
// Check if exists resolution for pixel aspect ratio
if (utils.isEmptyObj(this.metadata.video.resolutionSquare))
throw errors.renderError('resolution_square_not_defined');
// Apply the resolutionSquare
referrerResolution = this.metadata.video.resolutionSquare;
}
// Final data
var width = null
, height = null
, aspect = null;
// Regex to check which type of dimension was specified
var fixedWidth = /([0-9]+)x\?/.exec(options.video.size)
, fixedHeight = /\?x([0-9]+)/.exec(options.video.size)
, percentage = /([0-9]{1,2})%/.exec(options.video.size)
, classicSize = /([0-9]+)x([0-9]+)/.exec(options.video.size);
if (fixedWidth) {
// Set the width dimension
width = parseInt(fixedWidth[1], 10);
// Check if the video has the aspect ratio setted
if (!utils.isEmptyObj(this.metadata.video.aspect)) {
height = Math.round((width / this.metadata.video.aspect.x) * this.metadata.video.aspect.y);
} else {
// Calculte the new height
height = Math.round(referrerResolution.h / (referrerResolution.w / parseInt(fixedWidth[1], 10)));
}
} else if (fixedHeight) {
// Set the width dimension
height = parseInt(fixedHeight[1], 10);
// Check if the video has the aspect ratio setted
if (!utils.isEmptyObj(this.metadata.video.aspect)) {
width = Math.round((height / this.metadata.video.aspect.y) * this.metadata.video.aspect.x);
} else {
// Calculte the new width
width = Math.round(referrerResolution.w / (referrerResolution.h / parseInt(fixedHeight[1], 10)));
}
} else if (percentage) {
// Calculte the ratio from percentage
var ratio = parseInt(percentage[1], 10) / 100;
// Calculate the new dimensions
width = Math.round(referrerResolution.w * ratio);
height = Math.round(referrerResolution.h * ratio);
} else if (classicSize) {
width = parseInt(classicSize[1], 10);
height = parseInt(classicSize[2], 10);
} else
throw errors.renderError('size_format', options.video.size);
// If the width or height are not multiples of 2 will be decremented by one unit
if (width % 2 != 0) width -= 1;
if (height % 2 != 0) height -= 1;
if (keepAspectRatio) {
// Calculate the new aspect ratio
var gcdValue = utils.gcd(width, height);
aspect = new Object();
aspect.x = width / gcdValue;
aspect.y = height / gcdValue;
aspect.string = aspect.x + ':' + aspect.y;
}
return { width : width, height : height, aspect : aspect };
}
/**
* Executing the commands list
*/
var execCommand = function (callback, folder) {
// Checking if folder is defined
var onlyDestinationFile = folder != undefined ? false : true;
// Building the value for return value. Check if the callback is not a function. In this case will created a new instance of the deferred class
var deferred = typeof callback != 'function' ? when.defer() : { promise : null };
// Create a copy of the commands list
var finalCommands = ['ffmpeg -i']
.concat(inputs.join(' -i '))
.concat(commands.join(' '))
.concat(filtersComlpex.length > 0 ? ['-filter_complex "'].concat(filtersComlpex.join(', ')).join('') + '"' : [])
.concat([output]);
// Reset commands
resetCommands(this);
// Execute the commands from the list
utils.exec(finalCommands, settings, function (error, stdout, stderr) {
// Building the result
var result = null;
if (!error) {
// Check if show only destination filename or the complete file list
if (onlyDestinationFile) {
result = finalCommands[finalCommands.length-1];
} else {
// Clean possible "/" at the end of the string
if (folder.charAt(folder.length-1) == "/")
folder = folder.substr(0, folder.length-1);
// Read file list inside the folder
result = fs.readdirSync(folder);
// Scan all file and prepend the folder path
for (var i in result)
result[i] = [folder, result[i]].join('/')
}
}
// Check if the callback is a function
if (typeof callback == 'function') {
// Call the callback to return the info
callback(error, result);
} else {
if (error) {
// Negative response
deferred.reject(error);
} else {
// Positive response
deferred.resolve(result);
}
}
});
// Return a possible promise instance
return deferred.promise;
}
/*******************/
/* PRESET FUNCTION */
/*******************/
/**
* Extracting sound from a video, and save it as Mp3
*/
this.fnExtractSoundToMP3 = function (destionationFileName, callback) {
// Check if file already exists. In this case will remove it
if (fs.existsSync(destionationFileName))
fs.unlinkSync(destionationFileName);
// Building the final path
var destinationDirName = path.dirname(destionationFileName)
, destinationFileNameWE = path.basename(destionationFileName, path.extname(destionationFileName)) + '.mp3'
, finalPath = path.join(destinationDirName, destinationFileNameWE);
resetCommands(this);
// Adding commands to the list
this.addCommand('-vn');
this.addCommand('-ar', 44100);
this.addCommand('-ac', 2);
this.addCommand('-ab', 192);
this.addCommand('-f', 'mp3');
// Add destination file path to the command list
setOutput(finalPath);
// Executing the commands list
return execCommand.call(this, callback);
}
/**
* Extract frame from video file
*/
this.fnExtractFrameToJPG = function (/* destinationFolder, settings, callback */) {
var destinationFolder = null
, newSettings = null
, callback = null;
var settings = {
start_time : null // Start time to recording
, duration_time : null // Duration of recording
, frame_rate : null // Number of the frames to capture in one second
, size : null // Dimension each frame
, number : null // Total frame to capture
, every_n_frames : null // Frame to capture every N frames
, every_n_seconds : null // Frame to capture every N seconds
, every_n_percentage : null // Frame to capture every N percentage range
, keep_pixel_aspect_ratio : true // Mantain the original pixel video aspect ratio
, keep_aspect_ratio : true // Mantain the original aspect ratio
, padding_color : 'black' // Padding color
, file_name : null // File name
};
// Scan all arguments
for (var i in arguments) {
// Check the type of the argument
switch (typeof arguments[i]) {
case 'string':
destinationFolder = arguments[i];
break;
case 'object':
newSettings = arguments[i];
break;
case 'function':
callback = arguments[i];
break;
}
}
// Check if the settings are specified
if (newSettings !== null)
utils.mergeObject(settings, newSettings);
// Check if 'start_time' is in the format hours:minutes:seconds
if (settings.start_time != null) {
if (/([0-9]+):([0-9]{2}):([0-9]{2})/.exec(settings.start_time))
settings.start_time = utils.durationToSeconds(settings.start_time);
else if (!isNaN(settings.start_time))
settings.start_time = parseInt(settings.start_time, 10);
else
settings.start_time = null;
}
// Check if 'duration_time' is in the format hours:minutes:seconds
if (settings.duration_time != null) {
if (/([0-9]+):([0-9]{2}):([0-9]{2})/.exec(settings.duration_time))
settings.duration_time = utils.durationToSeconds(settings.duration_time);
else if (!isNaN(settings.duration_time))
settings.duration_time = parseInt(settings.duration_time, 10);
else
settings.duration_time = null;
}
// Check if the value of the framerate is number type
if (settings.frame_rate != null && isNaN(settings.frame_rate))
settings.frame_rate = null;
// If the size is not settings then the size of the screenshots is equal to video size
if (settings.size == null)
settings.size = this.metadata.video.resolution.w + 'x' + this.metadata.video.resolution.h;
// Check if the value of the 'number frame to capture' is number type
if (settings.number != null && isNaN(settings.number))
settings.number = null;
var every_n_check = 0;
// Check if the value of the 'every_n_frames' is number type
if (settings.every_n_frames != null && isNaN(settings.every_n_frames)) {
settings.every_n_frames = null;
every_n_check++;
}
// Check if the value of the 'every_n_seconds' is number type
if (settings.every_n_seconds != null && isNaN(settings.every_n_seconds)) {
settings.every_n_seconds = null;
every_n_check++;
}
// Check if the value of the 'every_n_percentage' is number type
if (settings.every_n_percentage != null && (isNaN(settings.every_n_percentage) || settings.every_n_percentage > 100)) {
settings.every_n_percentage = null;
every_n_check++;
}
if (every_n_check >= 2) {
if (callback) {
callback(errors.renderError('extract_frame_invalid_everyN_options'));
} else {
throw errors.renderError('extract_frame_invalid_everyN_options');
}
}
// If filename is null then his value is equal to original filename
if (settings.file_name == null) {
settings.file_name = path.basename(this.file_path, path.extname(this.file_path));
} else {
// Retrieve all possible replacements
var replacements = settings.file_name.match(/(\%[a-zA-Z]{1})/g);
// Check if exists replacements. The scan all replacements and build the final filename
if (replacements) {
for (var i in replacements) {
switch (replacements[i]) {
case '%t':
settings.file_name = settings.file_name.replace('%t', new Date().getTime());
break;
case '%s':
settings.file_name = settings.file_name.replace('%s', settings.size);
break;
case '%x':
settings.file_name = settings.file_name.replace('%x', settings.size.split(':')[0]);
break;
case '%y':
settings.file_name = settings.file_name.replace('%y', settings.size.split(':')[1]);
break;
default:
settings.file_name = settings.file_name.replace(replacements[i], '');
break;
}
}
}
}
// At the filename will added the number of the frame
settings.file_name = path.basename(settings.file_name, path.extname(settings.file_name)) + '_%d.jpg';
// Create the directory to save the extracted frames
utils.mkdir(destinationFolder, 0777);
resetCommands(this);
// Adding commands to the list
if (settings.startTime)
this.addCommand('-ss', settings.startTime);
if (settings.duration_time)
this.addCommand('-t', settings.duration_time);
if (settings.frame_rate)
this.addCommand('-r', settings.frame_rate);
// Setting the size and padding settings
this.setVideoSize(settings.size, settings.keep_pixel_aspect_ratio, settings.keep_aspect_ratio, settings.padding_color);
// Get the dimensions
var newDimension = _calculateNewDimension.call(this);
// Apply the size and padding commands
this.addCommand('-s', newDimension.width + 'x' + newDimension.height);
// CHeck if isset aspect ratio options
if (newDimension.aspect != null) {
this.addFilterComplex('scale=iw*sar:ih, pad=max(iw\\,ih*(' + newDimension.aspect.x + '/' + newDimension.aspect.y + ')):ow/(' + newDimension.aspect.x + '/' + newDimension.aspect.y + '):(ow-iw)/2:(oh-ih)/2' + (settings.padding_color != null ? ':' + settings.padding_color : ''));
this.addCommand('-aspect', newDimension.aspect.string);
}
if (settings.number)
this.addCommand('-vframes', settings.number);
if (settings.every_n_frames) {
this.addCommand('-vsync', 0);
this.addFilterComplex('select=not(mod(n\\,' + settings.every_n_frames + '))');
}
if (settings.every_n_seconds) {
this.addCommand('-vsync', 0);
this.addFilterComplex('select=not(mod(t\\,' + settings.every_n_seconds + '))');
}
if (settings.every_n_percentage) {
this.addCommand('-vsync', 0);
this.addFilterComplex('select=not(mod(t\\,' + parseInt((this.metadata.duration.seconds / 100) * settings.every_n_percentage) + '))');
}
// Add destination file path to the command list
setOutput([destinationFolder,settings.file_name].join('/'));
// Executing the commands list
return execCommand.call(this, callback, destinationFolder);
}
/**
* Add a watermark to the video and save it
*/
this.fnAddWatermark = function (watermarkPath /* newFilepath , settings, callback */) {
var newFilepath = null
, newSettings = null
, callback = null;
// Scan all arguments
for (var i = 1; i < arguments.length; i++) {
// Check the type of the argument
switch (typeof arguments[i]) {
case 'string':
newFilepath = arguments[i];
break;
case 'object':
newSettings = arguments[i];
break;
case 'function':
callback = arguments[i];
break;
}
}
resetCommands(this);
// Call the function to add the watermark options
this.setWatermark(watermarkPath, newSettings, true);
if (newFilepath == null)
newFilepath = path.dirname(this.file_path) + '/' +
path.basename(this.file_path, path.extname(this.file_path)) + '_watermark_' +
path.basename(watermarkPath, path.extname(watermarkPath)) +
path.extname(this.file_path);
// Add destination file path to the command list
setOutput(newFilepath);
// Executing the commands list
return execCommand.call(this, callback);
}
/**
* Constructor
*/
var __constructor = function (self) {
resetCommands(self);
}(this);
}

47
node_modules/ffmpeg/package.json generated vendored Normal file
View File

@ -0,0 +1,47 @@
{
"_from": "ffmpeg",
"_id": "ffmpeg@0.0.4",
"_inBundle": false,
"_integrity": "sha1-HEYN+OfaUSf2LO70v6BsWciWMMs=",
"_location": "/ffmpeg",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "ffmpeg",
"name": "ffmpeg",
"escapedName": "ffmpeg",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/ffmpeg/-/ffmpeg-0.0.4.tgz",
"_shasum": "1c460df8e7da5127f62ceef4bfa06c59c89630cb",
"_spec": "ffmpeg",
"_where": "C:\\Users\\matia\\Documents\\GitHub\\Musix-V3",
"author": {
"name": "Damiano Ciarla",
"email": "damiano.ciarl@gmail.com"
},
"bugs": {
"url": "https://github.com/damianociarla/node-ffmpeg/issues"
},
"bundleDependencies": false,
"dependencies": {
"when": ">= 0.0.1"
},
"deprecated": false,
"description": "Utility for managing video streams using ffmpeg",
"homepage": "https://github.com/damianociarla/node-ffmpeg#readme",
"main": "./index.js",
"name": "ffmpeg",
"repository": {
"type": "git",
"url": "git+https://github.com/damianociarla/node-ffmpeg.git"
},
"version": "0.0.4"
}