Source: node_modules/kurento-client-elements/lib/PlayerEndpoint.js

/* Autogenerated with Kurento Idl */

/*
 * (C) Copyright 2013-2015 Kurento (https://kurento.openvidu.io/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var inherits = require('inherits');

var kurentoClient = require('kurento-client');

var disguise = kurentoClient.disguise;

var checkType      = kurentoClient.checkType;
var ChecktypeError = checkType.ChecktypeError;


var Transaction = kurentoClient.TransactionsManager.Transaction;

var UriEndpoint = require('kurento-client-core').abstracts.UriEndpoint;


function noop(error, result) {
  if (error) console.trace(error);

  return result
};


/**
 * Create a PlayerEndpoint
 *
 * @classdesc
 *  Retrieves content from external sources.
 *  <p>
 *    PlayerEndpoint will access the given resource, read all available data, 
 *    and
 *    inject it into Kurento. Once this is is done, the injected video or audio 
 *    will
 *    be available for passing through any other Filter or Endpoint to which the
 *    PlayerEndpoint gets connected.
 *  </p>
 *  <p>
 *    The source can provide either seekable or non-seekable media; this will
 *    dictate whether the PlayerEndpoint is able (or not) to seek through the 
 *    file,
 *    for example to jump to any given timestamp.
 *  </p>
 *  <p>The <strong>Source URI</strong> supports these formats:</p>
 *  <ul>
 *    <li>
 *      File: A file path that will be read from the local file system. Example:
 *      <ul>
 *        <li><code>file:///path/to/file</code></li>
 *      </ul>
 *    </li>
 *    <li>
 *      HTTP: Any file available in an HTTP server. Examples:
 *      <ul>
 *        <li><code>http(s)://host/path/to/file</code></li>
 *        <li>
 *          <code>
 *            http(s)://username:password@host:port/path/to/file
 *          </code>
 *        </li>
 *      </ul>
 *    </li>
 *    <li>
 *      RTSP: Typically used to capture a feed from an IP Camera. Examples:
 *      <ul>
 *        <li><code>rtsp://host</code></li>
 *        <li>
 *          <code>
 *            rtsp://username:password@host:port/path/to/file?key=value&key=value
 *          </code>
 *        </li>
 *      </ul>
 *    </li>
 *    <li>
 *      <strong>
 *        NOTE: Special characters must be
 *        <a href='https://en.wikipedia.org/wiki/Query_string#URL_encoding'>
 *          URL-encoded
 *        </a>
 *        in <code>username</code> and <code>password</code> fields.
 *      </strong>
 *    </li>
 *  </ul>
 *  <p>
 *    Note that
 *    <strong> PlayerEndpoint requires read permissions to the source </strong>
 *    ; otherwise, the media server won't be able to retrieve any data, and an
 *    {@link ErrorEvent} will be fired. Make sure your application subscribes to
 *    event, otherwise troubleshooting issues will be difficult.
 *  </p>
 *  <p>The list of valid operations is:</p>
 *  <ul>
 *    <li>
 *      <strong><code>play</code></strong>
 *      : Starts streaming media. If invoked after pause, it will resume 
 *      playback.
 *    </li>
 *    <li>
 *      <strong><code>stop</code></strong>
 *      : Stops streaming media. If play is invoked afterwards, the file will be
 *      streamed from the beginning.
 *    </li>
 *    <li>
 *      <strong><code>pause</code></strong>
 *      : Pauses media streaming. Play must be invoked in order to resume 
 *      playback.
 *    </li>
 *    <li>
 *      <strong><code>seek</code></strong>
 *      : If the source supports seeking to a different time position, then the
 *      PlayerEndpoint can:
 *      <ul>
 *        <li>
 *          <strong><code>setPosition</code></strong>
 *          : Allows to set the position in the file.
 *        </li>
 *        <li>
 *          <strong><code>getPosition</code></strong>
 *          : Returns the current position being streamed.
 *        </li>
 *      </ul>
 *    </li>
 *  </ul>
 *  <h2>Events fired</h2>
 *  <ul>
 *    <li>
 *      <strong>EndOfStreamEvent</strong>: If the file is streamed completely.
 *    </li>
 *  </ul>
 *
 * @extends module:core/abstracts.UriEndpoint
 *
 * @constructor module:elements.PlayerEndpoint
 *
 * @fires {@link module:elements#event:EndOfStream EndOfStream}
 */
function PlayerEndpoint(){
  PlayerEndpoint.super_.call(this);
};
inherits(PlayerEndpoint, UriEndpoint);


//
// Public properties
//

