// instrument by jscoverage, do not modifly this file
(function () {
  var BASE;
  if (typeof global === 'object') {
    BASE = global;
  } else if (typeof window === 'object') {
    BASE = window;
  } else {
    throw new Error('[jscoverage] unknow ENV!');
  }
  if (!BASE._$jscoverage) {
    BASE._$jscoverage = {};
    BASE._$jscoverage_cond = {};
    BASE._$jscoverage_done = function (file, line, express) {
      if (arguments.length === 2) {
        BASE._$jscoverage[file][line] ++;
      } else {
        BASE._$jscoverage_cond[file][line] ++;
        return express;
      }
    };
    BASE._$jscoverage_init = function (base, file, lines) {
      var tmp = [];
      for (var i = 0; i < lines.length; i ++) {
        tmp[lines[i]] = 0;
      }
      base[file] = tmp;
    };
  }
})();
_$jscoverage_init(_$jscoverage, "lib/capabilities.js",[4,5,6,7,13,14,15,16,17,18,19,21,23,32,33,34,35,49,50,51,54,57,58,59,60,62,66,72,73,76,77,81,82,84,101,102,103,106,107,110,111,112,115,121,122,125,126,132,133,136,137,138,139,140,141,142,143,146,151,152,154,170,171,172,175,178,179,180,183,189,190,193,194,195,198,204,205,208,209,215,216,219,220,224,225,227,256,258,259,262,263,264,267,268,269,271,272,273,274,284,311,313,314,317,318,319,322,323,325,326,327,328,339,340,341,351,352,354,355,357,358,359,360,361,363,364,365,366,369,370,371,373,374,375,382,408,410,411,415,416,417,421,422,424,425,426,427,435,449,450,451,454,459,462,464,465,466,467,471,474,475,476,477,481,483,484,485,486,490,493,494,495,496,499,504,509,512,513,514,515,516,520,523,524,525,526,530,531,532,533,534,538,541,542,543,544,547]);
_$jscoverage_init(_$jscoverage_cond, "lib/capabilities.js",[50,57,59,72,81,102,110,121,132,137,139,151,171,178,189,193,204,215,224,258,263,273,313,318,327,327,340,340,357,357,370,410,416,426,465,466,466,474,476,484,485,485,493,495,514,514,515,515,515,523,525,532,532,533,533,533,541,543]);
_$jscoverage["lib/capabilities.js"].source = ["/*jshint node:true*/","'use strict';","","var fs = require('fs');","var path = require('path');","var async = require('async');","var utils = require('./utils');","","/*"," *! Capability helpers"," */","","var avCodecRegexp = /^\\s*([D ])([E ])([VAS])([S ])([D ])([T ]) ([^ ]+) +(.*)$/;","var ffCodecRegexp = /^\\s*([D\\.])([E\\.])([VAS])([I\\.])([L\\.])([S\\.]) ([^ ]+) +(.*)$/;","var ffEncodersRegexp = /\\(encoders:([^\\)]+)\\)/;","var ffDecodersRegexp = /\\(decoders:([^\\)]+)\\)/;","var formatRegexp = /^\\s*([D ])([E ]) ([^ ]+) +(.*)$/;","var lineBreakRegexp = /\\r\\n|\\r|\\n/;","var filterRegexp = /^(?: [T\\.][S\\.][C\\.] )?([^ ]+) +(AA?|VV?|\\|)->(AA?|VV?|\\|) +(.*)$/;","","var cache = {};","","module.exports = function(proto) {","  /**","   * Forget executable paths","   *","   * (only used for testing purposes)","   *","   * @method FfmpegCommand#_forgetPaths","   * @private","   */","  proto._forgetPaths = function() {","    delete cache.ffmpegPath;","    delete cache.ffprobePath;","    delete cache.flvtoolPath;","  };","","","  /**","   * Check for ffmpeg availability","   *","   * If the FFMPEG_PATH environment variable is set, try to use it.","   * If it is unset or incorrect, try to find ffmpeg in the PATH instead.","   *","   * @method FfmpegCommand#_getFfmpegPath","   * @param {Function} callback callback with signature (err, path)","   * @private","   */","  proto._getFfmpegPath = function(callback) {","    if ('ffmpegPath' in cache) {","      return callback(null, cache.ffmpegPath);","    }","","    async.waterfall([","      // Try FFMPEG_PATH","      function(cb) {","        if (process.env.FFMPEG_PATH) {","          fs.exists(process.env.FFMPEG_PATH, function(exists) {","            if (exists) {","              cb(null, process.env.FFMPEG_PATH);","            } else {","              cb(null, '');","            }","          });","        } else {","          cb(null, '');","        }","      },","","      // Search in the PATH","      function(ffmpeg, cb) {","        if (ffmpeg.length) {","          return cb(null, ffmpeg);","        }","","        utils.which('ffmpeg', function(err, ffmpeg) {","          cb(err, ffmpeg);","        });","      }","    ], function(err, ffmpeg) {","      if (err) {","        callback(err);","      } else {","        callback(null, cache.ffmpegPath = (ffmpeg || ''));","      }","    });","  };","","","  /**","   * Check for ffprobe availability","   *","   * If the FFPROBE_PATH environment variable is set, try to use it.","   * If it is unset or incorrect, try to find ffprobe in the PATH instead.","   * If this still fails, try to find ffprobe in the same directory as ffmpeg.","   *","   * @method FfmpegCommand#_getFfprobePath","   * @param {Function} callback callback with signature (err, path)","   * @private","   */","  proto._getFfprobePath = function(callback) {","    if ('ffprobePath' in cache) {","      return callback(null, cache.ffprobePath);","    }","","    var self = this;","    async.waterfall([","      // Try FFPROBE_PATH","      function(cb) {","        if (process.env.FFPROBE_PATH) {","          fs.exists(process.env.FFPROBE_PATH, function(exists) {","            cb(null, exists ? process.env.FFPROBE_PATH : '');","          });","        } else {","          cb(null, '');","        }","      },","","      // Search in the PATH","      function(ffprobe, cb) {","        if (ffprobe.length) {","          return cb(null, ffprobe);","        }","","        utils.which('ffprobe', function(err, ffprobe) {","          cb(err, ffprobe);","        });","      },","","      // Search in the same directory as ffmpeg","      function(ffprobe, cb) {","        if (ffprobe.length) {","          return cb(null, ffprobe);","        }","","        self._getFfmpegPath(function(err, ffmpeg) {","          if (err) {","            cb(err);","          } else if (ffmpeg.length) {","            var name = utils.isWindows ? 'ffprobe.exe' : 'ffprobe';","            var ffprobe = path.join(path.dirname(ffmpeg), name);","            fs.exists(ffprobe, function(exists) {","              cb(null, exists ? ffprobe : '');","            });","          } else {","            cb(null, '');","          }","        });","      }","    ], function(err, ffprobe) {","      if (err) {","        callback(err);","      } else {","        callback(null, cache.ffprobePath = (ffprobe || ''));","      }","    });","  };","","","  /**","   * Check for flvtool2/flvmeta availability","   *","   * If the FLVTOOL2_PATH or FLVMETA_PATH environment variable are set, try to use them.","   * If both are either unset or incorrect, try to find flvtool2 or flvmeta in the PATH instead.","   *","   * @method FfmpegCommand#_getFlvtoolPath","   * @param {Function} callback callback with signature (err, path)","   * @private","   */","  proto._getFlvtoolPath = function(callback) {","    if ('flvtoolPath' in cache) {","      return callback(null, cache.flvtoolPath);","    }","","    async.waterfall([","      // Try FLVMETA_PATH","      function(cb) {","        if (process.env.FLVMETA_PATH) {","          fs.exists(process.env.FLVMETA_PATH, function(exists) {","            cb(null, exists ? process.env.FLVMETA_PATH : '');","          });","        } else {","          cb(null, '');","        }","      },","","      // Try FLVTOOL2_PATH","      function(flvtool, cb) {","        if (flvtool.length) {","          return cb(null, flvtool);","        }","","        if (process.env.FLVTOOL2_PATH) {","          fs.exists(process.env.FLVTOOL2_PATH, function(exists) {","            cb(null, exists ? process.env.FLVTOOL2_PATH : '');","          });","        } else {","          cb(null, '');","        }","      },","","      // Search for flvmeta in the PATH","      function(flvtool, cb) {","        if (flvtool.length) {","          return cb(null, flvtool);","        }","","        utils.which('flvmeta', function(err, flvmeta) {","          cb(err, flvmeta);","        });","      },","","      // Search for flvtool2 in the PATH","      function(flvtool, cb) {","        if (flvtool.length) {","          return cb(null, flvtool);","        }","","        utils.which('flvtool2', function(err, flvtool2) {","          cb(err, flvtool2);","        });","      },","    ], function(err, flvtool) {","      if (err) {","        callback(err);","      } else {","        callback(null, cache.flvtoolPath = (flvtool || ''));","      }","    });","  };","","","  /**","   * A callback passed to {@link FfmpegCommand#availableFilters}.","   *","   * @callback FfmpegCommand~filterCallback","   * @param {Error|null} err error object or null if no error happened","   * @param {Object} filters filter object with filter names as keys and the following","   *   properties for each filter:","   * @param {String} filters.description filter description","   * @param {String} filters.input input type, one of 'audio', 'video' and 'none'","   * @param {Boolean} filters.multipleInputs whether the filter supports multiple inputs","   * @param {String} filters.output output type, one of 'audio', 'video' and 'none'","   * @param {Boolean} filters.multipleOutputs whether the filter supports multiple outputs","   */","","  /**","   * Query ffmpeg for available filters","   *","   * @method FfmpegCommand#availableFilters","   * @category Capabilities","   * @aliases getAvailableFilters","   *","   * @param {FfmpegCommand~filterCallback} callback callback function","   */","  proto.availableFilters =","  proto.getAvailableFilters = function(callback) {","    if ('filters' in cache) {","      return callback(null, cache.filters);","    }","","    this._spawnFfmpeg(['-filters'], { captureStdout: true }, function (err, stdout) {","      if (err) {","        return callback(err);","      }","","      var lines = stdout.split('\\n');","      var data = {};","      var types = { A: 'audio', V: 'video', '|': 'none' };","","      lines.forEach(function(line) {","        var match = line.match(filterRegexp);","        if (match) {","          data[match[1]] = {","            description: match[4],","            input: types[match[2].charAt(0)],","            multipleInputs: match[2].length > 1,","            output: types[match[3].charAt(0)],","            multipleOutputs: match[3].length > 1","          };","        }","      });","","      callback(null, cache.filters = data);","    });","  };","","","  /**","   * A callback passed to {@link FfmpegCommand#availableCodecs}.","   *","   * @callback FfmpegCommand~codecCallback","   * @param {Error|null} err error object or null if no error happened","   * @param {Object} codecs codec object with codec names as keys and the following","   *   properties for each codec (more properties may be available depending on the","   *   ffmpeg version used):","   * @param {String} codecs.description codec description","   * @param {Boolean} codecs.canDecode whether the codec is able to decode streams","   * @param {Boolean} codecs.canEncode whether the codec is able to encode streams","   */","","  /**","   * Query ffmpeg for available codecs","   *","   * @method FfmpegCommand#availableCodecs","   * @category Capabilities","   * @aliases getAvailableCodecs","   *","   * @param {FfmpegCommand~codecCallback} callback callback function","   */","  proto.availableCodecs =","  proto.getAvailableCodecs = function(callback) {","    if ('codecs' in cache) {","      return callback(null, cache.codecs);","    }","","    this._spawnFfmpeg(['-codecs'], { captureStdout: true }, function(err, stdout) {","      if (err) {","        return callback(err);","      }","","      var lines = stdout.split(lineBreakRegexp);","      var data = {};","","      lines.forEach(function(line) {","        var match = line.match(avCodecRegexp);","        if (match && match[7] !== '=') {","          data[match[7]] = {","            type: { 'V': 'video', 'A': 'audio', 'S': 'subtitle' }[match[3]],","            description: match[8],","            canDecode: match[1] === 'D',","            canEncode: match[2] === 'E',","            drawHorizBand: match[4] === 'S',","            directRendering: match[5] === 'D',","            weirdFrameTruncation: match[6] === 'T'","          };","        }","","        match = line.match(ffCodecRegexp);","        if (match && match[7] !== '=') {","          var codecData = data[match[7]] = {","            type: { 'V': 'video', 'A': 'audio', 'S': 'subtitle' }[match[3]],","            description: match[8],","            canDecode: match[1] === 'D',","            canEncode: match[2] === 'E',","            intraFrameOnly: match[4] === 'I',","            isLossy: match[5] === 'L',","            isLossless: match[6] === 'S'","          };","","          var encoders = codecData.description.match(ffEncodersRegexp);","          encoders = encoders ? encoders[1].trim().split(' ') : [];","","          var decoders = codecData.description.match(ffDecodersRegexp);","          decoders = decoders ? decoders[1].trim().split(' ') : [];","","          if (encoders.length || decoders.length) {","            var coderData = {};","            utils.copy(codecData, coderData);","            delete coderData.canEncode;","            delete coderData.canDecode;","","            encoders.forEach(function(name) {","              data[name] = {};","              utils.copy(coderData, data[name]);","              data[name].canEncode = true;","            });","","            decoders.forEach(function(name) {","              if (name in data) {","                data[name].canDecode = true;","              } else {","                data[name] = {};","                utils.copy(coderData, data[name]);","                data[name].canDecode = true;","              }","            });","          }","        }","      });","","      callback(null, cache.codecs = data);","    });","  };","","","  /**","   * A callback passed to {@link FfmpegCommand#availableFormats}.","   *","   * @callback FfmpegCommand~formatCallback","   * @param {Error|null} err error object or null if no error happened","   * @param {Object} formats format object with format names as keys and the following","   *   properties for each format:","   * @param {String} formats.description format description","   * @param {Boolean} formats.canDemux whether the format is able to demux streams from an input file","   * @param {Boolean} formats.canMux whether the format is able to mux streams into an output file","   */","","  /**","   * Query ffmpeg for available formats","   *","   * @method FfmpegCommand#availableFormats","   * @category Capabilities","   * @aliases getAvailableFormats","   *","   * @param {FfmpegCommand~formatCallback} callback callback function","   */","  proto.availableFormats =","  proto.getAvailableFormats = function(callback) {","    if ('formats' in cache) {","      return callback(null, cache.formats);","    }","","    // Run ffmpeg -formats","    this._spawnFfmpeg(['-formats'], { captureStdout: true }, function (err, stdout) {","      if (err) {","        return callback(err);","      }","","      // Parse output","      var lines = stdout.split(lineBreakRegexp);","      var data = {};","","      lines.forEach(function(line) {","        var match = line.match(formatRegexp);","        if (match) {","          data[match[3]] = {","            description: match[4],","            canDemux: match[1] === 'D',","            canMux: match[2] === 'E'","          };","        }","      });","","      callback(null, cache.formats = data);","    });","  };","","","  /**","   * Check capabilities before executing a command","   *","   * Checks whether all used codecs and formats are indeed available","   *","   * @method FfmpegCommand#_checkCapabilities","   * @param {Function} callback callback with signature (err)","   * @private","   */","  proto._checkCapabilities = function(callback) {","    var self = this;","    async.waterfall([","      // Get available formats","      function(cb) {","        self.availableFormats(cb);","      },","","      // Check whether specified formats are available","      function(formats, cb) {","        var unavailable;","","        // Output format(s)","        unavailable = self._outputs","          .reduce(function(fmts, output) {","            var format = output.options.find('-f', 1);","            if (format) {","              if (!(format[0] in formats) || !(formats[format[0]].canMux)) {","                fmts.push(format);","              }","            }","","            return fmts;","          }, []);","","        if (unavailable.length === 1) {","          return cb(new Error('Output format ' + unavailable[0] + ' is not available'));","        } else if (unavailable.length > 1) {","          return cb(new Error('Output formats ' + unavailable.join(', ') + ' are not available'));","        }","","        // Input format(s)","        unavailable = self._inputs","          .reduce(function(fmts, input) {","            var format = input.options.find('-f', 1);","            if (format) {","              if (!(format[0] in formats) || !(formats[format[0]].canDemux)) {","                fmts.push(format[0]);","              }","            }","","            return fmts;","          }, []);","","        if (unavailable.length === 1) {","          return cb(new Error('Input format ' + unavailable[0] + ' is not available'));","        } else if (unavailable.length > 1) {","          return cb(new Error('Input formats ' + unavailable.join(', ') + ' are not available'));","        }","","        cb();","      },","","      // Get available codecs","      function(cb) {","        self.availableCodecs(cb);","      },","","      // Check whether specified codecs are available","      function(codecs, cb) {","        var unavailable;","","        // Audio codec(s)","        unavailable = self._outputs.reduce(function(cdcs, output) {","          var acodec = output.audio.find('-acodec', 1);","          if (acodec && acodec[0] !== 'copy') {","            if (!(acodec[0] in codecs) || codecs[acodec[0]].type !== 'audio' || !(codecs[acodec[0]].canEncode)) {","              cdcs.push(acodec[0]);","            }","          }","","          return cdcs;","        }, []);","","        if (unavailable.length === 1) {","          return cb(new Error('Audio codec ' + unavailable[0] + ' is not available'));","        } else if (unavailable.length > 1) {","          return cb(new Error('Audio codecs ' + unavailable.join(', ') + ' are not available'));","        }","","        // Video codec(s)","        unavailable = self._outputs.reduce(function(cdcs, output) {","          var vcodec = output.video.find('-vcodec', 1);","          if (vcodec && vcodec[0] !== 'copy') {","            if (!(vcodec[0] in codecs) || codecs[vcodec[0]].type !== 'video' || !(codecs[vcodec[0]].canEncode)) {","              cdcs.push(vcodec[0]);","            }","          }","","          return cdcs;","        }, []);","","        if (unavailable.length === 1) {","          return cb(new Error('Video codec ' + unavailable[0] + ' is not available'));","        } else if (unavailable.length > 1) {","          return cb(new Error('Video codecs ' + unavailable.join(', ') + ' are not available'));","        }","","        cb();","      }","    ], callback);","  };","};",""];
"use strict";

