diff --git a/main/ipc.js b/main/ipc.js index 0d9c95fb..4bb55627 100644 --- a/main/ipc.js +++ b/main/ipc.js @@ -2,7 +2,6 @@ module.exports = { init } -var cp = require('child_process') var electron = require('electron') var app = electron.app @@ -13,6 +12,7 @@ var log = require('./log') var menu = require('./menu') var windows = require('./windows') var shortcuts = require('./shortcuts') +var vlc = require('./vlc') // has to be a number, not a boolean, and undefined throws an error var powerSaveBlockID = 0 @@ -93,44 +93,38 @@ function init () { }) ipcMain.on('vlcVersion', function (e) { - cp.exec('vlc --version', function (e, stdout, stderr) { - var version - if (e) { - version = null - } else { - // Prints several lines, starting with eg: VLC media player 2.7.0 - if (!stdout.startsWith('VLC media player')) version = 'unknown' - else version = stdout.split(' ')[3] - } + vlc.getInstalledVersion(function (version) { windows.main.send('vlcVersion', version) }) }) ipcMain.on('vlcPlay', function (e, url) { - // TODO: cross-platform VLC detection - var command = 'vlc' var args = ['--play-and-exit', '--quiet', url] - console.log('Running ' + command + ' ' + args.join(' ')) + console.log('Running vlc ' + args.join(' ')) - vlcProcess = cp.spawn(command, args) + vlc.spawn(args, function (err, proc) { + if (err) windows.main.send('dispatch', 'vlcNotFound') + vlcProcess = proc - // If it works, close the modal after a second - var closeModalTimeout = setTimeout(() => windows.main.send('dispatch', 'exitModal'), 1000) + // If it works, close the modal after a second + var closeModalTimeout = setTimeout(() => + windows.main.send('dispatch', 'exitModal'), 1000) - vlcProcess.on('close', function (code) { - clearTimeout(closeModalTimeout) - if (!vlcProcess) return // Killed - console.log('VLC exited with code ', code) - if (code === 0) { - windows.main.send('dispatch', 'backToList') - } else { - windows.main.send('dispatch', 'vlcNotFound') - } - vlcProcess = null - }) + vlcProcess.on('close', function (code) { + clearTimeout(closeModalTimeout) + if (!vlcProcess) return // Killed + console.log('VLC exited with code ', code) + if (code === 0) { + windows.main.send('dispatch', 'backToList') + } else { + windows.main.send('dispatch', 'vlcNotFound') + } + vlcProcess = null + }) - vlcProcess.on('error', function (e) { - console.log('VLC error', e) + vlcProcess.on('error', function (e) { + console.log('VLC error', e) + }) }) }) diff --git a/main/vlc.js b/main/vlc.js new file mode 100644 index 00000000..125e0b03 --- /dev/null +++ b/main/vlc.js @@ -0,0 +1,82 @@ +module.exports = { + getInstalledVersion, + spawn +} + +var cp = require('child_process') +var fs = require('fs') +var path = require('path') + +// Runs vlc --version. Calls back with the currently installed version of VLC +// or null if VLC is not installed. (Or 'unknown' if VLC runs and produces bad +// output, but that should never happen.) +function getInstalledVersion (cb) { + exec(['--version'], function (e, stdout, stderr) { + var version + if (e) { + version = null + } else { + // Prints several lines, starting with eg: VLC media player 2.7.0 + if (!stdout.startsWith('VLC media player')) version = 'unknown' + else version = stdout.split(' ')[3] + } + cb(version) + }) +} + +// TODO: make this its own module, to avoid duplicating code with webtorrent-cli +// Finds if VLC is installed on Mac, Windows, or Linux and runs it +function exec (args, cb) { + execOrSpawn(args, true, cb) +} + +// Finds if VLC is installed on Mac, Windows, or Linux. +// Uses child_process.spawn() to return a ChildProcess object +// Calls back with (err, childProcess) +function spawn (args, cb) { + execOrSpawn(args, false, cb) +} + +function execOrSpawn (args, isExec, cb) { + if (process.platform === 'win32') { + var Registry = require('winreg') + + var key + if (process.arch === 'x64') { + key = new Registry({ + hive: Registry.HKLM, + key: '\\Software\\Wow6432Node\\VideoLAN\\VLC' + }) + } else { + key = new Registry({ + hive: Registry.HKLM, + key: '\\Software\\VideoLAN\\VLC' + }) + } + + key.get('InstallDir', function (err, item) { + if (err) return cb(err) + var vlcPath = item.value + path.sep + 'vlc' + if (isExec) cp.execFile(vlcPath, args, cb) + else cb(null, cp.spawn(vlcPath, args)) + }) + } else { + var macRoot = '/Applications/VLC.app/Contents/MacOS/VLC' + var macHome = (process.env.HOME || '') + root + var locations = [macRoot, macHome, '/usr/bin/vlc'] + var found = false + var failed = 0 + locations.forEach(function (loc) { + fs.stat(loc, function (err) { + if (err) { + if (++failed === locations.length) cb(new Error('Can\'t find VLC')) + return + } + if (found) return + found = true + if (isExec) cp.execFile(loc, args, cb) + else cb(null, cp.spawn(loc, args)) + }) + }) + } +} diff --git a/package.json b/package.json index 19350a77..8b9c1ec6 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "srt-to-vtt": "^1.1.1", "virtual-dom": "^2.1.1", "webtorrent": "0.x", - "winreg": "^1.1.1" + "winreg": "^1.2.0" }, "devDependencies": { "cross-zip": "^2.0.1",