/**
 * Returns the GStreamer DOT string for this element's private pipeline
 *
 * @alias module:elements.PlayerEndpoint#getElementGstreamerDot
 *
 * @param {module:elements.PlayerEndpoint~getElementGstreamerDotCallback} [callback]
 *
 * @return {external:Promise}
 */
PlayerEndpoint.prototype.getElementGstreamerDot = function(callback){
  var transaction = (arguments[0] instanceof Transaction)
                  ? Array.prototype.shift.apply(arguments)
                  : undefined;

  var usePromise = false;
  
  if (callback == undefined) {
    usePromise = true;
  }
  
  if(!arguments.length) callback = undefined;

  callback = (callback || noop).bind(this)

  return disguise(this._invoke(transaction, 'getElementGstreamerDot', callback), this)
};
/**
 * @callback module:elements.PlayerEndpoint~getElementGstreamerDotCallback
 * @param {external:Error} error
 * @param {external:String} result
 */

/**
 * Get or set the actual position of the video in ms. <hr/><b>Note</b> Setting 
 * the position only works for seekable videos
 *
 * @alias module:elements.PlayerEndpoint#getPosition
 *
 * @param {module:elements.PlayerEndpoint~getPositionCallback} [callback]
 *
 * @return {external:Promise}
 */
PlayerEndpoint.prototype.getPosition = function(callback){
  var transaction = (arguments[0] instanceof Transaction)
                  ? Array.prototype.shift.apply(arguments)
                  : undefined;

  var usePromise = false;
  
  if (callback == undefined) {
    usePromise = true;
  }
  
  if(!arguments.length) callback = undefined;

  callback = (callback || noop).bind(this)

  return disguise(this._invoke(transaction, 'getPosition', callback), this)
};
/**
 * @callback module:elements.PlayerEndpoint~getPositionCallback
 * @param {external:Error} error
 * @param {external:int64} result
 */

/**
 * Get or set the actual position of the video in ms. <hr/><b>Note</b> Setting 
 * the position only works for seekable videos
 *
 * @alias module:elements.PlayerEndpoint#setPosition
 *
 * @param {external:int64} position
 * @param {module:elements.PlayerEndpoint~setPositionCallback} [callback]
 *
 * @return {external:Promise}
 */
PlayerEndpoint.prototype.setPosition = function(position, callback){
  var transaction = (arguments[0] instanceof Transaction)
                  ? Array.prototype.shift.apply(arguments)
                  : undefined;

  //  
  // checkType('int64', 'position', position, {required: true});
  //  

  var params = {
    position: position
  };

  callback = (callback || noop).bind(this)

  return disguise(this._invoke(transaction, 'setPosition', params, callback), this)
};
/**
 * @callback module:elements.PlayerEndpoint~setPositionCallback
 * @param {external:Error} error
 */

/**
 * Returns info about the source being played
 *
 * @alias module:elements.PlayerEndpoint#getVideoInfo
 *
 * @param {module:elements.PlayerEndpoint~getVideoInfoCallback} [callback]
 *
 * @return {external:Promise}
 */
PlayerEndpoint.prototype.getVideoInfo = function(callback){
  var transaction = (arguments[0] instanceof Transaction)
                  ? Array.prototype.shift.apply(arguments)
                  : undefined;

  var usePromise = false;
  
  if (callback == undefined) {
    usePromise = true;
  }
  
  if(!arguments.length) callback = undefined;

  callback = (callback || noop).bind(this)

  return disguise(this._invoke(transaction, 'getVideoInfo', callback), this)
};
/**
 * @callback module:elements.PlayerEndpoint~getVideoInfoCallback
 * @param {external:Error} error
 * @param {module:elements/complexTypes.VideoInfo} result
 */


//
// Public methods
//

/**
 * Starts reproducing the media, sending it to the :rom:cls:`MediaSource`. If 
 * the endpoint
 *           has been connected to other endpoints, those will start receiving 
 *           media.
 *
 * @alias module:elements.PlayerEndpoint.play
 *
 * @param {module:elements.PlayerEndpoint~playCallback} [callback]
 *
 * @return {external:Promise}
 */
PlayerEndpoint.prototype.play = function(callback){
  var transaction = (arguments[0] instanceof Transaction)
                  ? Array.prototype.shift.apply(arguments)
                  : undefined;

  var usePromise = false;
  
  if (callback == undefined) {
    usePromise = true;
  }
  
  if(!arguments.length) callback = undefined;

  callback = (callback || noop).bind(this)

  return disguise(this._invoke(transaction, 'play', callback), this)
};
/**
 * @callback module:elements.PlayerEndpoint~playCallback
 * @param {external:Error} error
 */