_$jscoverage_done("lib/capabilities.js", 4);
var fs = require("fs");

_$jscoverage_done("lib/capabilities.js", 5);
var path = require("path");

_$jscoverage_done("lib/capabilities.js", 6);
var async = require("async");

_$jscoverage_done("lib/capabilities.js", 7);
var utils = require("./utils");

_$jscoverage_done("lib/capabilities.js", 13);
var avCodecRegexp = /^\s*([D ])([E ])([VAS])([S ])([D ])([T ]) ([^ ]+) +(.*)$/;

_$jscoverage_done("lib/capabilities.js", 14);
var ffCodecRegexp = /^\s*([D\.])([E\.])([VAS])([I\.])([L\.])([S\.]) ([^ ]+) +(.*)$/;

_$jscoverage_done("lib/capabilities.js", 15);
var ffEncodersRegexp = /\(encoders:([^\)]+)\)/;

_$jscoverage_done("lib/capabilities.js", 16);
var ffDecodersRegexp = /\(decoders:([^\)]+)\)/;

_$jscoverage_done("lib/capabilities.js", 17);
var formatRegexp = /^\s*([D ])([E ]) ([^ ]+) +(.*)$/;

_$jscoverage_done("lib/capabilities.js", 18);
var lineBreakRegexp = /\r\n|\r|\n/;

