/* 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
};
/**
*
* @classdesc
* <p>
* Provides the functionality to store contents. The recorder can store
* in local files or in a network resource. It receives a media stream
* from another MediaElement (i.e. the source), and stores it in the
* designated location.
* </p>
* <p>
* The following information has to be provided In order to create a
* RecorderEndpoint, and can’t be changed afterwards:
* <ul>
* <li>
* URI of the resource where media will be stored. Following schemas
* are supported:
* <ul>
* <li>
* Files: mounted in the local file system.
* <ul>
* <li>file://<path-to-file></li>
* </ul>
* <li>
* HTTP: Requires the server to support method PUT
* <ul>
* <li>
* http(s)://<server-ip>/path/to/file
* </li>
* <li>
* http(s)://username:password@<server-ip>/path/to/file
* </li>
* </ul>
* </li>
* </ul>
* </li>
* <li>
* Relative URIs (with no schema) are supported. They are completed
* prepending a default URI defined by property defaultPath. This
* property allows using relative paths instead of absolute paths. If
* </li>
* <li>
* The media profile used to store the file. This will determine the
* encoding. See below for more details about media profile
* </li>
* <li>
* Optionally, the user can select if the endpoint will stop
* processing once the EndOfStream event is detected.
* </li>
* </ul>
* <p>
* </p>
* RecorderEndpoint requires access to the resource where stream is going
* <p>
* </p>
* The media profile is quite an important parameter, as it will
* determine whether there is a transcodification or not. If the input
* stream codec if not compatible with the selected media profile, the
* media will be transcoded into a suitable format, before arriving at
* the RecorderEndpoint's sink pad. This will result in a higher CPU load
* <ul>
* <li>WEBM: No transcodification will take place.</li>
* <li>MP4: The media server will have to transcode the media received
* from VP8 to H264. This will raise the CPU load in the system.</li>
* </ul>
* <p>
* </p>
* Recording will start as soon as the user invokes the record method.
* The recorder will then store, in the location indicated, the media
* that the source is sending to the endpoint’s sink. If no media is
* being received, or no endpoint has been connected, then the
* destination will be empty. The recorder starts storing information
* into the file as soon as it gets it.
* <p>
* </p>
* When another endpoint is connected to the recorder, by default both
* AUDIO and VIDEO media types are expected, unless specified otherwise
* when invoking the connect method. Failing to provide both types, will
* result in teh recording buffering the received media: it won’t be
* written to the file until the recording is stopped. This is due to the
* <p>
* </p>
* The source endpoint can be hot-swapped, while the recording is taking
* place. The recorded file will then contain different feeds. When
* switching video sources, if the new video has different size, the
* recorder will retain the size of the previous source. If the source is
* <p>
* </p>
* It is recommended to start recording only after media arrives, either
* to the endpoint that is the source of the media connected to the
* recorder, to the recorder itself, or both. Users may use the
* MediaFlowIn and MediaFlowOut events, and synchronise the recording
* with the moment media comes in. In any case, nothing will be stored in
* <p>
* </p>
* Stopping the recording process is done through the stopAndWait method,
* </p>
*
* @extends module:core/abstracts.UriEndpoint
*
* @constructor module:elements.RecorderEndpoint
*
* @fires {@link module:elements#event:Paused Paused}
* @fires {@link module:elements#event:Recording Recording}
* @fires {@link module:elements#event:Stopped Stopped}
*/
function RecorderEndpoint(){
RecorderEndpoint.super_.call(this);
};
inherits(RecorderEndpoint, UriEndpoint);
//
// Public methods
//
/**
* Starts storing media received through the sink pad.
*
* @alias module:elements.RecorderEndpoint.record
*
* @param {module:elements.RecorderEndpoint~recordCallback} [callback]
*
* @return {external:Promise}
*/
RecorderEndpoint.prototype.record = 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, 'record', callback), this)
};
/**
* @callback module:elements.RecorderEndpoint~recordCallback
* @param {external:Error} error
*/
/**
* Stops recording and does not return until all the content has been written to
*
* @alias module:elements.RecorderEndpoint.stopAndWait
*
* @param {module:elements.RecorderEndpoint~stopAndWaitCallback} [callback]
*
* @return {external:Promise}
*/
RecorderEndpoint.prototype.stopAndWait = 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, 'stopAndWait', callback), this)
};
/**
* @callback module:elements.RecorderEndpoint~stopAndWaitCallback
* @param {external:Error} error
*/
/**
* @alias module:elements.RecorderEndpoint.constructorParams
*
* @property {module:core.MediaPipeline} mediaPipeline
* the {@link module:core.MediaPipeline MediaPipeline} to which the endpoint
* belongs
*
* @property {module:elements/complexTypes.MediaProfileSpecType} [mediaProfile]
* Sets the media profile used for recording. If the profile is different than
* the one being recieved at the sink pad, media will be trnascoded, resulting
* in a higher CPU load. For instance, when recording a VP8 encoded video from
* a WebRTC endpoint in MP4, the load is higher that when recording in WEBM.
*
* @property {external:Boolean} [stopOnEndOfStream]
* Forces the recorder endpoint to finish processing data when an <a
* href="http://www.kurento.org/docs/current/glossary.html#term-eos">EOS</a> is
*
* @property {external:String} uri
* URI where the recording will be stored. It has to be accessible to the KMS
* process.
* <ul>
* <li>Local server resources: The user running the Kurento
* Media Server must have write permission over the file.</li>
* <li>Network resources: Must be accessible from the server
* where the media server is running.</li>
* </ul>
*/
RecorderEndpoint.constructorParams = {
mediaPipeline: {
type: 'kurento.MediaPipeline',
required: true
},
mediaProfile: {
type: 'kurento.MediaProfileSpecType' },
stopOnEndOfStream: {
type: 'boolean' },
uri: {
type: 'String',
required: true
}
};
/**
* @alias module:elements.RecorderEndpoint.events
*
* @extends module:core/abstracts.UriEndpoint.events
*/
RecorderEndpoint.events = UriEndpoint.events.concat(['Paused', 'Recording', 'Stopped']);
/**
* Checker for {@link module:elements.RecorderEndpoint}
*
* @memberof module:elements
*
* @param {external:String} key
* @param {module:elements.RecorderEndpoint} value
*/
function checkRecorderEndpoint(key, value)
{
if(!(value instanceof RecorderEndpoint))
throw ChecktypeError(key, RecorderEndpoint, value);
};
module.exports = RecorderEndpoint;
RecorderEndpoint.check = checkRecorderEndpoint;