(function declareConstants () {

	// initialization
	const navigator = { platform: 'windows' };
	const ffprobePath = (navigator.platform === 'MacIntel') ? '/Users/windz/bin/ffprobe' : 'C:\\myTools\\ffmpeg-20161101-60178e7-win64-static\\bin\\ffprobe.exe';
	if (fs.existsSync(ffprobePath)) {
		setFfprobePath(ffprobePath);
		canProbeVideo = true;
	}
	

	// CONSTANTS.DB
	const dataStoreConfig = {
		filename: __dirname + '/db/fileList.db',
		autoload: true
	};
	CONSTANTS.DB = new DataStore(dataStoreConfig);

	// CONSTANTS.IMAGE
	const IMAGE = CONSTANTS.IMAGE = "i";
	// CONSTANTS.IMAGE
	const VIDEO = CONSTANTS.VIDEO = "v";
	// CONSTANTS.EXT_DICT
	CONSTANTS.EXT_DICT = {
		"jpg": IMAGE,
		"jpeg": IMAGE,
		"png": IMAGE,
		"bmp": IMAGE,
		"avi": VIDEO,
		"mp4": VIDEO,
		"mkv": VIDEO,
		"wmv": VIDEO
	};

	// CONSTANTS.RESOLUTION_DICT
	CONSTANTS.RESOLUTION_DICT = {
		"HD": "HD",
		"SD": "SD",
		"GG": "GG"
	};
	// CONSTANTS.HD_VIDEO_HEIGHT
	CONSTANTS.HD_VIDEO_HEIGHT = 1000;

})();
Example #2
0
module.exports = (function () {
	//轉檔駐列
	var ffmpeg = require('fluent-ffmpeg'),
		app = this,
		fs = require('fs-extra'), 
		listCom = require('./listCom')(function  (_path,_next) {
			//var mp4Id = Date.now() + ( ( Math.random()*20000 ) >>1 ),
			var mp4Id = _path.split("/")[1].split(".")[0],
				wmimage = "logo.png",
				command = new ffmpeg(_path)
					//.inputFormat('avi')
					//.size('720x480').aspect('4:3').autopad(true)
					//.addOption('-vf', 'movie='+wmimage+ ' [watermark]; [in] [watermark] overlay=main_w-overlay_w-10:10 [out]') //浮水印
					.complexFilter([
							'scale=720:480[rescaled]',
							"movie="+wmimage+"[mm]",
							{
							    filter: 'overlay', options: { x: "main_w-overlay_w-10", y: 10 },
							    inputs: ['rescaled', 'mm'], outputs: 'redgreen'
							}
						],'redgreen')
					.on("start", function() {
						app.onStart( mp4Id );
						//console.log('An start: ' + _path);
					  })
					.on('error', function(err) {
						app.onError( mp4Id, err);
					    //console.log('An error occurred: ' + err.message);
					    _next();
					  })
					.on('progress', function(progress) {
					    //console.log('Processing a : ' + progress.percent + '% done');
					    app.onProgress( mp4Id, progress.percent );
					  })
					.on("end",function  () {
						fs.rename('upfile/' + mp4Id + '_.mp4', 'upfile/' + mp4Id + '.mp4', function(err) {
							if (err) throw err;
							//console.log("end! " + mp4Id);
							app.onEnd( mp4Id );
							_next();
						});
					})
					.save('upfile/' + mp4Id + '_.mp4');
		});
	ffmpeg.setFfmpegPath("D:/ffmpeg/bin/ffmpeg.exe");
	ffmpeg.setFfprobePath("D:/ffmpeg/bin/ffprobe.exe");
	this.push = function  (_path) {
		listCom.push(_path);
	}
	this.onProgress = function  ( _id, _progress ) {
		// body...
		console.log('Processing a : '+ _id + " " + _progress + '% done');
	}
	this.onEnd = function  (_id) {
		console.log("end! " + _id);
	}
	this.onError = function  (_id , err) {
		console.log("error! " + _id +" "+err.message);
	}
	this.onStart = function  (_id) {
		console.log("start! " + _id);
	}
	this.chkStep = listCom.chkStep;
	return this;
})();
Example #3
0
!function () {

	// if `nedb` run in render process, it will use browser's storage for the DB. Hence, nedb to declare in main process and use IPC to communicate
	// the path is useless, electron will save it in browser storage (filename = key to doc saving the whole DB)...

	// console.log('os:', os.platform());
	const dbDirPath = (os.platform() !== 'win32') ? '/Users/windz/Code/a-video-explorer/db' : `${__dirname}\\..\\db`;
	const dataStoreConfig = {
		filename: path.join(dbDirPath, 'fileList.db'),
		autoload: false
	};
	const DB = new DataStore(dataStoreConfig);
	DB.loadDatabase((err) => {
		if (err) console.error(err);
		else console.log('DB successfully loaded~');
	});

	// create index in DB (_id is automatically indexed)
	// DB.ensureIndex({ fieldName: '_id', unique: true, sparse: false }, function (err) {
	// 	if (err) console.error(err);
	// 	else console.log('DB index created');
	// });

	/*|================================================================|*/
	/*|                           IPC events                           |*/
	/*|================================================================|*/
	ipcMain.on('getAll', (event) => {
		DB.find({}, (err, docs) => {
			console.log(err, docs);
		});
	});
	ipcMain.on('presist', (event) => {
		DB.persistence.compactDatafile();
	});
	ipcMain.on('get', (event, id) => {
		DB.findOne({ _id: id }, (err, doc) => {
			event.returnValue = { err, doc };
		});
	});
	ipcMain.on('upsert', (event, doc) => {

		const query = { _id: doc._id };
		const options = { upsert: true };

		DB.update(query, doc, options, function (err, numAffected, affectedDocuments, upsertFlag) {
			// affectedDocuments is set, iff, upsertFlag = true or options.returnUpdatedDocs = true
			event.returnValue = { err };
		});
	});

	ipcMain.on('clearNonExist', (event) => {
		DB.find({}, (err, docs) => {
			console.log('--- clearNonExist() start ---');
			const paths = docs.map( d => d._id );
			paths.forEach((p) => {
				try {
					fs.accessSync(p);
				} catch (err) {
					console.log(`[path 404]\t ${p}`);
					DB.remove({ _id: p }, { multi: false }, function (err, numRemoved) {
						if (numRemoved !== 1) console.error(`[remove 500]\t ${p}`);
						else console.log(`[remove 200]\t ${p}`);
					});
				}
			});
		});
	});

	// ffprobe
	const ffprobePath = (os.platform() !== 'win32') ? '/Users/windz/bin/ffprobe' : 'C:\\myTools\\ffmpeg-20161101-60178e7-win64-static\\bin\\ffprobeeee.exe';
	const canProbeVideo = fs.existsSync(ffprobePath);
	if (canProbeVideo) setFfprobePath(ffprobePath);

	ipcMain.on('getResolution', (event, filePath) => {

		function gotError(err) {
			console.log('getResolution', err);
			event.returnValue = { err };
		}
		function gotMetadata(shouldSave, stat, metadata) {
			if (shouldSave) {
				const doc = {
					_id: filePath,
					stat,
					metadata
				};
				const query = { _id: filePath };
				const options = { upsert: true };
				DB.update(query, doc, options, function (err, numAffected, affectedDocuments, upsertFlag) {
					// affectedDocuments is set, iff, upsertFlag = true or options.returnUpdatedDocs = true
					if (err) return gotError(err);
					event.returnValue = { metadata };
				});
			} else event.returnValue = { metadata };
		}
		function readMeta(filePath, stat) {
			if (canProbeVideo) {
				ffprobe(filePath, function(err, metadata) {
					if (err) return gotError(err);

					gotMetadata(true, stat, metadata);
				});
			} else return gotError(new Error('ffprobe not found'));
		}

		// find in DB
		DB.findOne({ _id: filePath }, (err, doc) => {
			if (err) return gotError(err);

			const stat = fs.statSync(filePath);
			// not found, save and reply
			if (doc === null) {
				readMeta(filePath, stat);
			} else {
				if (stat.mtime.getTime() !== (new Date(doc.stat.mtime)).getTime()) {
					readMeta(filePath, stat);
				} else gotMetadata(false, stat, doc.metadata);
			}
		});
	});

}();
#!/usr/bin/env node