_$jscoverage_done("lib/capabilities.js", 19);
var filterRegexp = /^(?: [T\.][S\.][C\.] )?([^ ]+) +(AA?|VV?|\|)->(AA?|VV?|\|) +(.*)$/;

_$jscoverage_done("lib/capabilities.js", 21);
var cache = {};

_$jscoverage_done("lib/capabilities.js", 23);
module.exports = function(proto) {
    _$jscoverage_done("lib/capabilities.js", 32);
    proto._forgetPaths = function() {
        _$jscoverage_done("lib/capabilities.js", 33);
        delete cache.ffmpegPath;
        _$jscoverage_done("lib/capabilities.js", 34);
        delete cache.ffprobePath;
        _$jscoverage_done("lib/capabilities.js", 35);
        delete cache.flvtoolPath;
    };
    _$jscoverage_done("lib/capabilities.js", 49);
    proto._getFfmpegPath = function(callback) {
        _$jscoverage_done("lib/capabilities.js", 50);
        if (_$jscoverage_done("lib/capabilities.js", 50, "ffmpegPath" in cache)) {
            _$jscoverage_done("lib/capabilities.js", 51);
            return callback(null, cache.ffmpegPath);
        }
        _$jscoverage_done("lib/capabilities.js", 54);
        async.waterfall([ function(cb) {
            _$jscoverage_done("lib/capabilities.js", 57);
            if (_$jscoverage_done("lib/capabilities.js", 57, process.env.FFMPEG_PATH)) {
                _$jscoverage_done("lib/capabilities.js", 58);
                fs.exists(process.env.FFMPEG_PATH, function(exists) {
                    _$jscoverage_done("lib/capabilities.js", 59);
                    if (_$jscoverage_done("lib/capabilities.js", 59, exists)) {
                        _$jscoverage_done("lib/capabilities.js", 60);
                        cb(null, process.env.FFMPEG_PATH);
                    } else {
                        _$jscoverage_done("lib/capabilities.js", 62);
                        cb(null, "");
                    }
                });
            } else {
                _$jscoverage_done("lib/capabilities.js", 66);
                cb(null, "");
            }
        }, function(ffmpeg, cb) {
            _$jscoverage_done("lib/capabilities.js", 72);
            if (_$jscoverage_done("lib/capabilities.js", 72, ffmpeg.length)) {
                _$jscoverage_done("lib/capabilities.js", 73);
                return cb(null, ffmpeg);
            }
            _$jscoverage_done("lib/capabilities.js", 76);
            utils.which("ffmpeg", function(err, ffmpeg) {
                _$jscoverage_done("lib/capabilities.js", 77);
                cb(err, ffmpeg);
            });
        } ], function(err, ffmpeg) {
            _$jscoverage_done("lib/capabilities.js", 81);
            if (_$jscoverage_done("lib/capabilities.js", 81, err)) {
                _$jscoverage_done("lib/capabilities.js", 82);
                callback(err);
            } else {
                _$jscoverage_done("lib/capabilities.js", 84);
                callback(null, cache.ffmpegPath = ffmpeg || "");
            }
        });
    };
    _$jscoverage_done("lib/capabilities.js", 101);
    proto._getFfprobePath = function(callback) {
        _$jscoverage_done("lib/capabilities.js", 102);
        if (_$jscoverage_done("lib/capabilities.js", 102, "ffprobePath" in cache)) {
            _$jscoverage_done("lib/capabilities.js", 103);
            return callback(null, cache.ffprobePath);
        }
        _$jscoverage_done("lib/capabilities.js", 106);
        var self = this;
        _$jscoverage_done("lib/capabilities.js", 107);
        async.waterfall([ function(cb) {
            _$jscoverage_done("lib/capabilities.js", 110);
            if (_$jscoverage_done("lib/capabilities.js", 110, process.env.FFPROBE_PATH)) {
                _$jscoverage_done("lib/capabilities.js", 111);
                fs.exists(process.env.FFPROBE_PATH, function(exists) {
                    _$jscoverage_done("lib/capabilities.js", 112);
                    cb(null, exists ? process.env.FFPROBE_PATH : "");
                });
            } else {
                _$jscoverage_done("lib/capabilities.js", 115);
                cb(null, "");
            }
        }, function(ffprobe, cb) {
            _$jscoverage_done("lib/capabilities.js", 121);
            if (_$jscoverage_done("lib/capabilities.js", 121, ffprobe.length)) {
                _$jscoverage_done("lib/capabilities.js", 122);
                return cb(null, ffprobe);
            }
            _$jscoverage_done("lib/capabilities.js", 125);
            utils.which("ffprobe", function(err, ffprobe) {
                _$jscoverage_done("lib/capabilities.js", 126);
                cb(err, ffprobe);
            });
        }, function(ffprobe, cb) {
            _$jscoverage_done("lib/capabilities.js", 132);
            if (_$jscoverage_done("lib/capabilities.js", 132, ffprobe.length)) {
                _$jscoverage_done("lib/capabilities.js", 133);
                return cb(null, ffprobe);
            }
            _$jscoverage_done("lib/capabilities.js", 136);
            self._getFfmpegPath(function(err, ffmpeg) {
                _$jscoverage_done("lib/capabilities.js", 137);
                if (_$jscoverage_done("lib/capabilities.js", 137, err)) {
                    _$jscoverage_done("lib/capabilities.js", 138);
                    cb(err);
                } else {
                    _$jscoverage_done("lib/capabilities.js", 139);
                    if (_$jscoverage_done("lib/capabilities.js", 139, ffmpeg.length)) {
                        _$jscoverage_done("lib/capabilities.js", 140);
                        var name = utils.isWindows ? "ffprobe.exe" : "ffprobe";
                        _$jscoverage_done("lib/capabilities.js", 141);
                        var ffprobe = path.join(path.dirname(ffmpeg), name);
                        _$jscoverage_done("lib/capabilities.js", 142);
                        fs.exists(ffprobe, function(exists) {
                            _$jscoverage_done("lib/capabilities.js", 143);
                            cb(null, exists ? ffprobe : "");
                        });
                    } else {
                        _$jscoverage_done("lib/capabilities.js", 146);
                        cb(null, "");
                    }
                }
            });
        } ], function(err, ffprobe) {
            _$jscoverage_done("lib/capabilities.js", 151);
            if (_$jscoverage_done("lib/capabilities.js", 151, err)) {
                _$jscoverage_done("lib/capabilities.js", 152);
                callback(err);
            } else {
                _$jscoverage_done("lib/capabilities.js", 154);
                callback(null, cache.ffprobePath = ffprobe || "");
            }
        });
    };
    _$jscoverage_done("lib/capabilities.js", 170);
    proto._getFlvtoolPath = function(callback) {
        _$jscoverage_done("lib/capabilities.js", 171);
        if (_$jscoverage_done("lib/capabilities.js", 171, "flvtoolPath" in cache)) {
            _$jscoverage_done("lib/capabilities.js", 172);
            return callback(null, cache.flvtoolPath);
        }
        _$jscoverage_done("lib/capabilities.js", 175);
        async.waterfall([ function(cb) {
            _$jscoverage_done("lib/capabilities.js", 178);
            if (_$jscoverage_done("lib/capabilities.js", 178, process.env.FLVMETA_PATH)) {
                _$jscoverage_done("lib/capabilities.js", 179);
                fs.exists(process.env.FLVMETA_PATH, function(exists) {
                    _$jscoverage_done("lib/capabilities.js", 180);
                    cb(null, exists ? process.env.FLVMETA_PATH : "");
                });
            } else {
                _$jscoverage_done("lib/capabilities.js", 183);
                cb(null, "");
            }
        }, function(flvtool, cb) {
            _$jscoverage_done("lib/capabilities.js", 189);
            if (_$jscoverage_done("lib/capabilities.js", 189, flvtool.length)) {
                _$jscoverage_done("lib/capabilities.js", 190);
                return cb(null, flvtool);
            }
            _$jscoverage_done("lib/capabilities.js", 193);
            if (_$jscoverage_done("lib/capabilities.js", 193, process.env.FLVTOOL2_PATH)) {
                _$jscoverage_done("lib/capabilities.js", 194);
                fs.exists(process.env.FLVTOOL2_PATH, function(exists) {
                    _$jscoverage_done("lib/capabilities.js", 195);
                    cb(null, exists ? process.env.FLVTOOL2_PATH : "");
                });
            } else {
                _$jscoverage_done("lib/capabilities.js", 198);
                cb(null, "");
            }
        }, function(flvtool, cb) {
            _$jscoverage_done("lib/capabilities.js", 204);
            if (_$jscoverage_done("lib/capabilities.js", 204, flvtool.length)) {
                _$jscoverage_done("lib/capabilities.js", 205);
                return cb(null, flvtool);
            }
            _$jscoverage_done("lib/capabilities.js", 208);
            utils.which("flvmeta", function(err, flvmeta) {
                _$jscoverage_done("lib/capabilities.js", 209);
                cb(err, flvmeta);
            });
        }, function(flvtool, cb) {
            _$jscoverage_done("lib/capabilities.js", 215);
            if (_$jscoverage_done("lib/capabilities.js", 215, flvtool.length)) {
                _$jscoverage_done("lib/capabilities.js", 216);
                return cb(null, flvtool);
            }
            _$jscoverage_done("lib/capabilities.js", 219);
            utils.which("flvtool2", function(err, flvtool2) {
                _$jscoverage_done("lib/capabilities.js", 220);
                cb(err, flvtool2);
            });
        } ], function(err, flvtool) {
            _$jscoverage_done("lib/capabilities.js", 224);
            if (_$jscoverage_done("lib/capabilities.js", 224, err)) {
                _$jscoverage_done("lib/capabilities.js", 225);
                callback(err);
            } else {
                _$jscoverage_done("lib/capabilities.js", 227);
                callback(null, cache.flvtoolPath = flvtool || "");
            }
        });
    };
    _$jscoverage_done("lib/capabilities.js", 256);
    proto.availableFilters = proto.getAvailableFilters = function(callback) {
        _$jscoverage_done("lib/capabilities.js", 258);
        if (_$jscoverage_done("lib/capabilities.js", 258, "filters" in cache)) {
            _$jscoverage_done("lib/capabilities.js", 259);
            return callback(null, cache.filters);
        }
        _$jscoverage_done("lib/capabilities.js", 262);
        this._spawnFfmpeg([ "-filters" ], {
            captureStdout: true
        }, function(err, stdout) {
            _$jscoverage_done("lib/capabilities.js", 263);
            if (_$jscoverage_done("lib/capabilities.js", 263, err)) {
                _$jscoverage_done("lib/capabilities.js", 264);
                return callback(err);
            }
            _$jscoverage_done("lib/capabilities.js", 267);
            var lines = stdout.split("\n");
            _$jscoverage_done("lib/capabilities.js", 268);
            var data = {};
            _$jscoverage_done("lib/capabilities.js", 269);
            var types = {
                A: "audio",
                V: "video",
                "|": "none"
            };
            _$jscoverage_done("lib/capabilities.js", 271);
            lines.forEach(function(line) {
                _$jscoverage_done("lib/capabilities.js", 272);
                var match = line.match(filterRegexp);
                _$jscoverage_done("lib/capabilities.js", 273);
                if (_$jscoverage_done("lib/capabilities.js", 273, match)) {
                    _$jscoverage_done("lib/capabilities.js", 274);
                    data[match[1]] = {
                        description: match[4],
                        input: types[match[2].charAt(0)],
                        multipleInputs: match[2].length > 1,
                        output: types[match[3].charAt(0)],
                        multipleOutputs: match[3].length > 1
                    };
                }
            });
            _$jscoverage_done("lib/capabilities.js", 284);
            callback(null, cache.filters = data);
        });
    };
    _$jscoverage_done("lib/capabilities.js", 311);
    proto.availableCodecs = proto.getAvailableCodecs = function(callback) {
        _$jscoverage_done("lib/capabilities.js", 313);
        if (_$jscoverage_done("lib/capabilities.js", 313, "codecs" in cache)) {
            _$jscoverage_done("lib/capabilities.js", 314);
            return callback(null, cache.codecs);
        }
        _$jscoverage_done("lib/capabilities.js", 317);
        this._spawnFfmpeg([ "-codecs" ], {
            captureStdout: true
        }, function(err, stdout) {
            _$jscoverage_done("lib/capabilities.js", 318);
            if (_$jscoverage_done("lib/capabilities.js", 318, err)) {
                _$jscoverage_done("lib/capabilities.js", 319);
                return callback(err);
            }
            _$jscoverage_done("lib/capabilities.js", 322);
            var lines = stdout.split(lineBreakRegexp);
            _$jscoverage_done("lib/capabilities.js", 323);
            var data = {};
            _$jscoverage_done("lib/capabilities.js", 325);
            lines.forEach(function(line) {
                _$jscoverage_done("lib/capabilities.js", 326);
                var match = line.match(avCodecRegexp);
                _$jscoverage_done("lib/capabilities.js", 327);
                if (_$jscoverage_done("lib/capabilities.js", 327, match) && _$jscoverage_done("lib/capabilities.js", 327, match[7] !== "=")) {
                    _$jscoverage_done("lib/capabilities.js", 328);
                    data[match[7]] = {
                        type: {
                            V: "video",
                            A: "audio",
                            S: "subtitle"
                        }[match[3]],
                        description: match[8],
                        canDecode: match[1] === "D",
                        canEncode: match[2] === "E",
                        drawHorizBand: match[4] === "S",
                        directRendering: match[5] === "D",
                        weirdFrameTruncation: match[6] === "T"
                    };
                }
                _$jscoverage_done("lib/capabilities.js", 339);
                match = line.match(ffCodecRegexp);
                _$jscoverage_done("lib/capabilities.js", 340);
                if (_$jscoverage_done("lib/capabilities.js", 340, match) && _$jscoverage_done("lib/capabilities.js", 340, match[7] !== "=")) {
                    _$jscoverage_done("lib/capabilities.js", 341);
                    var codecData = data[match[7]] = {
                        type: {
                            V: "video",
                            A: "audio",
                            S: "subtitle"
                        }[match[3]],
                        description: match[8],
                        canDecode: match[1] === "D",
                        canEncode: match[2] === "E",
                        intraFrameOnly: match[4] === "I",
                        isLossy: match[5] === "L",
                        isLossless: match[6] === "S"
                    };
                    _$jscoverage_done("lib/capabilities.js", 351);
                    var encoders = codecData.description.match(ffEncodersRegexp);
                    _$jscoverage_done("lib/capabilities.js", 352);
                    encoders = encoders ? encoders[1].trim().split(" ") : [];
                    _$jscoverage_done("lib/capabilities.js", 354);
                    var decoders = codecData.description.match(ffDecodersRegexp);
                    _$jscoverage_done("lib/capabilities.js", 355);
                    decoders = decoders ? decoders[1].trim().split(" ") : [];
                    _$jscoverage_done("lib/capabilities.js", 357);
                    if (_$jscoverage_done("lib/capabilities.js", 357, encoders.length) || _$jscoverage_done("lib/capabilities.js", 357, decoders.length)) {
                        _$jscoverage_done("lib/capabilities.js", 358);
                        var coderData = {};
                        _$jscoverage_done("lib/capabilities.js", 359);
                        utils.copy(codecData, coderData);
                        _$jscoverage_done("lib/capabilities.js", 360);
                        delete coderData.canEncode;
                        _$jscoverage_done("lib/capabilities.js", 361);
                        delete coderData.canDecode;
                        _$jscoverage_done("lib/capabilities.js", 363);
                        encoders.forEach(function(name) {
                            _$jscoverage_done("lib/capabilities.js", 364);
                            data[name] = {};
                            _$jscoverage_done("lib/capabilities.js", 365);
                            utils.copy(coderData, data[name]);
                            _$jscoverage_done("lib/capabilities.js", 366);
                            data[name].canEncode = true;
                        });
                        _$jscoverage_done("lib/capabilities.js", 369);
                        decoders.forEach(function(name) {
                            _$jscoverage_done("lib/capabilities.js", 370);
                            if (_$jscoverage_done("lib/capabilities.js", 370, name in data)) {
                                _$jscoverage_done("lib/capabilities.js", 371);
                                data[name].canDecode = true;
                            } else {
                                _$jscoverage_done("lib/capabilities.js", 373);
                                data[name] = {};
                                _$jscoverage_done("lib/capabilities.js", 374);
                                utils.copy(coderData, data[name]);
                                _$jscoverage_done("lib/capabilities.js", 375);
                                data[name].canDecode = true;
                            }
                        });
                    }
                }
            });
            _$jscoverage_done("lib/capabilities.js", 382);
            callback(null, cache.codecs = data);
        });
    };
    _$jscoverage_done("lib/capabilities.js", 408);
    proto.availableFormats = proto.getAvailableFormats = function(callback) {
        _$jscoverage_done("lib/capabilities.js", 410);
        if (_$jscoverage_done("lib/capabilities.js", 410, "formats" in cache)) {
            _$jscoverage_done("lib/capabilities.js", 411);
            return callback(null, cache.formats);
        }
        _$jscoverage_done("lib/capabilities.js", 415);
        this._spawnFfmpeg([ "-formats" ], {
            captureStdout: true
        }, function(err, stdout) {
            _$jscoverage_done("lib/capabilities.js", 416);
            if (_$jscoverage_done("lib/capabilities.js", 416, err)) {
                _$jscoverage_done("lib/capabilities.js", 417);
                return callback(err);
            }
            _$jscoverage_done("lib/capabilities.js", 421);
            var lines = stdout.split(lineBreakRegexp);
            _$jscoverage_done("lib/capabilities.js", 422);
            var data = {};
            _$jscoverage_done("lib/capabilities.js", 424);
            lines.forEach(function(line) {
                _$jscoverage_done("lib/capabilities.js", 425);
                var match = line.match(formatRegexp);
                _$jscoverage_done("lib/capabilities.js", 426);
                if (_$jscoverage_done("lib/capabilities.js", 426, match)) {
                    _$jscoverage_done("lib/capabilities.js", 427);
                    data[match[3]] = {
                        description: match[4],
                        canDemux: match[1] === "D",
                        canMux: match[2] === "E"
                    };
                }
            });
            _$jscoverage_done("lib/capabilities.js", 435);
            callback(null, cache.formats = data);
        });
    };
    _$jscoverage_done("lib/capabilities.js", 449);
    proto._checkCapabilities = function(callback) {
        _$jscoverage_done("lib/capabilities.js", 450);
        var self = this;
        _$jscoverage_done("lib/capabilities.js", 451);
        async.waterfall([ function(cb) {
            _$jscoverage_done("lib/capabilities.js", 454);
            self.availableFormats(cb);
        }, function(formats, cb) {
            _$jscoverage_done("lib/capabilities.js", 459);
            var unavailable;
            _$jscoverage_done("lib/capabilities.js", 462);
            unavailable = self._outputs.reduce(function(fmts, output) {
                _$jscoverage_done("lib/capabilities.js", 464);
                var format = output.options.find("-f", 1);
                _$jscoverage_done("lib/capabilities.js", 465);
                if (_$jscoverage_done("lib/capabilities.js", 465, format)) {
                    _$jscoverage_done("lib/capabilities.js", 466);
                    if (_$jscoverage_done("lib/capabilities.js", 466, !(format[0] in formats)) || _$jscoverage_done("lib/capabilities.js", 466, !formats[format[0]].canMux)) {
                        _$jscoverage_done("lib/capabilities.js", 467);
                        fmts.push(format);
                    }
                }
                _$jscoverage_done("lib/capabilities.js", 471);
                return fmts;
            }, []);
            _$jscoverage_done("lib/capabilities.js", 474);
            if (_$jscoverage_done("lib/capabilities.js", 474, unavailable.length === 1)) {
                _$jscoverage_done("lib/capabilities.js", 475);
                return cb(new Error("Output format " + unavailable[0] + " is not available"));
            } else {
                _$jscoverage_done("lib/capabilities.js", 476);
                if (_$jscoverage_done("lib/capabilities.js", 476, unavailable.length > 1)) {
                    _$jscoverage_done("lib/capabilities.js", 477);
                    return cb(new Error("Output formats " + unavailable.join(", ") + " are not available"));
                }
            }
            _$jscoverage_done("lib/capabilities.js", 481);
            unavailable = self._inputs.reduce(function(fmts, input) {
                _$jscoverage_done("lib/capabilities.js", 483);
                var format = input.options.find("-f", 1);
                _$jscoverage_done("lib/capabilities.js", 484);
                if (_$jscoverage_done("lib/capabilities.js", 484, format)) {
                    _$jscoverage_done("lib/capabilities.js", 485);
                    if (_$jscoverage_done("lib/capabilities.js", 485, !(format[0] in formats)) || _$jscoverage_done("lib/capabilities.js", 485, !formats[format[0]].canDemux)) {
                        _$jscoverage_done("lib/capabilities.js", 486);
                        fmts.push(format[0]);
                    }
                }
                _$jscoverage_done("lib/capabilities.js", 490);
                return fmts;
            }, []);
            _$jscoverage_done("lib/capabilities.js", 493);
            if (_$jscoverage_done("lib/capabilities.js", 493, unavailable.length === 1)) {
                _$jscoverage_done("lib/capabilities.js", 494);
                return cb(new Error("Input format " + unavailable[0] + " is not available"));
            } else {
                _$jscoverage_done("lib/capabilities.js", 495);
                if (_$jscoverage_done("lib/capabilities.js", 495, unavailable.length > 1)) {
                    _$jscoverage_done("lib/capabilities.js", 496);
                    return cb(new Error("Input formats " + unavailable.join(", ") + " are not available"));
                }
            }
            _$jscoverage_done("lib/capabilities.js", 499);
            cb();
        }, function(cb) {
            _$jscoverage_done("lib/capabilities.js", 504);
            self.availableCodecs(cb);
        }, function(codecs, cb) {
            _$jscoverage_done("lib/capabilities.js", 509);
            var unavailable;
            _$jscoverage_done("lib/capabilities.js", 512);
            unavailable = self._outputs.reduce(function(cdcs, output) {
                _$jscoverage_done("lib/capabilities.js", 513);
                var acodec = output.audio.find("-acodec", 1);
                _$jscoverage_done("lib/capabilities.js", 514);
                if (_$jscoverage_done("lib/capabilities.js", 514, acodec) && _$jscoverage_done("lib/capabilities.js", 514, acodec[0] !== "copy")) {
                    _$jscoverage_done("lib/capabilities.js", 515);
                    if (_$jscoverage_done("lib/capabilities.js", 515, !(acodec[0] in codecs)) || _$jscoverage_done("lib/capabilities.js", 515, codecs[acodec[0]].type !== "audio") || _$jscoverage_done("lib/capabilities.js", 515, !codecs[acodec[0]].canEncode)) {
                        _$jscoverage_done("lib/capabilities.js", 516);
                        cdcs.push(acodec[0]);
                    }
                }
                _$jscoverage_done("lib/capabilities.js", 520);
                return cdcs;
            }, []);
            _$jscoverage_done("lib/capabilities.js", 523);
            if (_$jscoverage_done("lib/capabilities.js", 523, unavailable.length === 1)) {
                _$jscoverage_done("lib/capabilities.js", 524);
                return cb(new Error("Audio codec " + unavailable[0] + " is not available"));
            } else {
                _$jscoverage_done("lib/capabilities.js", 525);
                if (_$jscoverage_done("lib/capabilities.js", 525, unavailable.length > 1)) {
                    _$jscoverage_done("lib/capabilities.js", 526);
                    return cb(new Error("Audio codecs " + unavailable.join(", ") + " are not available"));
                }
            }
            _$jscoverage_done("lib/capabilities.js", 530);
            unavailable = self._outputs.reduce(function(cdcs, output) {
                _$jscoverage_done("lib/capabilities.js", 531);
                var vcodec = output.video.find("-vcodec", 1);
                _$jscoverage_done("lib/capabilities.js", 532);
                if (_$jscoverage_done("lib/capabilities.js", 532, vcodec) && _$jscoverage_done("lib/capabilities.js", 532, vcodec[0] !== "copy")) {
                    _$jscoverage_done("lib/capabilities.js", 533);
                    if (_$jscoverage_done("lib/capabilities.js", 533, !(vcodec[0] in codecs)) || _$jscoverage_done("lib/capabilities.js", 533, codecs[vcodec[0]].type !== "video") || _$jscoverage_done("lib/capabilities.js", 533, !codecs[vcodec[0]].canEncode)) {
                        _$jscoverage_done("lib/capabilities.js", 534);
                        cdcs.push(vcodec[0]);
                    }
                }
                _$jscoverage_done("lib/capabilities.js", 538);
                return cdcs;
            }, []);
            _$jscoverage_done("lib/capabilities.js", 541);
            if (_$jscoverage_done("lib/capabilities.js", 541, unavailable.length === 1)) {
                _$jscoverage_done("lib/capabilities.js", 542);
                return cb(new Error("Video codec " + unavailable[0] + " is not available"));
            } else {
                _$jscoverage_done("lib/capabilities.js", 543);
                if (_$jscoverage_done("lib/capabilities.js", 543, unavailable.length > 1)) {
                    _$jscoverage_done("lib/capabilities.js", 544);
                    return cb(new Error("Video codecs " + unavailable.join(", ") + " are not available"));
                }
            }
            _$jscoverage_done("lib/capabilities.js", 547);
            cb();
        } ], callback);
    };
};