mirror of
				https://github.com/musix-org/musix-oss
				synced 2025-11-04 12:59:31 +00:00 
			
		
		
		
	fix
This commit is contained in:
		
							
								
								
									
										8
									
								
								node_modules/ffmpeg/lib/configs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								node_modules/ffmpeg/lib/configs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										35
									
								
								node_modules/ffmpeg/lib/errors.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										251
									
								
								node_modules/ffmpeg/lib/ffmpeg.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										43
									
								
								node_modules/ffmpeg/lib/presets.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										132
									
								
								node_modules/ffmpeg/lib/utils.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										863
									
								
								node_modules/ffmpeg/lib/video.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user