const config = require('./config')

const path = require('path')
const fse = require('fs-extra')
const program = require('commander')

const commands = require('./commands')

const ffmpeg = require('fluent-ffmpeg')

//paths to the ffmpeg binaries for fluent-ffmpeg
ffmpeg.setFfmpegPath(config.ffmpegPath)
ffmpeg.setFfprobePath(config.ffprobePath)


//set up the command line interface with the commander module
program
  .version(config.version)
  .usage('[options] <videofile ...>')
  .description('Combines each video files with a cooresponding audio files (which should be in the same folder and differ only in extension).')
  .option('--output-suffix [string]', 'Suffix for output filenames', '')
  .option('--output-folder [string]', 'Folder for output filenames [combine]', 'combine')
  .option('--output-extension [string]', 'Extension for output filenames [.mp4]', '.mp4')
  .option('--audio-extension [string]', 'Extension for audio files [.m4a]', '.m4a')
  .option('--audio-suffix [string]', 'Suffix for audio files')
  .option('--audio-folder [string]', 'Folder for audio files (default is same folder as video files)')

  .option('-v, --verbose', 'Logs information about execution')
  .parse(process.argv)
Example #5
0
	})
	.option('ffprobe-path', {
		describe: 'Location ffprobe executable to use'
	})
	.usage('Usage: $0 --in [originalfile] --out [convertedfile]')
	.demandOption(['in', 'out'])
	.argv;

