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

/* Autogenerated with Kurento Idl */

/*
 * (C) Copyright 2013-2015 Kurento (http://kurento.org/)
 *
 * 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 <a 
 *    href="http://www.kurento.org/docs/current/glossary.html#term-kms">KMS</a>.
 *    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)://{server-ip}/path/to/file</code></li>
 *        <li>
 *          <code>
 *            http(s)://{username}:{password}@{server-ip}:{server-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://{server-ip}</code></li>
 *        <li>
 *          <code>
 *            rtsp://{username}:{password}@{server-ip}:{server-port}/path/to/file
 *          </code>
 *        </li>
 *      </ul>
 *    </li>
 *    <li>
 *      <strong>
 *        NOTE (for current versions of Kurento 6.x): special characters are not
 *        supported in <code>{username}</code> or <code>{password}</code>.
 *      </strong>
 *      This means that <code>{username}</code> cannot contain colons
 *      (<code>:</code>), and <code>{password}</code> cannot contain 'at' signs
 *      (<code>@</code>). This is a limitation of GStreamer 1.8 (the underlying
 *      media framework behind Kurento), and is already fixed in newer versions
 *      (which the upcoming Kurento 7.x will use).
 *    </li>
 *    <li>
 *      <strong>
 *        NOTE (for upcoming Kurento 7.x): special characters in
 *        <code>{username}</code> or <code>{password}</code> must be 
 *        url-encoded.
 *      </strong>
 *      This means that colons (<code>:</code>) should be replaced with
 *      <code>%3A</code>, and 'at' signs (<code>@</code>) should be replaced 
 *      with
 *      <code>%40</code>.
 *    </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 module:core.MediaPipeline 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 the input media as-is to the Media Pipeline, instead of first decoding 
 *  it.
 *                <p>
 *                When this property is not enabled, the input media gets always
 *                </p>
 *                <p>
 *                When this property is enabled, the explained behavior gets 
 *                disabled. Instead, The endpoint will provide any input media 
 *                directly to the Media Pipeline, without prior decoding. 
 *                Enabling this mode of operation could have a severe effect on 
 *                stability, because lost video keyframes will not be 
 *                regenerated; however, avoiding a full cycle of decoding and 
 *                encoding can be very useful for certain applications, because 
 *                it improves performance by greatly reducing the CPU processing
 *                </p>
 *                <p>
 *                Keep in mind that if this property is enabled, the original 
 *                source media MUST already have an encoding format which is 
 *                compatible with the destination target. For example: given a 
 *                pipeline which uses this endpoint to read a file and then 
 *                streams it to a WebRTC browser such as Chrome, then the file 
 *                must already be encoded with a VP8 or H.264 codec profile 
 *                which Chrome is able to decode. Note that for this example, 
 *                most browsers don't support ANY combination of H.264 encoding 
 *                options; instead, they tend to support only a very specific 
 *                subset of the codec features (also known as 'profiles').
 *                </p>
 *                <p>
 *                We strongly recommend to avoid using this option, because 
 *                correct behavior cannot be guaranteed.
 *                </p>
 */
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;