# Source: options/output.js

    /*jshint node:true*/
    'use strict';

    var utils = require('../utils');

    /*
     *! Output-related methods
     */

    module.exports = function(proto) {
      /**
       * Add output
       *
       * @method FfmpegCommand#output
       * @category Output
       * @aliases addOutput
       *
       * @param {String|Writable} target target file path or writable stream
       * @param {Object} [pipeopts={}] pipe options (only applies to streams)
       * @return FfmpegCommand
       */
      proto.addOutput =
      proto.output = function(target, pipeopts) {
        var isFile = false;

        if (!target && this._currentOutput) {
          // No target is only allowed when called from constructor
          throw new Error('Invalid output');
        }

        if (target && typeof target !== 'string') {
          if (!('writable' in target) || !(target.writable)) {
            throw new Error('Invalid output');
          }
        } else if (typeof target === 'string') {
          var protocol = target.match(/^([a-z]{2,}):/i);
          isFile = !protocol || protocol[0] === 'file';
        }

        if (target && !('target' in this._currentOutput)) {
          // For backwards compatibility, set target for first output
          this._currentOutput.target = target;
          this._currentOutput.isFile = isFile;
          this._currentOutput.pipeopts = pipeopts || {};
        } else {
          if (target && typeof target !== 'string') {
            var hasOutputStream = this._outputs.some(function(output) {
              return typeof output.target !== 'string';
            });

            if (hasOutputStream) {
              throw new Error('Only one output stream is supported');
            }
          }

          this._outputs.push(this._currentOutput = {
            target: target,
            isFile: isFile,
            flags: {},
            pipeopts: pipeopts || {}
          });

          var self = this;
          ['audio', 'audioFilters', 'video', 'videoFilters', 'sizeFilters', 'options'].forEach(function(key) {
            self._currentOutput[key] = utils.args();
          });

          if (!target) {
            // Call from constructor: remove target key
            delete this._currentOutput.target;
          }
        }

        return this;
      };

      /**
       * Specify output seek time
       *
       * @method FfmpegCommand#seek
       * @category Input
       * @aliases seekOutput
       *
       * @param {String|Number} seek seek time in seconds or as a '[hh:[mm:]]ss[.xxx]' string
       * @return FfmpegCommand
       */
      proto.seekOutput =
      proto.seek = function(seek) {
        this._currentOutput.options('-ss', seek);
        return this;
      };

      /**
       * Set output duration
       *
       * @method FfmpegCommand#duration
       * @category Output
       * @aliases withDuration,setDuration
       *
       * @param {String|Number} duration duration in seconds or as a '[[hh:]mm:]ss[.xxx]' string
       * @return FfmpegCommand
       */
      proto.withDuration =
      proto.setDuration =
      proto.duration = function(duration) {
        this._currentOutput.options('-t', duration);
        return this;
      };

      /**
       * Set output format
       *
       * @method FfmpegCommand#format
       * @category Output
       * @aliases toFormat,withOutputFormat,outputFormat
       *
       * @param {String} format output format name
       * @return FfmpegCommand
       */
      proto.toFormat =
      proto.withOutputFormat =
      proto.outputFormat =
      proto.format = function(format) {
        this._currentOutput.options('-f', format);
        return this;
      };

      /**
       * Add stream mapping to output
       *
       * @method FfmpegCommand#map
       * @category Output
       *
       * @param {String} spec stream specification string, with optional square brackets
       * @return FfmpegCommand
       */
      proto.map = function(spec) {
        this._currentOutput.options('-map', spec.replace(utils.streamRegexp, '[$1]'));
        return this;
      };

      /**
       * Run flvtool2/flvmeta on output
       *
       * @method FfmpegCommand#flvmeta
       * @category Output
       * @aliases updateFlvMetadata
       *
       * @return FfmpegCommand
       */
      proto.updateFlvMetadata =
      proto.flvmeta = function() {
        this._currentOutput.flags.flvmeta = true;
        return this;
      };
    };