inputs.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*jshint node:true*/
  2. 'use strict';
  3. var utils = require('../utils');
  4. /*
  5. *! Input-related methods
  6. */
  7. module.exports = function(proto) {
  8. /**
  9. * Add an input to command
  10. *
  11. * Also switches "current input", that is the input that will be affected
  12. * by subsequent input-related methods.
  13. *
  14. * Note: only one stream input is supported for now.
  15. *
  16. * @method FfmpegCommand#input
  17. * @category Input
  18. * @aliases mergeAdd,addInput
  19. *
  20. * @param {String|Readable} source input file path or readable stream
  21. * @return FfmpegCommand
  22. */
  23. proto.mergeAdd =
  24. proto.addInput =
  25. proto.input = function(source) {
  26. var isFile = false;
  27. var isStream = false;
  28. if (typeof source !== 'string') {
  29. if (!('readable' in source) || !(source.readable)) {
  30. throw new Error('Invalid input');
  31. }
  32. var hasInputStream = this._inputs.some(function(input) {
  33. return input.isStream;
  34. });
  35. if (hasInputStream) {
  36. throw new Error('Only one input stream is supported');
  37. }
  38. isStream = true;
  39. source.pause();
  40. } else {
  41. var protocol = source.match(/^([a-z]{2,}):/i);
  42. isFile = !protocol || protocol[0] === 'file';
  43. }
  44. this._inputs.push(this._currentInput = {
  45. source: source,
  46. isFile: isFile,
  47. isStream: isStream,
  48. options: utils.args()
  49. });
  50. return this;
  51. };
  52. /**
  53. * Specify input format for the last specified input
  54. *
  55. * @method FfmpegCommand#inputFormat
  56. * @category Input
  57. * @aliases withInputFormat,fromFormat
  58. *
  59. * @param {String} format input format
  60. * @return FfmpegCommand
  61. */
  62. proto.withInputFormat =
  63. proto.inputFormat =
  64. proto.fromFormat = function(format) {
  65. if (!this._currentInput) {
  66. throw new Error('No input specified');
  67. }
  68. this._currentInput.options('-f', format);
  69. return this;
  70. };
  71. /**
  72. * Specify input FPS for the last specified input
  73. * (only valid for raw video formats)
  74. *
  75. * @method FfmpegCommand#inputFps
  76. * @category Input
  77. * @aliases withInputFps,withInputFPS,withFpsInput,withFPSInput,inputFPS,inputFps,fpsInput
  78. *
  79. * @param {Number} fps input FPS
  80. * @return FfmpegCommand
  81. */
  82. proto.withInputFps =
  83. proto.withInputFPS =
  84. proto.withFpsInput =
  85. proto.withFPSInput =
  86. proto.inputFPS =
  87. proto.inputFps =
  88. proto.fpsInput =
  89. proto.FPSInput = function(fps) {
  90. if (!this._currentInput) {
  91. throw new Error('No input specified');
  92. }
  93. this._currentInput.options('-r', fps);
  94. return this;
  95. };
  96. /**
  97. * Use native framerate for the last specified input
  98. *
  99. * @method FfmpegCommand#native
  100. * @category Input
  101. * @aliases nativeFramerate,withNativeFramerate
  102. *
  103. * @return FfmmegCommand
  104. */
  105. proto.nativeFramerate =
  106. proto.withNativeFramerate =
  107. proto.native = function() {
  108. if (!this._currentInput) {
  109. throw new Error('No input specified');
  110. }
  111. this._currentInput.options('-re');
  112. return this;
  113. };
  114. /**
  115. * Specify input seek time for the last specified input
  116. *
  117. * @method FfmpegCommand#seekInput
  118. * @category Input
  119. * @aliases setStartTime,seekTo
  120. *
  121. * @param {String|Number} seek seek time in seconds or as a '[hh:[mm:]]ss[.xxx]' string
  122. * @return FfmpegCommand
  123. */
  124. proto.setStartTime =
  125. proto.seekInput = function(seek) {
  126. if (!this._currentInput) {
  127. throw new Error('No input specified');
  128. }
  129. this._currentInput.options('-ss', seek);
  130. return this;
  131. };
  132. /**
  133. * Loop over the last specified input
  134. *
  135. * @method FfmpegCommand#loop
  136. * @category Input
  137. *
  138. * @param {String|Number} [duration] loop duration in seconds or as a '[[hh:]mm:]ss[.xxx]' string
  139. * @return FfmpegCommand
  140. */
  141. proto.loop = function(duration) {
  142. if (!this._currentInput) {
  143. throw new Error('No input specified');
  144. }
  145. this._currentInput.options('-loop', '1');
  146. if (typeof duration !== 'undefined') {
  147. this.duration(duration);
  148. }
  149. return this;
  150. };
  151. };