/**
 * @alias module:elements.PlayerEndpoint.constructorParams
 *
 * @property {module:core.MediaPipeline} mediaPipeline
 *  The {@link MediaPipeline} this PlayerEndpoint belongs to.
 *
 * @property {external:Integer} [networkCache]
 *  RTSP buffer length.
 *  <p>
 *    When receiving media from an RTSP source, the streamed video can suffer 
 *    spikes
 *    or stuttering, caused by hardware or network issues. Having a reception 
 *    buffer
 *    helps alleviate these problems, because it smoothes the stream of incoming
 *    data to the receiving endpoint.
 *  </p>
 *  <p>
 *    Finding a buffer length that works best for your connection might take 
 *    some
 *    tweaking, which can be done with this optional property. Note that a 
 *    longer
 *    buffer will be able to fix bigger network spikes, but at the cost of
 *    introducing more latency to the media playback.
 *  </p>
 *  <ul>
 *    <li>Unit: milliseconds.</li>
 *    <li>Default: 2000.</li>
 *  </ul>
 *
 * @property {external:String} uri
 *  URI pointing to the video. It has to be accessible to the KMS process.
 *                <ul>
 *                  <li>Local resources: The user running the Kurento Media 
 *                  Server must have read permission over the file.</li>
 *                  <li>Remote resources: Must be accessible from the server 
 *                  where the media server is running.</li>
 *                </ul>
 *
 * @property {external:Boolean} [useEncodedMedia]
 *  Feed an encoded media as-is to the Media Pipeline, instead of first decoding
 *                <p>
 *                  This property is disabled by default. The input media gets 
 *                  always decoded into
 *                  a raw format upon receiving it, before being processed by 
 *                  the rest of the
 *                  Media Pipeline. This is done to ensure that Kurento is able 
 *                  to keep track of
 *                  lost keyframes among other quality-control measurements. Of 
 *                  course, having to
 *                  decode the media has a cost in terms of CPU usage, but 
 *                  ensures that the output
 *                  streaming will be more robust and reliable.
 *                </p>
 *                <p>
 *                  When this property is enabled, Kurento simply passes the 
 *                  encoded media as-is
 *                  to the rest of the Media Pipeline, without decoding. 
 *                  Enabling this mode of
 *                  operation could have a severe effect on stability, because 
 *                  lost video
 *                  keyframes will not be regenerated; however, not having to 
 *                  encode the video
 *                  greatly reduces the CPU load.
 *                </p>
 *                <p>
 *                  Keep in mind that if this property is enabled, the original 
 *                  source media MUST
 *                  already be in a format that is compatible with the 
 *                  destination target. For
 *                  example: Given a Pipeline that reads a file and then streams
 *                  browser such as Chrome, the file must already be encoded 
 *                  with a VP8 or H.264
 *                  codec profile, which Chrome is able to decode.
 *                </p>
 *                <p>
 *                  Of special note is that you cannot feed any random 
 *                  combination of H.264
 *                  encoding options to a web browser; instead, they tend to 
 *                  support only a very
 *                  specific subset of the codec features (also known as 
 *                  'profiles'). The most
 *                  compatible config for H.264 is
 *                  <strong>Constrained Baseline profile, level 3.1.</strong>
 *                </p>
 *                <p>Code examples:</p>
 *                <pre><code>
 *                  # Java
 *                  PlayerEndpoint player = new PlayerEndpoint
 *                    .Builder(pipeline, 'rtsp://localhost:5000/video')
 *                    .useEncodedMedia()
 *                    .build();
 *                </code></pre>
 *                <pre><code>
 *                  # JavaScript
 *                  let player = await pipeline.create('PlayerEndpoint', {
 *                    uri: 'rtsp://localhost:5000/video',
 *                    useEncodedMedia: true,
 *                  });
 *                </code></pre>
 */
PlayerEndpoint.constructorParams = {
  mediaPipeline: {
    type: 'kurento.MediaPipeline',
    required: true
  },
  networkCache: {
    type: 'int'  },
  uri: {
    type: 'String',
    required: true
  },
  useEncodedMedia: {
    type: 'boolean'  }
};

/**
 * @alias module:elements.PlayerEndpoint.events
 *
 * @extends module:core/abstracts.UriEndpoint.events
 */
PlayerEndpoint.events = UriEndpoint.events.concat(['EndOfStream']);


/**
 * Checker for {@link module:elements.PlayerEndpoint}
 *
 * @memberof module:elements
 *
 * @param {external:String} key
 * @param {module:elements.PlayerEndpoint} value
 */
function checkPlayerEndpoint(key, value)
{
  if(!(value instanceof PlayerEndpoint))
    throw ChecktypeError(key, PlayerEndpoint, value);
};


module.exports = PlayerEndpoint;

PlayerEndpoint.check = checkPlayerEndpoint;