var src = argv.in;

if (argv.ffmpegPath) {
	FFmpeg.setFfmpegPath(argv.ffmpegPath);
}

if (argv.ffprobePath) {
	FFmpeg.setFfprobePath(argv.ffprobePath);
}

new FFmpeg({ source: src }).ffprobe(function (err, metadata) {

	if (err) {
		throw err;
	} else if (!metadata) {
		console.error('Failed reading metadata from video');
		process.exit(1);
	}

	var fileExt = src.split('.')[src.split('.').length - 1];
	var fileFormats = metadata.format.format_name.split(',');
	var intermediateFormat = fileFormats.indexOf(fileExt) > -1 ? fileExt : fileFormats[0];
	var alpha = new FFmpeg({ source: src });
Example #6
0
exports.getAudioMetadata = function(filepath, callback){
    ffmpeg.setFfprobePath(config.FFPROBE_PATH[os.type()]);
    ffmpeg.ffprobe(filepath, function(err, metadata){
        return callback(err, metadata);
    });
}
Example #7
0
// 将文件夹下的视频文件每隔1s截图一次并保存
// 文件名如 "1-20160117.mkv"
// 截图文件夹为名为 "1"
// 截图文件名为 "1-" + 所在秒数 + ".png" 如 "1-3601.png"

var ffmpeg = require('fluent-ffmpeg');
var async = require('async');
var fs = require('fs');

ffmpeg.setFfmpegPath('ffmpeg-20160322-git-30d1213-win64-static/bin/ffmpeg.exe');
ffmpeg.setFfprobePath('ffmpeg-20160322-git-30d1213-win64-static/bin/ffprobe.exe');

var videoScreenshotPreSecond = function(fileName, videoFilePath, screenshotsDir, callback) {
  var screenshotCount = 0;
  var eachScreenshotCount = 100;

  var waterfallFuncArr = [];
  var getScreenshotCountFunc = function(cb)
  {
    ffmpeg(videoFilePath).ffprobe(0, function(err, data) {
      if(!!err) {
        cb(err, null)
      } else {
        screenshotCount = parseInt(data.format.duration);
        cb(null, {screenshotCount: screenshotCount})
      }
    });
  };

  waterfallFuncArr.push(getScreenshotCountFunc)
Example #8
0
    'port': 9000
  }
})

// If user requested help instructions
if (argv.h) {
  printUsage()
  process.exit(-1)
}
// Set temporary directory path
if (argv.t) require ('../lib/EngineManager').setTemporaryDirectory(argv.t)

// Set ffmpeg executables path
if (argv.f) {
  ffmpeg.setFfmpegPath(argv.f + '/ffmpeg')
  ffmpeg.setFfprobePath(argv.f + '/ffprobe')
}

routes.setHttpPort(argv.port)

/**
 * Start HTTP server
 */
const app = express()

app.use(morgan('combined'))
app.use(express.static('public'))
app.get('/version', routes.getVersion)
app.get('/info/:magnet', routes.torrentInfo)
app.get('/raw/:magnet/:ind', routes.rawFile)
app.get('/probe/:magnet/:ind', routes.probe)
Example #9
0
;( function ()
	{
		var FS = require( 'fs' )

		var OS = require( 'os' )

		var NUM_CPUS = OS.cpus().length

		var PATH = require( 'path' )

		var UTIL = require( 'util' )

		var EventEmitter = require( 'events' ).EventEmitter

		var EJS = require( 'ejs' )

		var CHOKIDAR = require( 'chokidar' )

		// use nbqueue to limit the number of async functions
		var Queue = require( 'nbqueue' )

		var QUEUE_SCAN = new Queue( NUM_CPUS )

		// resort to filename mime detection because node-webkit can't run mmmagic...
		var MIME = require( 'mime' )

		var FFMPEG = require( 'fluent-ffmpeg' )

		var ROOT_DIR = PATH.join( __dirname, '../', '../' )

		var VIEWS_DIR = PATH.join( ROOT_DIR, 'views' )

		var VIEWS = require( VIEWS_DIR )

		var WIN

		var AUDIO_REGEX = /^audio\/(?:(?!x\-mpegurl).*)$/

		var VIDEO_REGEX = /^video\//

		var SPAWN = require( 'child_process' ).spawn

		var MPLAYER_PATH

		var MPLAYER_PROCESS

		var MPLAYER_ANSWER_REGEX = /^ANS_([\w\d_-]+)=([\w\d _-]+)/

		// audio element
		var AUDIO

		// set ffmpeg/ffprobe path if windows,
		// since windows users will more than
		// likely not have this setup
		if ( process.platform === 'win32' )
		{
			MPLAYER_PATH = PATH.join( ROOT_DIR, 'include', 'mplayer', 'mplayer.exe' )

			FFMPEG.setFfmpegPath( PATH.join( ROOT_DIR, 'include', 'ffmpeg', 'bin', 'ffmpeg.exe' ) )

			FFMPEG.setFfprobePath( PATH.join( ROOT_DIR, 'include', 'ffmpeg', 'bin', 'ffprobe.exe' ) )
		}

		else
		{
			MPLAYER_PATH = 'mplayer'
		}

		process.on( 'uncaughtException', function ( e )
			{
				console.log( e )

				console.trace()

				//process.exit( 1 )
			}
		)

		process.on( 'exit', function ()
			{
				if ( MPLAYER_PROCESS )
				{
					MPLAYER_PROCESS.kill( 'SIGKILL' )
				}
			}
		)

		// clamp a number between min and max
		function _clamp( target, min, max )
		{
			return target > min ? target < max ? target : max : min
		}

		function doError( str )
		{
			Server_log.call( this, 'error', str )
		}

		function doWarning( str )
		{
			Server_log.call( this, 'warning', str )
		}

		function doMessage( str )
		{
			Server_log.call( this, 'message', str )
		}

		/** @constructor */
		function Server()
		{
			// initialize EventEmitter on this instance
			EventEmitter.call( this )

			var that = this

			this.nowPlaying = null

			// define read-only isPlaying property
			Object.defineProperty( this, 'isPlaying',
				{
					get: function ()
					{
						return !!MPLAYER_PROCESS
					}
				}
			)

			var myPaused = false

			Object.defineProperty( this, 'isPaused',
				{
					get: function ()
					{
						return myPaused
					},

					set: function ( newValue )
					{
						if ( newValue !== myPaused )
						{
							if ( myPaused = newValue )
							{
								that.emit( 'pause' )
							}

							else
							{
								that.emit( 'unpause' )
							}
						}
					}
				}
			)

			var myVolume = 80;

			// volume: 0-100 float
			// use get/set accessor so the new value is always clamped
			Object.defineProperty( this, 'volume',
				{
					get: function ()
					{
						return myVolume
					},

					set: function ( newValue )
					{
						// clamp to be safe
						myVolume = _clamp( parseFloat( newValue ), 0, 100 )
					}
				}
			)

			var mySeekPercent = 0;

			// seekPercent: 0-100 float
			// use get/set accessor so the new value is always clamped
			Object.defineProperty( this, 'seekPercent',
				{
					get: function ()
					{
						return mySeekPercent
					},

					set: function ( newValue )
					{
						// clamp to be safe
						mySeekPercent = _clamp( parseFloat( newValue ), 0, 100 )
					}
				}
			)

			this
				.on( 'newlibraryfolder', function ( data )
					{
						Server_watchFolder.call( that, data.path )

						Server_scanFolder.call( that, data.path )
					}
				)

				.on( 'listening', function ()
					{
						// console.log( 'listening' )
					}
				)

				.on( 'connected', function ()
					{
						Server_init.call( that )
					}
				)

				.on( 'stopped', function ()
					{
						that.isPaused = false
					}
				)

				.on( 'playing', function ()
					{
						that.isPaused = false
					}
				)
		}

		// inherit from EventEmitter constructor
		UTIL.inherits( Server, EventEmitter )

		Server.prototype.kill = function ()
		{
			process.exit( 1 )
		}

		// render ejs file
		Server.prototype.renderFile = function ( name, data )
		{
			if ( !VIEWS[ name ] )
			{
				doError( 'tried to render file \'' + name + '\'.ejs, which does not exist' )

				return
			}

			var finalData = {}

			for ( var key in data )
			{
				finalData[ key ] = data[ key ]
			}

			finalData.filename = PATH.join( VIEWS_DIR, name + '.ejs' )

			return EJS.render( VIEWS[ name ], finalData )
		}

		Server.prototype.playSong = function ( path )
		{
			var that = this

			// check for existing process
			if ( MPLAYER_PROCESS )
			{
				// kill it with SIGTERM signal
				MPLAYER_PROCESS.kill( 'SIGKILL' )
			}

			// create a new mplayer process
			MPLAYER_PROCESS = SPAWN( MPLAYER_PATH,
				[
					'-slave',

					'-quiet',

					'-input', 'nodefault-bindings',

					'-noconfig', 'all',

					path

					//PATH.relative( __dirname, path )
				],

				{
					detached: false,

					stdio: 'pipe'
				}
			)

			MPLAYER_PROCESS
				// listen for close event
				.on( 'close', function ( code, signal )
					{
						// if no signal sent, unset MPLAYER_PROCESS
						if ( !signal )
						{
							MPLAYER_PROCESS = undefined

							that.emit( 'songfinished' )
						}

						// clear timeout just in case
						clearTimeout( mplayerTimeout )

						
					}
				)

			this.emit( 'playing', path )

			//var myLength

			//var myPercent = 0

			MPLAYER_PROCESS.stdout
				.on( 'data', function ( chunk )
					{
						var str = chunk.toString()

						// parse title and stuff from str or pull from db?

						var matches = str.match( MPLAYER_ANSWER_REGEX )

						if ( matches )
						{
							var m1 = matches[ 1 ].toLowerCase()

							var m2 = matches[ 2 ]

							// process stuff before emitting event
							switch ( m1 )
							{
								case 'pause'
								:
									if ( !( that.isPaused = m2 === 'yes' ) )
									{
										initTimeout()
									}

									break

								case 'percent_position'
								:
									var f = parseFloat( m2 )

									// if value hasn't changed, return and don't emit event
									if ( Math.abs( f - that.seekPercent ) < 1 )
									//if ( f <= that.seekPercent )
									{
										return
									}

									that.seekPercent = f

									break
							}

							that.emit( 'mplayer',
								{
									key: m1,

									value: m2
								}
							)
						}
					}
				)

			MPLAYER_PROCESS.stdin.write( 'pausing_keep_force get_time_length\n' )

			var mplayerTimeout

			var initTimeout = function ()
			{
				mplayerTimeout = setTimeout( function ()
					{
						if ( !MPLAYER_PROCESS || that.isPaused )
						{
							return
						}

						MPLAYER_PROCESS.stdin.write( 'pausing_keep_force get_percent_pos\n' )

						initTimeout()
					},

					250
				)
			}

			initTimeout()
		}

		Server.prototype.seekToPercent = function ( percent )
		{
			// make sure process exists
			if ( !MPLAYER_PROCESS )
			{
				return
			}

			// defaults to 0
			percent = parseFloat( typeof percent !== 'undefined' ? percent : 0 )

			// clamps to 0-100
			this.seekPercent = percent

			// seek by percent
			MPLAYER_PROCESS.stdin.write( 'pausing_keep_force seek ' + this.seekPercent + ' 1' )
		}

		// toggles pause on the currently playing song
		Server.prototype.pauseSong = function ()
		{
			// return if there is no mplayer process
			if ( !MPLAYER_PROCESS )
			{
				return
			}

			// pause the currently playing song
			MPLAYER_PROCESS.stdin.write( 'pause\n' )

			MPLAYER_PROCESS.stdin.write( 'pausing_keep_force get_property pause\n' )

			this.emit( 'paused' )
		}

		Server.prototype.scanLibrary = function ( folders )
		{
			if ( !folders || !Array.isArray( folders ) )
			{
				return // folders must be an array
			}

			var that = this

			folders.forEach( function ( obj )
				{
					// obj = { path: full path to directory, mtime: last modified time }

					FS.stat( obj.path, function ( err, stats )
						{
							if ( err )
							{
								return console.log( err )
							}

							if ( !stats.isDirectory() )
							{
								return doWarning.call( that, 'could not scan \'' + obj.path + '\' because it is not a directory' )
							}

							Server_watchFolder.call( that, obj.path )

							Server_scanFolder.call( that, obj.path )
						}
					)
				}
			)
		}

		function Server_watchFolder( pathToFolder )
		{
			var that = this

			// watch with chokidar - uses a lot of memory, might want to experiment with other methods
			var watcher = CHOKIDAR.watch( pathToFolder,
				{
					ignored: /[\/\\]\./,

					persistent: true,

					// not sure if this should be set to false or not
					usePolling: false
				}
			)

			watcher
				.on( 'error', function ( err )
					{
						console.log( err )
					}
				)

				.on( 'add', function ( path )
					{
						// stats from chokidar were not set on change, so call stat here
						FS.stat( path, function ( err, stats )
							{
								if ( err )
								{
									return console.log( err )
								}

								Server_scanFile.call( that, PATH.basename( path ), path, stats )
							}
						)
					}
				)

				.on( 'change', function ( path )
					{
						// stats from chokidar were not set on change, so call stat here
						FS.stat( path, function ( err, stats )
							{
								if ( err )
								{
									return console.log( err )
								}

								if ( stats.isDirectory() )
								{
									Server_scanFolder.call( that, path )

									return // directory
								}

								else
								{
									// assume file
									Server_scanFile.call( that, PATH.basename( path ), path, stats )
								}
							}
						)
					}
				)

				.on( 'addDir', function ( path )
					{
						Server_scanFolder.call( that, path )

						// watch folder?
					}
				)

				.on( 'unlink', function ( path )
					{
						// remove file
					}
				)

				.on( 'unlinkDir', function ( path )
					{
						// remove folder
					}
				)
		}

		function Server_scanFolder( path )
		{
			// make sure path exists
			if ( !path )
			{
				return
			}

			// reference this to use later
			var that = this

			FS.readdir( path, function ( err, files )
				{
					if ( err )
					{
						return console.log( err )
					}

					if ( !files )
					{
						return
					}

					//
					// WATCH THIS DIRECTORY HERE?
					//

					files.forEach( function ( file )
						{
							var filePath = PATH.join( path, file )

							FS.stat( filePath, function ( err, stats )
								{
									if ( err )
									{
										return // console.log( err )
									}

									// recursive scanning -
									// run this method on the file if it's a directory
									if ( stats.isDirectory() )
									{
										return Server_scanFolder.call( that, filePath )
									}

									Server_scanFile.call( that, file, filePath, stats )
								}
							)
						}
					)
				}
			)
		}

		// not really needed in mpserver anymore
		// converts seconds to formatted time - h:mm:ss
		/* function convertTime( seconds )
		{
			seconds = parseInt( seconds )

			var hours = Math.floor( seconds / ( 60 * 60 ) )

			var minutes = Math.floor( seconds / 60 ) - ( hours * ( 60 * 60 ) )

			seconds = seconds - ( minutes * 60 )

			var ret = ''

			if ( hours !== 0 )
			{
				ret += hours.toString() + ':'

				if ( minutes.toString().length === 1 )
				{
					minutes = '0' + minutes.toString()
				}
			}

			ret += minutes.toString() + ':'

			if ( seconds.toString().length === 1 )
			{
				seconds = '0' + seconds.toString()
			}

			ret += seconds.toString()

			return ret
		} */

		function Server_scanFile( fileName, filePath, stats )
		{
			if ( !filePath )
			{
				return
			}

			// return if hidden file
			if ( fileName.charAt( 0 ) === '.' )
			{
				return
			}

			var that = this

			var mime = MIME.lookup( filePath )

			if ( AUDIO_REGEX.test( mime ) )
			{
				// check indexeddb for existing file before scanning

				var transaction = WIN.mpdb.transaction( [ 'mpsongs' ], 'readonly' )

				var objectStore = transaction.objectStore( 'mpsongs' )

				var req = objectStore.get( filePath )

				req.onerror = function ( evt )
				{
					console.log( 'error' )

					console.log( evt )
				}

				req.onsuccess = function ( evt )
				{
					if ( evt.target.result && typeof evt.target.result.mtime !== 'undefined' && stats.mtime <= evt.target.result.mtime )
					{
						return
					}

					QUEUE_SCAN.add( function ( done )
						{
							//console.log( filePath )

							FFMPEG.ffprobe( filePath, function ( err, data )
								{
									if ( err )
									{
										//console.log( mime )

										//doError.call( that, err.message )

										return done()
									}

									var tags = data.format.tags || {}

									var track = ( tags.track || tags.TRACK || '' ).toString().split( '/' )[ 0 ].trim()

									if ( track !== '' )
									{
										track = parseInt( track )
									}

									that.emit( 'scannedsong',
										{
											track: track,

											title: ( tags.title || tags.TITLE || fileName ).toString().trim(),

											artist: ( tags.artist || tags.ARTIST || 'unknown artist' ).toString().trim(),

											album: ( tags.album || tags.ALBUM || 'unknown album' ).toString().trim(),

											duration: parseFloat( data.format.duration || 0 ),

											path: filePath,

											mtime: stats.mtime
										}
									)

									done()
								}
							)
						}
					)
				}
			}

			/* else

			if ( VIDEO_REGEX.test( mime ) )
			{

			} */

			// attempt to handle octet stream, maybe?
		}

		// fires when the server is connected to indexedDB
		function Server_init()
		{
			doMessage.call( this, 'mpserver running' )

			//this.scanLibrary()
		}

		function Server_log( type, str )
		{
			this.emit( 'log', { type: type, message: str } )
		}

		var server = new Server()

		module.exports = function ( win )
		{
			WIN = win || {}

			WIN.mpserver = server

			AUDIO = WIN.document.getElementById( 'mp-audio' )

			return WIN.mpserver
		}
	}
const path = require('path');
const ffmpeg = require('fluent-ffmpeg');
const command = ffmpeg();

ffmpeg.setFfmpegPath('./ffmpeg/ffmpeg.exe');
ffmpeg.setFfprobePath('./ffmpeg/ffprobe.exe');

ffmpeg.ffprobe('./file.flac', function(err, res) {
  console.log(JSON.stringify(res, null, '  '));
});

ffmpeg.ffprobe('./no-info.flac', function(err, res) {
  console.log(JSON.stringify(res, null, '  '));
});
Example #11
0
'use strict';

var _      = require('lodash');
var Video  = require('./video.model');
var fs     = require('fs');
var path   = require('path');
var crypto = require('crypto');
var config = require('../../config/environment');
var ffmpeg = require('fluent-ffmpeg');

// Set FFMPEG path
ffmpeg.setFfmpegPath('/home/gmonne/bin/ffmpeg');
ffmpeg.setFfprobePath('/home/gmonne/bin/ffprobe');

// Get list of videos
exports.index = function(req, res) {
  var query, params = {};
  if (req.query._category){ params._category = req.query._category; }
  if (req.query.enabled)  { params.enabled   = req.query.enabled; } 
  query = Video
    .find(params)
    .populate('_category', 'name')
    .populate('createdBy', 'name')
    .populate('updatedBy', 'name');
  if (req.query.limitTo){
    query = query.limit(parseInt(req.query.limitTo));
  }
  query.exec(function (err, videos) {
      if(err) { return handleError(res, err); }
      return res.json(200, videos);
    });